39 template<u
int_t M, u
int_t P,
typename T>
41 static const uint_t N = IPow<M,P>::value;
45 for (int_t i=0; i<2*N-1; i+=2) {
47 std::swap(data[j], data[i]);
48 std::swap(data[j+1], data[i+1]);
51 while (m>=2 && j>=m) {
74 template<u
int_t M, u
int_t P,
typename T, u
int_t I=0>
76 static const int_t BN = IPow<M,I>::value;
77 static const int_t BR = IPow<M,P-I-1>::value;
80 void apply(T* data, int_t n=0, int_t r=0) {
81 const int_t qn = n/BN;
82 const int_t rn = n%BN;
83 const int_t qr = r/BR;
84 const int_t rr = r%BR;
85 for (uint_t i = 0; i < M; ++i) {
86 next.apply(data,(qn+i)*BN+rn,(qr+i)*BR+rr);
91 template<u
int_t M, u
int_t P,
typename T>
94 void apply(T* data, int_t n=0, int_t r=0) {
98 std::swap(data[n2],data[r2]);
99 std::swap(data[n2+1],data[r2+1]);
104 template<u
int_t P,
typename T, u
int_t I>
105 class GFFTswap2<2,P,T,I> {
106 static const int_t BN = 1<<(I+1);
107 static const int_t BR = 1<<(P-I);
108 GFFTswap2<2,P,T,I+1> next;
110 void apply(T* data, int_t n=0, int_t r=0) {
111 next.apply(data,n,r);
112 next.apply(data,n|BN,r|BR);
116 template<u
int_t P,
typename T>
117 class GFFTswap2<2,P,T,P> {
119 void apply(T* data, int_t n=0, int_t r=0) {
121 std::swap(data[n],data[r]);
122 std::swap(data[n+1],data[r+1]);
132 template<uint_t M, uint_t P,
typename T,
133 template<
typename>
class Complex>
136 static const uint_t N = IPow<M,P>::value;
138 void apply(Complex<T>* data) {
140 for (int_t i=0; i<N; ++i) {
142 std::swap(data[j], data[i]);
145 while (m>=1 && j>=m) {
154 template<uint_t M, uint_t P,
typename T, uint_t I,
155 template<
typename>
class Complex>
157 static const int_t BN = IPow<M,I>::value;
158 static const int_t BR = IPow<M,P-I-1>::value;
161 void apply(Complex<T>* data, int_t n=0, int_t r=0) {
162 const int_t qn = n/BN;
163 const int_t rn = n%BN;
164 const int_t qr = r/BR;
165 const int_t rr = r%BR;
166 for (uint_t i = 0; i < M; ++i) {
167 next.apply(data,(qn+i)*BN+rn,(qr+i)*BR+rr);
172 template<uint_t M, uint_t P,
typename T,
173 template<
typename>
class Complex>
174 class GFFTswap2<M,P,Complex<T>,P> {
176 void apply(Complex<T>* data, int_t n=0, int_t r=0) {
178 std::swap(data[n],data[r]);
182 template<uint_t P,
typename T, uint_t I,
183 template<
typename>
class Complex>
184 class GFFTswap2<2,P,Complex<T>,I> {
185 static const int_t BN = 1<<I;
186 static const int_t BR = 1<<(P-I-1);
187 GFFTswap2<2,P,Complex<T>,I+1> next;
189 void apply(Complex<T>* data, int_t n=0, int_t r=0) {
190 next.apply(data,n,r);
191 next.apply(data,n|BN,r|BR);
195 template<uint_t P,
typename T,
196 template<
typename>
class Complex>
197 class GFFTswap2<2,P,Complex<T>,P> {
199 void apply(Complex<T>* data, int_t n=0, int_t r=0) {
201 swap(data[n],data[r]);
212 template<
int_t N,
typename T,
int S>
214 typedef typename TempTypeTrait<T>::Result LocalVType;
215 static const int M = (S==1) ? 2 : 1;
217 void apply(T* data) {
219 LocalVType wtemp,wr,wi,wpr,wpi;
220 LocalVType h1r,h1i,h2r,h2i,h3r,h3i;
222 wpr = -2.*wtemp*wtemp;
226 for (i=1; i<N/2; ++i) {
231 h1r = 0.5*(data[i1]+data[i3]);
232 h1i = 0.5*(data[i2]-data[i4]);
233 h2r = S*0.5*(data[i2]+data[i4]);
234 h2i =-S*0.5*(data[i1]-data[i3]);
235 h3r = wr*h2r - wi*h2i;
236 h3i = wr*h2i + wi*h2r;
237 data[i1] = h1r + h3r;
238 data[i2] = h1i + h3i;
239 data[i3] = h1r - h3r;
240 data[i4] =-h1i + h3i;
243 wr += wr*wpr - wi*wpi;
244 wi += wi*wpr + wtemp*wpi;
247 data[0] = M*0.5*(h1r + data[1]);
248 data[1] = M*0.5*(h1r - data[1]);
250 if (N>1) data[N+1] = -data[N+1];
253 void apply(
const T*, T*)
255 std::cout <<
"Not implemented!" << std::endl;
267 template<int_t N,
typename T,
int S,
268 template<
typename>
class Complex>
270 typedef typename TempTypeTrait<T>::Result LocalVType;
271 typedef Complex<LocalVType> LocalComplex;
272 static const int M = (S==1) ? 2 : 1;
274 void apply(Complex<T>* data) {
276 LocalComplex h1,h2,h3;
279 LocalComplex w(1.+wp.real(),wp.imag());
281 for (i=1; i<N/2; ++i) {
283 h1 = Complex<LocalVType>(
static_cast<LocalVType
>(0.5*(data[i].real()+data[i1].real())),
284 static_cast<LocalVType
>(0.5*(data[i].imag()-data[i1].imag())));
285 h2 = Complex<LocalVType>(
static_cast<LocalVType
>( S*0.5*(data[i].imag()+data[i1].imag())),
286 static_cast<LocalVType
>(-S*0.5*(data[i].real()-data[i1].real())));
290 data[i1] = Complex<T>(data[i1].real(), -data[i1].imag());
294 wtemp = data[0].real();
295 data[0] = Complex<T>(M*0.5*(wtemp + data[0].imag()), M*0.5*(wtemp - data[0].imag()));
297 data[N/2] = Complex<T>(data[N/2].real(), -data[N/2].imag());
300 void apply(
const Complex<T>*, Complex<T>*)
302 std::cout <<
"Not implemented!" << std::endl;
308 template<
int_t N,
typename T>
312 void apply(
const T*, T*) { }
313 void apply(
const T*, T*, T*) { }
316 template<int_t N,
typename T,
317 template<
typename>
class Complex>
318 struct Forward<N,Complex<T> > {
320 void apply(Complex<T>*) { }
321 void apply(
const Complex<T>*, Complex<T>*) { }
322 void apply(
const Complex<T>*, Complex<T>*, Complex<T>*) { }
326 template<
int_t N,
typename T>
329 void apply(T* data) {
330 for (T* i=data; i<data+2*N; ++i) *i/=N;
332 void apply(
const T*, T* dst) { apply(dst); }
333 void apply(
const T*, T* dst, T*) { apply(dst); }
336 template<int_t N,
typename T,
337 template<
typename>
class Complex>
338 struct Backward<N,Complex<T> > {
340 void apply(Complex<T>* data) {
341 for (int_t i=0; i<N; ++i) {
345 void apply(
const Complex<T>*, Complex<T>* dst) { apply(dst); }
346 void apply(
const Complex<T>*, Complex<T>* dst, Complex<T>*) { apply(dst); }