15 #ifndef __gfftstdspec_h
16 #define __gfftstdspec_h
39 template<int_t N, int_t M,
typename T,
int S,
40 template<
typename>
class Complex>
46 static const int_t K = (N-1)/2;
47 static const int_t NM = N*M;
57 void apply(Complex<T>* data)
59 Complex<T> s[K], d[K];
60 for (int_t i=0; i<K; ++i) {
61 const int_t k = (i+1)*M;
62 s[i] = data[k] + data[NM-k];
63 d[i] = data[k] - data[NM-k];
66 for (int_t i=1; i<K+1; ++i) {
67 Complex<T> t1(0,0), t2(0,0);
68 for (int_t j=0; j<K; ++j) {
69 const bool sign_change = (i*(j+1) % N) > K;
70 const int_t kk = (i+j*i)%N;
71 const int_t k = (kk>K) ? N-kk-1 : kk-1;
72 const T s1 = m_s[k]*d[j].imag();
73 const T s2 = m_s[k]*d[j].real();
75 Complex<T> tt(sign_change ? -s1 : s1, sign_change ? s2 : -s2);
79 data[k] = data[0] + t1 + t2;
80 data[NM-k] = data[0] + t1 - t2;
83 for (int_t i=0; i<K; ++i)
87 void apply(Complex<T>* data,
const Complex<T>* w)
89 Complex<T> s[K], d[K];
90 for (int_t i=0; i<K; ++i) {
91 const int_t k = (i+1)*M;
92 Complex<T> t1(data[k]*w[i]);
93 Complex<T> t2(data[NM-k]*w[N-i-2]);
98 for (int_t i=1; i<K+1; ++i) {
99 Complex<T> t1(0,0), t2(0,0);
100 for (int_t j=0; j<K; ++j) {
101 const bool sign_change = (i*(j+1) % N) > K;
102 const int_t kk = (i+j*i)%N;
103 const int_t k = (kk>K) ? N-kk-1 : kk-1;
104 const T s1 = m_s[k]*d[j].imag();
105 const T s2 = m_s[k]*d[j].real();
107 Complex<T> tt(sign_change ? -s1 : s1, sign_change ? s2 : -s2);
111 data[k] = data[0] + t1 + t2;
112 data[NM-k] = data[0] + t1 - t2;
115 for (int_t i=0; i<K; ++i)
120 template<int_t M,
typename T,
int S,
121 template<
typename>
class Complex>
124 static const int_t I10 = M;
125 static const int_t I20 = M+M;
130 DFTk_inp() : m_coef(S * Sqrt<3, T>::value() * 0.5) { }
132 void apply(Complex<T>* data)
134 Complex<T> sum(data[I10] + data[I20]);
135 Complex<T> dif(m_coef * (data[I10] - data[I20]));
136 Complex<T> t(data[0] - 0.5*sum);
138 data[I10] = Complex<T>(t.real() + dif.imag(), t.imag() - dif.real());
139 data[I20] = Complex<T>(t.real() - dif.imag(), t.imag() + dif.real());
141 void apply(Complex<T>* data,
const Complex<T>* w)
143 Complex<T> t1(data[I10]*w[0]);
144 Complex<T> t2(data[I20]*w[1]);
146 Complex<T> sum(t1 + t2);
147 Complex<T> dif(m_coef * (t1 - t2));
148 Complex<T> t(data[0] - 0.5*sum);
150 data[I10] = Complex<T>(t.real() + dif.imag(), t.imag() - dif.real());
151 data[I20] = Complex<T>(t.real() - dif.imag(), t.imag() + dif.real());
155 template<int_t M,
typename T,
int S,
156 template<
typename>
class Complex>
157 class DFTk_inp<2,M,Complex<T>,S>
160 void apply(Complex<T>* data)
162 Complex<T> t(data[M]);
163 data[M] = data[0] - t;
167 void apply(Complex<T>* data,
const Complex<T>* w)
169 Complex<T> t(data[M] * (*w));
170 data[M] = data[0] - t;
193 template<int_t N, int_t SI, int_t DI,
typename T,
int S,
194 template<
typename>
class Complex>
195 class DFTk<N,SI,DI,Complex<T>,S>
200 static const int_t K = (N-1)/2;
201 static const int_t NSI = N*SI;
202 static const int_t NDI = N*DI;
212 void apply(
const Complex<T>* src, Complex<T>* dst)
214 Complex<T> s[K], d[K];
215 for (int_t i=0; i<K; ++i) {
216 const int_t k = (i+1)*SI;
217 s[i] = src[k] + src[NSI-k];
218 d[i] = src[k] - src[NSI-k];
221 for (int_t i=1; i<K+1; ++i) {
222 Complex<T> t1(0,0), t2(0,0);
223 for (int_t j=0; j<K; ++j) {
224 const bool sign_change = (i*(j+1) % N) > K;
225 const int_t kk = (i+j*i)%N;
226 const int_t k = (kk>K) ? N-kk-1 : kk-1;
227 const T s1 = m_s[k]*d[j].imag();
228 const T s2 = m_s[k]*d[j].real();
230 Complex<T> tt(sign_change ? -s1 : s1, sign_change ? s2 : -s2);
233 const int_t k = i*DI;
234 dst[k] = src[0] + t1 + t2;
235 dst[NDI-k] = src[0] + t1 - t2;
239 for (int_t i=0; i<K; ++i)
244 template<int_t SI, int_t DI,
typename T,
int S,
245 template<
typename>
class Complex>
246 class DFTk<3,SI,DI,Complex<T>,S>
248 static const int_t SI2 = SI+SI;
249 static const int_t DI2 = DI+DI;
253 DFTk() : m_coef(S * Sqrt<3, T>::value() * 0.5) { }
255 void apply(
const Complex<T>* src, Complex<T>* dst)
258 Complex<T> s(src[SI] + src[SI2]);
259 Complex<T> d(m_coef * (src[SI] - src[SI2]));
260 Complex<T> t(src[0] - 0.5*s);
262 dst[DI] = Complex<T>(t.real() + d.imag(), t.imag() - d.real());
263 dst[DI2] = Complex<T>(t.real() - d.imag(), t.imag() + d.real());
267 template<int_t SI, int_t DI,
typename T,
int S,
268 template<
typename>
class Complex>
269 class DFTk<2,SI,DI,Complex<T>,S>
272 void apply(
const Complex<T>* src, Complex<T>* dst)
275 Complex<T> t(src[0] - src[SI]);
276 dst[0] = src[0] + src[SI];
286 template<
typename>
class Complex>
288 Complex<T> t(data[1]);
294 template<
typename>
class Complex>
295 inline void _spec2(
const Complex<T>* src, Complex<T>* dst)
297 dst[0] = src[0] + src[1];
298 dst[1] = src[0] - src[1];