38 template<
typename T,
int_t N,
int S,
int_t K>
41 static const int_t K2 = K*2;
43 static void apply(T* c, T* s)
51 template<
typename T,
int_t N,
int S>
54 static void apply(T* c, T* s)
71 template<
int_t N,
int_t M,
typename T,
int S>
76 typedef typename TempTypeTrait<T>::Result LocalVType;
77 static const int_t K = (N-1)/2;
78 static const int_t NM = N*M;
80 LocalVType m_c[K], m_s[K];
90 T sr[K], si[K], dr[K], di[K];
91 for (int_t i=0; i<K; ++i) {
92 const int_t k = (i+1)*M;
93 sr[i] = data[k] + data[NM-k];
94 si[i] = data[k+1] + data[NM-k+1];
95 dr[i] = data[k] - data[NM-k];
96 di[i] = data[k+1] - data[NM-k+1];
99 for (int_t i=1; i<K+1; ++i) {
100 T re1(0), re2(0), im1(0), im2(0);
101 for (int_t j=0; j<K; ++j) {
102 const bool sign_change = (i*(j+1) % N) > K;
103 const int_t kk = (i+j*i)%N;
104 const int_t k = (kk>K) ? N-kk-1 : kk-1;
105 const T s1 = m_s[k]*di[j];
106 const T s2 = m_s[k]*dr[j];
109 re2 += sign_change ? -s1 : s1;
110 im2 -= sign_change ? -s2 : s2;
113 data[k] = data[0] + re1 + re2;
114 data[k+1] = data[1] + im1 + im2;
115 data[NM-k] = data[0] + re1 - re2;
116 data[NM-k+1] = data[1] + im1 - im2;
119 for (int_t i=0; i<K; ++i) {
126 void apply(T* data,
const LT* wr,
const LT* wi)
128 T sr[K], si[K], dr[K], di[K];
129 for (int_t i=0; i<K; ++i) {
130 const int_t k = (i+1)*M;
131 const T tr1 = data[k]*wr[i] - data[k+1]*wi[i];
132 const T ti1 = data[k]*wi[i] + data[k+1]*wr[i];
133 const T tr2 = data[NM-k]*wr[N-i-2] - data[NM-k+1]*wi[N-i-2];
134 const T ti2 = data[NM-k]*wi[N-i-2] + data[NM-k+1]*wr[N-i-2];
141 for (int_t i=1; i<K+1; ++i) {
142 T re1(0), re2(0), im1(0), im2(0);
143 for (int_t j=0; j<K; ++j) {
144 const bool sign_change = (i*(j+1) % N) > K;
145 const int_t kk = (i+j*i)%N;
146 const int_t k = (kk>K) ? N-kk-1 : kk-1;
147 const T s1 = m_s[k]*di[j];
148 const T s2 = m_s[k]*dr[j];
151 re2 += sign_change ? -s1 : s1;
152 im2 -= sign_change ? -s2 : s2;
155 data[k] = data[0] + re1 + re2;
156 data[k+1] = data[1] + im1 + im2;
157 data[NM-k] = data[0] + re1 - re2;
158 data[NM-k+1] = data[1] + im1 - im2;
161 for (int_t i=0; i<K; ++i) {
168 void apply(
const LT* wr,
const LT* wi, T* data)
170 T sr[K], si[K], dr[K], di[K];
171 for (int_t i=0; i<K; ++i) {
172 const int_t k = (i+1)*M;
173 sr[i] = data[k] + data[NM-k];
174 si[i] = data[k+1] + data[NM-k+1];
175 dr[i] = data[k] - data[NM-k];
176 di[i] = data[k+1] - data[NM-k+1];
179 for (int_t i=1; i<K+1; ++i) {
180 T re1(0), re2(0), im1(0), im2(0);
181 for (int_t j=0; j<K; ++j) {
182 const bool sign_change = (i*(j+1) % N) > K;
183 const int_t kk = (i+j*i)%N;
184 const int_t k = (kk>K) ? N-kk-1 : kk-1;
185 const T s1 = m_s[k]*di[j];
186 const T s2 = m_s[k]*dr[j];
189 re2 += sign_change ? -s1 : s1;
190 im2 -= sign_change ? -s2 : s2;
193 const T tr1 = data[0] + re1 + re2;
194 const T ti1 = data[1] + im1 + im2;
195 const T tr2 = data[0] + re1 - re2;
196 const T ti2 = data[1] + im1 - im2;
197 data[k] = tr1*wr[i-1] - ti1*wi[i-1];
198 data[k+1] = tr1*wi[i-1] + ti1*wr[i-1];
199 data[NM-k] = tr2*wr[K-i+1] - ti2*wi[K-i+1];
200 data[NM-k+1] = tr2*wi[K-i+1] + ti2*wr[K-i+1];
203 for (int_t i=0; i<K; ++i) {
263 template<
int_t M,
typename T,
int S>
266 static const int_t I10 = M;
267 static const int_t I11 = M+1;
268 static const int_t I20 = M+M;
269 static const int_t I21 = I20+1;
274 DFTk_inp() : m_coef(S * Sqrt<3, T>::value() * 0.5) { }
278 const T sum_r = data[I10] + data[I20];
279 const T dif_r = m_coef * (data[I10] - data[I20]);
280 const T sum_i = data[I11] + data[I21];
281 const T dif_i = m_coef * (data[I11] - data[I21]);
282 const T tr = data[0] - 0.5*sum_r;
283 const T ti = data[1] - 0.5*sum_i;
286 data[I10] = tr + dif_i;
287 data[I11] = ti - dif_r;
288 data[I20] = tr - dif_i;
289 data[I21] = ti + dif_r;
292 void apply(T* data,
const LT* wr,
const LT* wi)
294 const T tr1 = data[I10]*wr[0] - data[I11]*wi[0];
295 const T ti1 = data[I10]*wi[0] + data[I11]*wr[0];
296 const T tr2 = data[I20]*wr[1] - data[I21]*wi[1];
297 const T ti2 = data[I20]*wi[1] + data[I21]*wr[1];
299 const T sum_r = tr1 + tr2;
300 const T dif_r = m_coef * (tr1 - tr2);
301 const T sum_i = ti1 + ti2;
302 const T dif_i = m_coef * (ti1 - ti2);
303 const T tr = data[0] - 0.5*sum_r;
304 const T ti = data[1] - 0.5*sum_i;
307 data[I10] = tr + dif_i;
308 data[I11] = ti - dif_r;
309 data[I20] = tr - dif_i;
310 data[I21] = ti + dif_r;
313 void apply(
const LT* wr,
const LT* wi, T* data)
315 const T sum_r = data[I10] + data[I20];
316 const T dif_r = m_coef * (data[I10] - data[I20]);
317 const T sum_i = data[I11] + data[I21];
318 const T dif_i = m_coef * (data[I11] - data[I21]);
319 const T tr = data[0] - 0.5*sum_r;
320 const T ti = data[1] - 0.5*sum_i;
321 const T trpdi = tr + dif_i;
322 const T trmdi = tr - dif_i;
323 const T tipdr = ti + dif_r;
324 const T timdr = ti - dif_r;
327 data[I10] = trpdi*wr[0] - timdr*wi[0];
328 data[I11] = trpdi*wi[0] + timdr*wr[0];
329 data[I20] = trmdi*wr[1] - tipdr*wi[1];
330 data[I21] = trmdi*wi[1] + tipdr*wr[1];
335 template<
int_t M,
typename T,
int S>
336 class DFTk_inp<2,M,T,S>
341 const T tr = data[M];
342 const T ti = data[M+1];
343 data[M] = data[0]-tr;
344 data[M+1] = data[1]-ti;
357 void apply(T* data,
const LT* wr,
const LT* wi)
359 const T tr = data[M] * (*wr) - data[M+1] * (*wi);
360 const T ti = data[M] * (*wi) + data[M+1] * (*wr);
361 data[M] = data[0]-tr;
362 data[M+1] = data[1]-ti;
368 void apply(
const LT* wr,
const LT* wi, T* data)
370 const T tr = data[0] - data[M];
371 const T ti = data[1] - data[M+1];
373 data[1] += data[M+1];
374 data[M] = tr * (*wr) - ti * (*wi);
375 data[M+1] = ti * (*wr) + tr * (*wi);
391 template<
int_t N,
int_t SI,
int_t DI,
typename T,
int S>
396 typedef typename TempTypeTrait<T>::Result LocalVType;
397 static const int_t K = (N-1)/2;
398 static const int_t NSI = N*SI;
399 static const int_t NDI = N*DI;
401 LocalVType m_c[K], m_s[K];
409 void apply(
const T* src, T* dst)
411 T sr[K], si[K], dr[K], di[K];
412 for (int_t i=0; i<K; ++i) {
413 const int_t k = (i+1)*SI;
414 sr[i] = src[k] + src[NSI-k];
415 si[i] = src[k+1] + src[NSI-k+1];
416 dr[i] = src[k] - src[NSI-k];
417 di[i] = src[k+1] - src[NSI-k+1];
420 for (int_t i=1; i<K+1; ++i) {
421 T re1(0), re2(0), im1(0), im2(0);
422 for (int_t j=0; j<K; ++j) {
423 const bool sign_change = (i*(j+1) % N) > K;
424 const int_t kk = (i+j*i)%N;
425 const int_t k = (kk>K) ? N-kk-1 : kk-1;
426 const T s1 = m_s[k]*di[j];
427 const T s2 = m_s[k]*dr[j];
430 re2 += sign_change ? -s1 : s1;
431 im2 -= sign_change ? -s2 : s2;
433 const int_t k = i*DI;
434 dst[k] = src[0] + re1 + re2;
435 dst[k+1] = src[1] + im1 + im2;
436 dst[NDI-k] = src[0] + re1 - re2;
437 dst[NDI-k+1] = src[1] + im1 - im2;
442 for (int_t i=0; i<K; ++i) {
449 template<
int_t SI,
int_t DI,
typename T,
int S>
450 class DFTk<3,SI,DI,T,S>
452 static const int_t SI2 = SI+SI;
453 static const int_t DI2 = DI+DI;
457 DFTk() : m_coef(S * Sqrt<3, T>::value() * 0.5) { }
459 void apply(
const T* src, T* dst)
462 const T sr = src[SI] + src[SI2];
463 const T dr = m_coef * (src[SI] - src[SI2]);
464 const T si = src[SI+1] + src[SI2+1];
465 const T di = m_coef * (src[SI+1] - src[SI2+1]);
466 const T tr = src[0] - 0.5*sr;
467 const T ti = src[1] - 0.5*si;
468 dst[0] = src[0] + sr;
469 dst[1] = src[1] + si;
473 dst[DI2+1] = ti + dr;
500 template<
int_t SI,
int_t DI,
typename T,
int S>
501 class DFTk<2,SI,DI,T,S>
504 void apply(
const T* src, T* dst)
507 const T tr = src[0] - src[SI];
508 const T ti = src[1] - src[SI+1];
509 dst[0] = src[0] + src[SI];
510 dst[1] = src[1] + src[SI+1];
534 const T tr = data[2];
535 const T ti = data[3];
536 data[2] = data[0]-tr;
537 data[3] = data[1]-ti;
548 const T v1(src[1]), v2(src[2]), v3(src[3]);
549 dst[0] = (*src + v2);
551 dst[2] = (*src - v2);