34 static const int_t StaticLoopLimit = 8;
37 template<
int_t K,
int_t M,
typename T,
int S,
class W1,
int NIter = 1,
class W = W1>
40 typedef typename TempTypeTrait<T>::Result LocalVType;
41 typedef Compute<typename W::Re,2> WR;
42 typedef Compute<typename W::Im,2> WI;
43 static const int_t M2 = M*2;
44 static const int_t N = K*M;
46 typedef typename GetNextRoot<NIter+1,N,W1,W,2>::Result Wnext;
47 IterateInTime<K,M,T,S,W1,NIter+1,Wnext> next;
53 const LocalVType wr = WR::value();
54 const LocalVType wi = WI::value();
56 spec_inp.apply(data + (NIter-1)*2, &wr, &wi);
63 template<
int_t K,
int_t M,
typename T,
int S,
class W1,
class W>
64 class IterateInTime<K,M,T,S,W1,M,W>
67 typedef typename TempTypeTrait<T>::Result LocalVType;
68 typedef Compute<typename W::Re,2> WR;
69 typedef Compute<typename W::Im,2> WI;
70 static const int_t M2 = M*2;
71 static const int_t N = K*M;
76 const LocalVType wr = WR::value();
77 const LocalVType wi = WI::value();
79 spec_inp.apply(data + (M-1)*2, &wr, &wi);
84 template<
int_t K,
int_t M,
typename T,
int S,
class W1,
class W>
85 class IterateInTime<K,M,T,S,W1,1,W> {
86 static const int_t M2 = M*2;
88 IterateInTime<K,M,T,S,W1,2,W> next;
112 template<
int_t K,
int_t M,
typename T,
int S,
class W,
bool doStaticLoop>
116 template<
int_t K,
int_t M,
typename T,
int S,
class W>
117 class DFTk_x_Im_T<K,M,T,S,W,true> :
public IterateInTime<K,M,T,S,W> {};
120 template<
int_t K,
int_t M,
typename T,
int S,
class W>
123 typedef typename TempTypeTrait<T>::Result LocalVType;
124 typedef Compute<typename W::Re,2> WR;
125 typedef Compute<typename W::Im,2> WI;
126 static const int_t N = K*M;
127 static const int_t M2 = M*2;
132 spec_inp.apply(data);
134 LocalVType wr[K-1], wi[K-1], wpr[K-1], wpi[K-1], t;
137 wpr[0] = WR::value();
138 wpi[0] = WI::value();
144 for (int_t i=0; i<K-2; ++i) {
145 wpr[i+1] = wpr[i]*wpr[0] - wpi[i]*wpi[0];
146 wpi[i+1] = wpr[i]*wpi[0] + wpr[0]*wpi[i];
149 for (int_t i=0; i<K-1; ++i) {
154 for (int_t i=2; i<M2; i+=2) {
155 spec_inp.apply(data+i, wr, wi);
157 for (int_t i=0; i<K-1; ++i) {
159 wr[i] = t*wpr[i] - wi[i]*wpi[i];
160 wi[i] = wi[i]*wpr[i] + t*wpi[i];
168 template<
int_t M,
typename T,
int S,
class W>
169 class DFTk_x_Im_T<3,M,T,S,W,false> {
170 typedef typename TempTypeTrait<T>::Result LocalVType;
171 typedef Compute<typename W::Re,2> WR;
172 typedef Compute<typename W::Im,2> WI;
173 static const int_t N = 3*M;
174 static const int_t M2 = M*2;
175 DFTk_inp<3,M2,T,S> spec_inp;
179 spec_inp.apply(data);
181 LocalVType wr[2],wi[2],t;
187 const LocalVType wpr1 = WR::value();
188 const LocalVType wpi1 = WI::value();
191 const LocalVType wpr2 = wpr1*wpr1 - wpi1*wpi1;
192 const LocalVType wpi2 = 2*wpr1*wpi1;
198 for (int_t i=2; i<M2; i+=2) {
199 spec_inp.apply(data+i, wr, wi);
202 wr[0] = t*wpr1 - wi[0]*wpi1;
203 wi[0] = wi[0]*wpr1 + t*wpi1;
205 wr[1] = t*wpr2 - wi[1]*wpi2;
206 wi[1] = wi[1]*wpr2 + t*wpi2;
212 template<
int_t M,
typename T,
int S,
class W>
213 class DFTk_x_Im_T<2,M,T,S,W,false> {
214 typedef typename TempTypeTrait<T>::Result LocalVType;
215 typedef Compute<typename W::Re,2> WR;
216 typedef Compute<typename W::Im,2> WI;
217 static const int_t N = 2*M;
218 DFTk_inp<2,N,T,S> spec_inp;
222 spec_inp.apply(data);
228 const LocalVType wpr = WR::value();
229 const LocalVType wpi = WI::value();
232 for (int_t i=2; i<N; i+=2) {
233 spec_inp.apply(data+i, &wr, &wi);
236 wr = wr*wpr - wi*wpi;
256 template<
int_t N,
typename NFact,
typename T,
int S,
class W1,
int_t LastK = 1>
266 template<
int_t N,
typename Head,
typename T,
int S,
class W1,
int_t LastK>
267 class InTime<N, Loki::Typelist<Head,Loki::NullType>, T, S, W1, LastK>
269 typedef typename TempTypeTrait<T>::Result LocalVType;
270 static const int_t K = Head::first::value;
271 static const int_t M = N/K;
272 static const int_t M2 = M*2;
273 static const int_t N2 = N*2;
275 typedef typename IPowBig<W1,K>::Result WK;
276 typedef Loki::Typelist<Pair<
typename Head::first,
SInt<Head::second::value-1> >, Loki::NullType> NFactNext;
284 for (int_t m=0; m < N2; m+=M2)
285 dft_str.apply(data + m);
287 dft_scaled.apply(data);
292 template<
int_t N,
int_t K,
typename Tail,
typename T,
int S,
class W1,
int_t LastK>
293 class InTime<N, Loki::Typelist<Pair<SInt<K>, SInt<0> >,Tail>, T, S, W1, LastK>
294 :
public InTime<N, Tail, T, S, W1, LastK> {};
298 template<
int_t N,
typename T,
int S,
class W1,
int_t LastK>
299 class InTime<N,Loki::Typelist<Pair<SInt<N>, SInt<1> >, Loki::NullType>,T,S,W1,LastK> {
300 DFTk_inp<N, 2, T, S> spec_inp;
304 spec_inp.apply(data);
323 template<
int_t N,
typename NFact,
typename T,
int S,
class W1,
int_t LastK = 1>
326 template<
int_t N,
typename Head,
typename Tail,
typename T,
int S,
class W1,
int_t LastK>
327 class InTimeOOP<N, Loki::Typelist<Head,Tail>, T, S, W1, LastK>
329 typedef typename TempTypeTrait<T>::Result LocalVType;
330 static const int_t K = Head::first::value;
331 static const int_t M = N/K;
332 static const int_t M2 = M*2;
333 static const int_t N2 = N*2;
334 static const int_t LastK2 = LastK*2;
336 typedef typename IPowBig<W1,K>::Result WK;
337 typedef Loki::Typelist<Pair<
typename Head::first,
SInt<Head::second::value-1> >, Tail> NFactNext;
343 void apply(
const T* src, T* dst)
347 for (int_t m = 0; m < N2; m+=M2, lk+=LastK2)
348 dft_str.apply(src + lk, dst + m);
350 dft_scaled.apply(dst);
355 template<
int_t N,
int_t K,
typename Tail,
typename T,
int S,
class W1,
int_t LastK>
356 class InTimeOOP<N, Loki::Typelist<Pair<SInt<K>, SInt<0> >,Tail>, T, S, W1, LastK>
357 :
public InTimeOOP<N, Tail, T, S, W1, LastK> {};
361 template<
int_t N,
typename T,
int S,
class W1,
int_t LastK>
362 class InTimeOOP<N,Loki::Typelist<Pair<SInt<N>, SInt<1> >, Loki::NullType>,T,S,W1,LastK>
363 :
public DFTk<N, LastK*2, 2, T, S> {};