Generative Fast Fourier Transforms (GFFT)  0.3
metafunc.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2007-2014 by Vladimir Mirnyy *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 2 of the License, or *
7  * (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  ***************************************************************************/
14 
15 #ifndef __metafunc_h
16 #define __metafunc_h
17 
22 #include <cmath>
23 
24 #include "srational.h"
25 #include "sdecimal.h"
26 
27 #include "pseudometafunc.h"
28 
29 template<typename T>
30 struct TempTypeTrait;
31 
32 template<>
33 struct TempTypeTrait<float> {
34  typedef double Result;
35 };
36 
37 template<>
38 struct TempTypeTrait<double> {
39  typedef long double Result;
40 };
41 
42 template<typename T,
43 template<typename> class Complex>
44 struct TempTypeTrait<Complex<T> > {
45  typedef typename TempTypeTrait<T>::Result Result;
46 };
47 
48 template<typename T, typename A,
49 template<typename,typename> class Complex>
50 struct TempTypeTrait<Complex<T,A> > {
51  typedef typename TempTypeTrait<T>::Result Result;
52 };
53 
54 // template<typename T, typename A,
55 // template<typename,typename> class Complex>
56 // struct TempTypeTrait<Complex<T,A> > {
57 // typedef T Result;
58 // };
59 
61 // typedef TYPELIST_1(SInt<314159265>) NL1;
62 // typedef TYPELIST_1(SInt<100000000>) DL1;
63 // typedef SRational<SBigInt<true,NL1,DefaultBase>,SBigInt<true,DL1,DefaultBase> > TPi1;
64 //
65 // typedef TYPELIST_2(SInt<358979324>,SInt<314159265>) NL2;
66 // typedef TYPELIST_2(SInt<0>,SInt<100000000>) DL2;
67 // typedef SRational<SBigInt<true,NL2,DefaultBase>,SBigInt<true,DL2,DefaultBase> > TPi2;
68 
69 typedef TYPELIST_2(SInt<141592653>,SInt<3>) NL11;
70 typedef SDecimal<SBigInt<true,NL11,DefaultDecimalBase>,1,DefaultDecimalBase> TPi1Dec;
71 
72 typedef TYPELIST_3(SInt<589793238>,SInt<141592653>,SInt<3>) NL21;
73 typedef SDecimal<SBigInt<true,NL21,DefaultDecimalBase>,2,DefaultDecimalBase> TPi2Dec;
74 
75 typedef TYPELIST_4(SInt<462643383>,SInt<589793238>,SInt<141592653>,SInt<3>) NL31;
76 typedef SDecimal<SBigInt<true,NL31,DefaultDecimalBase>,3,DefaultDecimalBase> TPi3Dec;
77 
78 
79 // Works with SRational of decimal bases (10^n) only
80 // TODO: change that
81 template<class Rational, int_t NDigits, base_t DecBase=DefaultDecimalBase>
82 struct RationalToDecimal;
83 
84 template<class Numer, class Denom, int_t NDigits, base_t DecBase>
85 struct RationalToDecimal<SRational<Numer,Denom>,NDigits,DecBase> {
86  typedef typename MF::IPowBig<SInt<DecBase>,NDigits>::Result D;
87  typedef typename Mult<Numer,D>::Result NewNumer;
88  typedef typename Div<NewNumer,Denom>::DivResult AllDecimals;
89  typedef SDecimal<AllDecimals,NDigits,DecBase> Result;
90 };
91 
92 template<bool S1, class N1, class Denom, int_t NDigits, base_t Base>
93 struct RationalToDecimal<SRational<SBigInt<S1,N1,Base>,Denom>,NDigits,Base> {
94  typedef typename Loki::TL::ShiftRight<N1,NDigits,SInt<0> >::Result NList;
95  typedef SBigInt<S1,NList,Base> NewNumer;
96 //typedef typename NL::Print<NewNumer>::Result TT2;
97  typedef typename Div<NewNumer,Denom>::DivResult AllDecimals;
98  typedef SDecimal<AllDecimals,NDigits,Base> Result;
99 };
100 
101 template<int_t N, int_t NDigits, base_t DecBase>
102 struct RationalToDecimal<SInt<N>,NDigits,DecBase> {
103  typedef SDecimal<SInt<N>,0,DecBase> Result;
104 };
105 
106 template<class BI, int_t ND, base_t Base, int_t NDigits, base_t DecBase>
107 struct RationalToDecimal<SDecimal<BI,ND,Base>,NDigits,DecBase> {
108  typedef BI AllDecimals;
109  typedef SDecimal<BI,ND,Base> Result;
110 };
111 
113 
114 template<class N, class D, int Accuracy, base_t Base>
115 struct Reduce<SRational<N,D>,Accuracy,Base> {
116  typedef typename MF::IPowBig<SInt<Base>,Accuracy>::Result Denom;
117  typedef typename RationalToDecimal<SRational<N,D>,Accuracy,Base>::AllDecimals Decimals;
118  typedef typename Simplify<SRational<Decimals,Denom> >::Result Result;
119 };
120 
121 
123 
128 namespace MF {
129 
130 
131 template<class X, class FuncStep,
132 template<class,class> class Accum,
133 int Accuracy,
134 int_t Count>
135 struct FuncSeries
136 {
137  typedef FuncSeries<X,FuncStep,Accum,Accuracy,Count-1> NextIter;
138  typedef typename FuncStep::template Value<Count-1,X,typename NextIter::ResultAux,Accuracy> FStep;
139  typedef typename FStep::Result Step;
140  typedef typename FStep::ResultAux ResultAux;
141 
142  typedef typename Accum<Step,typename NextIter::Result>::Result Result;
143 };
144 
145 template<class X, class FuncStep,
146 template<class,class> class Accum,
147 int Accuracy>
148 struct FuncSeries<X,FuncStep,Accum,Accuracy,1>
149 {
150  typedef typename FuncStep::template Value<0,X,Loki::NullType,Accuracy> FStep;
151  typedef typename FStep::Result Result;
152  typedef typename FStep::ResultAux ResultAux;
153 };
154 
155 template<class X, class FuncStep,
156 template<class,class> class Accum,
157 int Accuracy>
158 struct FuncSeries<X,FuncStep,Accum,Accuracy,0> {}; // Error
159 
161 
162 template<class X, class FuncStep,
163 template<class,class> class Accum,
164 int Accuracy, int I,
165 class Value, class Dec1, class Dec2, class Aux,
166 bool C = (NL::Compare<Dec1,Dec2>::value == 0)>
167 class FuncAccuracyLoop;
168 
169 template<class X, class FuncStep,
170 template<class,class> class Accum,
171 int Accuracy, int I, class Value, class Dec1, class Dec2, class Aux>
172 struct FuncAccuracyLoop<X,FuncStep,Accum,Accuracy,I,Value,Dec1,Dec2,Aux,true>
173 {
174  typedef Dec2 NextDecimal;
175  typedef Value Result;
176 };
177 
178 template<class X, class FuncStep,
179 template<class,class> class Accum,
180 int Accuracy, int I, class Value, class Dec1, class Dec2, class Aux>
181 struct FuncAccuracyLoop<X,FuncStep,Accum,Accuracy,I,Value,Dec1,Dec2,Aux,false>
182 {
183  typedef typename FuncStep::template Value<I,X,Aux,Accuracy> FStep;
184  typedef typename FStep::Result NextStep;
185  typedef typename FStep::ResultAux NextAux;
186  typedef typename Accum<Value,NextStep>::Result NextValue;
187 
188  typedef typename RationalToDecimal<NextValue,Accuracy,DefaultDecimalBase>::AllDecimals NextDecimal;
189  typedef typename FuncAccuracyLoop<X,FuncStep,Accum,Accuracy,I+1,NextValue,Dec2,NextDecimal,NextAux>::Result Result;
190 };
191 
193 
194 template<class X, class FuncStep,
195 template<class,class> class Accum,
196 int Len, int I, class Value1, class Value2, class Aux,
197 bool C = (NL::Length<typename Value2::Numer>::value > Len
198  || NL::Length<typename Value2::Denom>::value > Len)>
199 class FuncLengthLoop;
200 
201 template<class X, class FuncStep,
202 template<class,class> class Accum,
203 int Len, int I, class Value1, class Value2, class Aux>
204 struct FuncLengthLoop<X,FuncStep,Accum,Len,I,Value1,Value2,Aux,true>
205 {
206  typedef Value1 Result;
207 };
208 
209 template<class X, class FuncStep,
210 template<class,class> class Accum,
211 int Len, int I, class Value1, class Value2, class Aux>
212 struct FuncLengthLoop<X,FuncStep,Accum,Len,I,Value1,Value2,Aux,false>
213 {
214  typedef typename FuncStep::template Value<I,X,Aux> FStep;
215  typedef typename FStep::Result NextStep;
216  typedef typename FStep::ResultAux NextAux;
217  typedef typename Accum<Value2,NextStep>::Result NextValue;
218  typedef typename FuncLengthLoop<X,FuncStep,Accum,Len,I+1,Value2,NextValue,NextAux>::Result Result;
219 };
220 
222 template<class Value, int Accuracy, base_t Base>
223 struct GenericAccuracyBasedFuncAdapter;
224 
225 template<class N, class D, int Accuracy, base_t Base>
226 struct GenericAccuracyBasedFuncAdapter<SRational<N,D>,Accuracy,Base>
227 {
228  typedef typename RationalToDecimal<SRational<N,D>,Accuracy,DefaultBase>::AllDecimals Result;
229 };
230 
231 template<class BI, int_t ND, int Accuracy, base_t Base>
232 struct GenericAccuracyBasedFuncAdapter<SDecimal<BI,ND,Base>,Accuracy,Base>
233 {
234  typedef typename SDecimal<BI,ND,Base>::Num Result;
235 };
236 
237 
238 template<class X, class FuncStep, // One step of the series to compute the function
239 template<class,class> class Accumulator, // How the steps are accumulated, normally Add or Mult
240 int Accuracy, // in powers of DefaultBase
241 int NStartingSteps>
242 struct GenericAccuracyBasedFunc
243 {
244  typedef FuncSeries<X,FuncStep,Accumulator,Accuracy,NStartingSteps> Sum;
245  typedef typename Sum::Result StartValue;
246  typedef typename Sum::ResultAux Aux;
247  typedef typename GenericAccuracyBasedFuncAdapter<StartValue,Accuracy,DefaultBase>::Result StartDecimal;
248 
249  typedef typename FuncStep::template Value<NStartingSteps,X,Aux,Accuracy> FStep;
250  typedef typename FStep::Result NextStep;
251  typedef typename FStep::ResultAux NextAux;
252  typedef typename Accumulator<NextStep,StartValue>::Result NextValue;
253  typedef typename GenericAccuracyBasedFuncAdapter<NextValue,Accuracy,DefaultBase>::Result NextDecimal;
254 
255  typedef FuncAccuracyLoop<X,FuncStep,Accumulator,Accuracy,NStartingSteps+1,
256  NextValue,StartDecimal,NextDecimal,NextAux> Loop;
257  //typedef SDecimal<typename Loop::NextDecimal,Accuracy,DefaultDecimalBase> ResultDecimal;
258  typedef typename Loop::Result Result;
259 };
260 
262 
263 template<class X, class FuncStep, // One step of the series to compute the function
264 template<class,class> class Accumulator, // How the steps are accumulated, normally Add or Mult
265 int Length, // in digits of DefaultBase
266 int NStartingSteps>
267 struct GenericLengthBasedFunc
268 {
269  typedef FuncSeries<X,FuncStep,Accumulator,Length,NStartingSteps> Sum;
270  typedef typename Sum::Result StartValue;
271  typedef typename Sum::ResultAux Aux;
272 
273  typedef typename FuncStep::template Value<NStartingSteps,X,Aux,Length> FStep;
274  typedef typename FStep::Result NextStep;
275  typedef typename FStep::ResultAux NextAux;
276  typedef typename Accumulator<NextStep,StartValue>::Result NextValue;
277 
278  typedef typename FuncLengthLoop<X,FuncStep,Accumulator,Length,NStartingSteps+1,StartValue,NextValue,NextAux>::Result Result;
279 };
280 
282 
283 
284 template<class SFrac, int Accuracy, class RetType = long double>
285 struct Compute;
286 
287 template<class Numer, class Denom, int Accuracy, class RetType>
288 struct Compute<SRational<Numer,Denom>,Accuracy,RetType> {
289  typedef SRational<Numer,Denom> Value;
290  typedef typename RationalToDecimal<Value,Accuracy,DefaultDecimalBase>::Result TDec;
291  typedef typename DoubleBase<typename TDec::Num>::Result BigInt;
292 
293  static RetType value() {
294  return EvaluateToFloat<BigInt,RetType>::value()
295  / DPow<DefaultDecimalBase,Accuracy,RetType>::value();
296  }
297 };
298 
299 template<int_t N, int Accuracy, class RetType>
300 struct Compute<SInt<N>,Accuracy,RetType> {
301  typedef SInt<N> BigInt;
302  static RetType value() { return static_cast<RetType>(N); }
303 };
304 
305 template<class BI, int_t ND, base_t Base, int Accuracy, class RetType>
306 struct Compute<SDecimal<BI,ND,Base>,Accuracy,RetType> {
307  typedef SDecimal<BI,ND,Base> Value;
308  typedef typename Reduce<Value,Accuracy,Base>::Result TDec;
309  typedef typename DoubleBase<typename TDec::Num>::Result BigInt;
310 
311  static RetType value() {
312  return EvaluateToFloat<BigInt,RetType>::value()
313  / DPow<Base,Accuracy,RetType>::value();
314  }
315 };
316 
317 template<int_t N, int_t ND, base_t Base, int Accuracy, class RetType>
318 struct Compute<SDecimal<SInt<N>,ND,Base>,Accuracy,RetType> {
319  typedef SDecimal<SInt<N>,ND,Base> Value;
320 
321  static RetType value() {
322  return static_cast<RetType>(N)
323  / DPow<Base,ND,RetType>::value();
324  }
325 };
326 
328 
329 template<int K,class C,class Aux>
330 struct PiRational
331 {
332  typedef typename IPowBig<SInt<16>,K>::Result PBig;
333  typedef SInt<8*K+1> TK1;
334  typedef SInt<4*K+2> TK2;
335  typedef SInt<8*K+5> TK3;
336  typedef SInt<8*K+6> TK4;
337  typedef typename Mult<typename Mult<typename Mult<TK1,TK2>::Result,
338  typename Mult<TK3,TK4>::Result>::Result,PBig>::Result Denom;
339  typedef typename Add<SInt<188>, typename Mult<SInt<4*K>,SInt<120*K+151> >::Result>::Result Numer;
340 
341  typedef typename Simplify<SRational<Numer,Denom> >::Result Result;
342 // typedef SRational<Numer,Denom> Result;
343  typedef Loki::NullType ResultAux;
344 };
345 
346 template<class C,class Aux>
347 struct PiRational<0,C,Aux>
348 {
349  typedef SRational<SInt<47>, SInt<15> > Result;
350  typedef Loki::NullType ResultAux;
351 };
352 
353 struct PiRationalFunc
354 {
355  template<int K,class C,class Aux,int Accuracy>
356  struct Value : public PiRational<K,C,Aux> {};
357 };
358 
359 
360 template<int K,class C,class Aux,int Accuracy>
361 struct PiDecimal
362 {
363  typedef typename IPowBig<SInt<16>,K>::Result PBig;
364  typedef SInt<8*K+1> TK1;
365  typedef SInt<4*K+2> TK2;
366  typedef SInt<8*K+5> TK3;
367  typedef SInt<8*K+6> TK4;
368  typedef typename Mult<typename Mult<typename Mult<TK1,TK2>::Result,
369  typename Mult<TK3,TK4>::Result>::Result,PBig>::Result Denom;
370  typedef typename Add<SInt<188>, typename Mult<SInt<4*K>,SInt<120*K+151> >::Result>::Result Numer;
371 
372  typedef SRational<Numer,Denom> F;
373  typedef typename RationalToDecimal<F,Accuracy,DefaultDecimalBase>::Result Result;
374  typedef Loki::NullType ResultAux;
375 };
376 
377 template<class C,class Aux,int Accuracy>
378 struct PiDecimal<0,C,Aux,Accuracy>
379 {
380  typedef SRational<SInt<47>, SInt<15> > F;
381  typedef typename RationalToDecimal<F,Accuracy,DefaultDecimalBase>::Result Result;
382  typedef Loki::NullType ResultAux;
383 };
384 
385 struct PiDecimalFunc
386 {
387  template<int K,class C,class Aux,int Accuracy>
388  struct Value : public PiDecimal<K,C,Aux,Accuracy> {};
389 };
390 
391 
392 template<int Accuracy = 2, // in powers of DefaultBase
393 int NStartingSteps = 5>
394 struct PiAcc : public GenericAccuracyBasedFunc<Loki::NullType,PiRationalFunc,Add,Accuracy,NStartingSteps>
395 {};
396 
397 template<int NStartingSteps>
398 struct PiAcc<1,NStartingSteps> {
399  static const base_t Base = DefaultDecimalBase;
400  typedef TYPELIST_1(SInt<314159265>) NL1;
401  typedef TYPELIST_1(SInt<Base/10>) DL1;
402  typedef SRational<SBigInt<true,NL1,Base>,SBigInt<true,DL1,Base> > Result;
403 };
404 
405 template<int NStartingSteps>
406 struct PiAcc<2,NStartingSteps> {
407  static const base_t Base = DefaultDecimalBase;
408  typedef TYPELIST_2(SInt<358979323>,SInt<314159265>) NL2;
409  typedef TYPELIST_2(SInt<0>,SInt<Base/10>) DL2;
410  typedef SRational<SBigInt<true,NL2,Base>,SBigInt<true,DL2,Base> > Result;
411 };
412 
413 
414 template<int Accuracy = 2, // in powers of DefaultBase
415 int NStartingSteps = 5>
416 struct PiDecAcc : public GenericAccuracyBasedFunc<Loki::NullType,PiDecimalFunc,Add,Accuracy,NStartingSteps> {};
417 
418 
419 template<int Len = 2, // in powers of DefaultBase
420 int NStartingSteps = 3>
421 struct PiLen : public GenericLengthBasedFunc<Loki::NullType,PiRationalFunc,Add,Len,NStartingSteps>
422 {};
423 
425 
426 template<class X, class Step, class Aux = Loki::NullType>
427 struct SinCosAux
428 {
429  typedef Pair<typename Aux::first, Step> Result;
430 };
431 
432 template<class X, class Step>
433 struct SinCosAux<X,Step,Loki::NullType>
434 {
435  typedef typename Mult<X,X>::Result XX;
436  typedef Pair<XX,Step> Result;
437 };
438 
439 // Aux is Pair, where the first type is X^2 and the second is the previous series member
440 template<int K, class X, class Aux, int_t D> // D=1 (for cos); D=2 (for sin)
441 struct SinCosRational
442 {
443  static const int_t M = 2*(K-1)+D;
444  typedef SRational<SInt<1>,SInt<M*(M+1)> > Divider;
445  typedef typename Mult<typename Aux::first,Divider>::Result XX;
446  typedef typename Mult<XX,typename Aux::second>::Result XP;
447  typedef typename Negate<XP>::Result Result;
448  typedef typename SinCosAux<X,Result,Aux>::Result ResultAux;
449 // typedef typename NL::Print<Result>::Result TT2;
450 };
451 
452 template<class X, class Aux, int_t D> // D=1 (for cos); D=2 (for sin)
453 struct SinCosRational<0,X,Aux,D>
454 {
455  typedef typename Aux::second Result;
456  typedef typename SinCosAux<X,Result,Aux>::Result ResultAux;
457 };
458 
459 
460 template<int K, class X, class Aux, int_t D, // D=1 (for cos); D=2 (for sin)
461 int Accuracy>
462 struct SinCosDecimal
463 {
464  static const int_t M = 2*(K-1)+D;
465  typedef SRational<SInt<1>,SInt<M*(M+1)> > Divider;
466  typedef typename RationalToDecimal<Divider,Accuracy>::Result DividerDec;
467  typedef typename Mult<typename Aux::first,DividerDec>::Result XX;
468  typedef typename Mult<XX,typename Aux::second>::Result XP;
469  typedef typename Reduce<XP,Accuracy>::Result XPR;
470  typedef typename Negate<XPR>::Result Result;
471  typedef typename SinCosAux<X,Result,Aux>::Result ResultAux;
472 };
473 
474 template<class X, class Aux, int_t D, // D=1 (for cos); D=2 (for sin)
475 int Accuracy>
476 struct SinCosDecimal<0,X,Aux,D,Accuracy>
477 {
478  typedef typename Aux::second Result;
479  typedef typename SinCosAux<X,Result,Aux>::Result ResultAux;
480 };
481 
482 
483 template<int K, class X, class Aux>
484 struct CosRational : public SinCosRational<K,X,Aux,1> {};
485 
486 template<int K, class X>
487 struct CosRational<K,X,Loki::NullType>
488 : public SinCosRational<K,X,typename SinCosAux<X,SInt<1> >::Result,1> {};
489 
490 struct CosRationalFunc {
491  template<int K, class X, class Aux, int Accuracy>
492  struct Value : public CosRational<K,X,Aux> {};
493 };
494 
495 
496 template<int K, class X, class Aux, int Accuracy>
497 struct CosDecimal : public SinCosDecimal<K,X,Aux,1,Accuracy> {};
498 
499 template<int K, class X, int Accuracy>
500 struct CosDecimal<K,X,Loki::NullType,Accuracy>
501 : public SinCosDecimal<K,X,typename SinCosAux<X,SInt<1> >::Result,1,Accuracy> {};
502 
503 struct CosDecimalFunc {
504  template<int K, class X, class Aux, int Accuracy>
505  struct Value : public CosDecimal<K,X,Aux,Accuracy> {};
506 };
507 
508 
509 template<int K, class X, class Aux>
510 struct SinRational : public SinCosRational<K,X,Aux,2> {};
511 
512 template<int K, class X>
513 struct SinRational<K,X,Loki::NullType>
514 : public SinCosRational<K,X,typename SinCosAux<X,X>::Result,2> {};
515 
516 struct SinRationalFunc {
517  template<int K, class X, class Aux, int Accuracy>
518  struct Value : public SinRational<K,X,Aux> {};
519 };
520 
521 
522 template<int K, class X, class Aux, int Accuracy>
523 struct SinDecimal : public SinCosDecimal<K,X,Aux,2,Accuracy> {};
524 
525 template<int K, class X, int Accuracy>
526 struct SinDecimal<K,X,Loki::NullType,Accuracy>
527 : public SinCosDecimal<K,X,typename SinCosAux<X,X>::Result,2,Accuracy> {};
528 
529 
530 struct SinDecimalFunc {
531  template<int K, class X, class Aux, int Accuracy>
532  struct Value : public SinDecimal<K,X,Aux,Accuracy> {};
533 };
534 
535 
536 template<class X,
537 int Accuracy = 2, // in powers of DefaultBase
538 int NStartingSteps = 5>
539 struct CosAcc : public GenericAccuracyBasedFunc<X,CosRationalFunc,Add,Accuracy,NStartingSteps> {};
540 
541 template<class X,
542 int Accuracy = 2, // in powers of DefaultBase
543 int NStartingSteps = 5>
544 struct CosDecAcc : public GenericAccuracyBasedFunc<X,CosDecimalFunc,Add,Accuracy,NStartingSteps> {};
545 
546 template<class X,
547 int Len = 2, // in powers of DefaultBase
548 int NStartingSteps = 3>
549 struct CosLen : public GenericLengthBasedFunc<X,CosRationalFunc,Add,Len,NStartingSteps> {};
550 
551 
552 template<class X,
553 int Accuracy = 2, // in powers of DefaultBase
554 int NStartingSteps = 5>
555 struct SinAcc : public GenericAccuracyBasedFunc<X,SinRationalFunc,Add,Accuracy,NStartingSteps> {};
556 
557 template<class X,
558 int Accuracy = 2, // in powers of DefaultBase
559 int NStartingSteps = 5>
560 struct SinDecAcc : public GenericAccuracyBasedFunc<X,SinDecimalFunc,Add,Accuracy,NStartingSteps> {};
561 
562 template<class X,
563 int Len = 2, // in powers of DefaultBase
564 int NStartingSteps = 3>
565 struct SinLen : public GenericLengthBasedFunc<X,SinRationalFunc,Add,Len,NStartingSteps> {};
566 
567 
568 template<int_t A, int_t B,
569 int Accuracy = 2, // in powers of DefaultBase
570 int NStartingSteps = 5>
571 struct __SinPiFrac {
572  typedef SRational<SInt<A>,SInt<B> > F;
573  typedef typename PiAcc<Accuracy,NStartingSteps>::Result TPi;
574  typedef typename Mult<TPi,F>::Result X;
575  typedef typename SinAcc<X,Accuracy>::Result Result;
576 };
577 
578 template<int_t A,
579 int Accuracy, int NStartingSteps>
580 struct __SinPiFrac<A,1,Accuracy,NStartingSteps> {
581  typedef SInt<0> Result;
582 };
583 
584 template<int_t A,
585 int Accuracy, int NStartingSteps>
586 struct __SinPiFrac<A,2,Accuracy,NStartingSteps> {
587  typedef typename Loki::Select<(A%4 == 1),SInt<1>,SInt<-1> >::Result Result;
588 };
589 
590 template<int_t A, int NStartingSteps>
591 struct __SinPiFrac<A,3,2,NStartingSteps> {
592  static const int_t R = A%6;
593  typedef TYPELIST_2(SInt<784438645>,SInt<866025403>) NList;
594  typedef TYPELIST_3(SInt<0>,SInt<0>,SInt<1>) DList;
597  typedef SRational<Numer,Denom> Result;
598 };
599 
600 template<int_t A, int NStartingSteps>
601 struct __SinPiFrac<A,4,2,NStartingSteps> {
602  static const int_t R = A%8;
603  typedef TYPELIST_2(SInt<186547523>,SInt<707106781>) NList;
604  typedef TYPELIST_3(SInt<0>,SInt<0>,SInt<1>) DList;
607  typedef SRational<Numer,Denom> Result;
608 };
609 
610 template<int_t A,
611 int Accuracy, int NStartingSteps>
612 struct __SinPiFrac<A,6,Accuracy,NStartingSteps> {
613  static const int_t R = A%12;
614  typedef SRational<SInt<1>,SInt<2> > V1;
615  typedef SRational<SInt<-1>,SInt<2> > V2;
616  typedef typename Loki::Select<(R==1 || R==5),V1,V2>::Result Result;
617 };
618 
619 template<int_t A, int_t B,
620 int Accuracy = 2, // in powers of DefaultBase
621 int NStartingSteps = 5>
622 struct SinPiFrac {
623  typedef SRational<SInt<A>,SInt<B> > F;
624  typedef typename Simplify<F>::Result SF;
625  typedef typename __SinPiFrac<SF::Numer::value,SF::Denom::value,Accuracy,NStartingSteps>::Result Result;
626 };
627 
628 
629 template<int_t A, int_t B,
630 int Accuracy, // in powers of DefaultBase
631 int NStartingSteps = 5>
632 struct __SinPiDecimal {
633  typedef SRational<SInt<A>,SInt<B> > F;
634  typedef typename RationalToDecimal<F,Accuracy>::Result FDec;
635  typedef typename PiDecAcc<Accuracy,NStartingSteps>::Result TPi;
636  //typedef TPi2Dec TPi; // <<< TODO: make general accuracy
637  //typedef TPi3Dec TPi; // <<< TODO: make general accuracy
638  //typedef TPi1Dec TPi; // <<< TODO: make general accuracy
639  typedef typename Mult<TPi,FDec>::Result X;
640  typedef typename Reduce<X,Accuracy>::Result XR;
641  typedef typename SinDecAcc<XR,Accuracy>::Result Result;
642 };
643 
644 template<int_t A,
645 int Accuracy, int NStartingSteps>
646 struct __SinPiDecimal<A,1,Accuracy,NStartingSteps> {
647  typedef SInt<0> Result;
648 };
649 
650 template<int_t A,
651 int Accuracy, int NStartingSteps>
652 struct __SinPiDecimal<A,2,Accuracy,NStartingSteps> {
653  typedef typename Loki::Select<(A%4 == 1),SInt<1>,SInt<-1> >::Result Result;
654 };
655 
656 template<int_t A, int NStartingSteps>
657 struct __SinPiDecimal<A,3,2,NStartingSteps> {
658  static const int_t R = A%6;
659  typedef TYPELIST_2(SInt<784438645>,SInt<866025403>) NList;
661  typedef SDecimal<Numer,2,DefaultDecimalBase> Result;
662 };
663 
664 template<int_t A, int NStartingSteps>
665 struct __SinPiDecimal<A,4,2,NStartingSteps> {
666  static const int_t R = A%8;
667  typedef TYPELIST_2(SInt<186547523>,SInt<707106781>) NList;
669  typedef SDecimal<Numer,2,DefaultDecimalBase> Result;
670 };
671 
672 template<int_t A,
673 int Accuracy, int NStartingSteps>
674 struct __SinPiDecimal<A,6,Accuracy,NStartingSteps> {
675  static const int_t R = A%12;
676  typedef Loki::Typelist<SInt<500000000>,Loki::NullType> NList1;
677  typedef typename Loki::TL::ShiftRight<NList1,Accuracy-1,SInt<0> >::Result NList;
679  typedef SDecimal<Numer,2,DefaultDecimalBase> Result;
680 };
681 
682 template<int_t A, int_t B,
683 int Accuracy = 2, // in powers of DefaultBase
684 int NStartingSteps = 5>
685 struct SinPiDecimal {
686  typedef SRational<SInt<A>,SInt<B> > F;
687  typedef typename Simplify<F>::Result SF;
688  typedef typename __SinPiDecimal<SF::Numer::value,SF::Denom::value,Accuracy,NStartingSteps>::Result Result;
689 };
690 
691 
692 
693 template<int_t A, int_t B,
694 int Accuracy = 2, // in powers of DefaultBase
695 int NStartingSteps = 5>
696 struct __CosPiFrac {
697  typedef SRational<SInt<A>,SInt<B> > F;
698  typedef typename PiAcc<Accuracy,NStartingSteps>::Result TPi;
699  typedef typename Mult<TPi,F>::Result X;
700  typedef typename CosAcc<X,Accuracy>::Result Result;
701 };
702 
703 template<int_t A,
704 int Accuracy, int NStartingSteps>
705 struct __CosPiFrac<A,1,Accuracy,NStartingSteps> {
706  typedef typename Loki::Select<(A%2==0),SInt<1>,SInt<-1> >::Result Result;
707 };
708 
709 template<int_t A,
710 int Accuracy, int NStartingSteps>
711 struct __CosPiFrac<A,2,Accuracy,NStartingSteps> {
712  typedef SInt<0> Result;
713 };
714 
715 template<int_t A, int_t B,
716 int Accuracy = 2, // in powers of DefaultBase
717 int NStartingSteps = 5>
718 struct CosPiFrac {
719  typedef SRational<SInt<A>,SInt<B> > F;
720  typedef typename Simplify<F>::Result SF;
721  typedef typename __CosPiFrac<SF::Numer::value,SF::Denom::value,Accuracy,NStartingSteps>::Result Result;
722 };
723 
724 
725 
726 template<int_t A, int_t B,
727 int Accuracy = 2, // in powers of DefaultBase
728 int NStartingSteps = 5>
729 struct __CosPiDecimal {
730  typedef SRational<SInt<A>,SInt<B> > F;
731  typedef typename RationalToDecimal<F,Accuracy>::Result FDec;
732  typedef typename PiDecAcc<Accuracy,NStartingSteps>::Result TPi;
733  //typedef TPi2Dec TPi; // <<< TODO: make general accuracy
734  //typedef TPi3Dec TPi; // <<< TODO: make general accuracy
735  typedef typename Mult<TPi,FDec>::Result X;
736  typedef typename Reduce<X,Accuracy>::Result XR;
737  typedef typename CosDecAcc<XR,Accuracy>::Result Result;
738 };
739 
740 template<int_t A,
741 int Accuracy, int NStartingSteps>
742 struct __CosPiDecimal<A,1,Accuracy,NStartingSteps> {
743  typedef typename Loki::Select<(A%2==0),SInt<1>,SInt<-1> >::Result Result;
744 };
745 
746 template<int_t A,
747 int Accuracy, int NStartingSteps>
748 struct __CosPiDecimal<A,2,Accuracy,NStartingSteps> {
749  typedef SInt<0> Result;
750 };
751 
752 template<int_t A, int_t B,
753 int Accuracy = 2, // in powers of DefaultBase
754 int NStartingSteps = 5>
755 struct CosPiDecimal {
756  typedef SRational<SInt<A>,SInt<B> > F;
757  typedef typename Simplify<F>::Result SF;
758  typedef typename __CosPiDecimal<SF::Numer::value,SF::Denom::value,Accuracy,NStartingSteps>::Result Result;
759 };
760 
761 
763 
764 template<class T>
765 struct Cout;
766 
767 template<int_t N>
768 struct Cout<SInt<N> >
769 {
770  static void apply(std::ostream& os) {
771  os << N;
772  }
773 };
774 
775 template<bool S, class H, class T, base_t Base>
776 struct Cout<SBigInt<S,Loki::Typelist<H,T>,Base> >
777 {
778  static const int_t W = NDigits<Base-1,10>::value;
779  typedef Cout<SBigInt<S,T,Base> > Next;
780 
781  static void apply(std::ostream& os) {
782  Next::apply(os);
783  os.fill('0');
784  os.width(W);
785  os << std::right << H::value << " ";
786  }
787 };
788 
789 template<bool S, class H, base_t Base>
790 struct Cout<SBigInt<S,Loki::Typelist<H,Loki::NullType>,Base> > {
791  static void apply(std::ostream& os) {
792 // os << H::Value << " ";
793  if (!S)
794  os << "-";
795  os << H::value << " ";
796  }
797 };
798 
799 template<class N, class D>
800 struct Cout<SRational<N,D> >
801 {
802  typedef Cout<N> CN;
803  typedef Cout<D> CD;
804 
805  static void apply(std::ostream& os) {
806  CN::apply(os);
807  os << " / ";
808  CD::apply(os);
809  }
810 };
811 
813 
814 template<bool S, class H, class T, base_t Base, int_t NDecPlaces, base_t DecBase>
815 struct Cout<SDecimal<SBigInt<S,Loki::Typelist<H,T>,Base>,NDecPlaces,DecBase> >
816 {
817  static const int_t W = NDigits<Base-1,10>::value;
818  static const int_t DW = NDigits<DecBase-1,10>::value;
819  static const int_t Len = NL::Length<SBigInt<S,Loki::Typelist<H,T>,Base> >::value;
820  static const int_t DP = DW * NDecPlaces;
821  typedef Cout<SDecimal<SBigInt<S,T,Base>,NDecPlaces,DecBase> > Next;
822 
823  static void apply(std::ostream& os, const int_t len = 0) {
824  Next::apply(os,len+W);
825  os.fill('0');
826  if (DP < len+W && DP > len) {
827  int_t d = 1;
828  for (int i = 0; i < DP-len; ++i) d *= 10;
829  os.width(W-DP+len);
830  os << std::right << H::value/d << "." << H::value%d;
831  }
832  else {
833  os.width(W);
834  os << std::right << H::value;
835  }
836  if (DP == len)
837  os << ".";
838  }
839 };
840 
841 template<bool S, class H, base_t Base, int_t NDecPlaces, base_t DecBase>
842 struct Cout<SDecimal<SBigInt<S,Loki::Typelist<H,Loki::NullType>,Base>,NDecPlaces,DecBase> >
843 {
844  static const int_t HW = NDigits<H::value,10>::value;
845  static const int_t DP = NDigits<DecBase-1,10>::value * NDecPlaces;
846 
847  static void apply(std::ostream& os, const int_t len = 0)
848  {
849  if (!S)
850  os << "-";
851  if (DP >= len+HW) {
852  os << "0.";
853  os.fill('0');
854  os.width(DP-len);
855  os << std::right << H::value;
856  }
857  else if (DP < len+HW && DP > len) {
858  int_t d = 1;
859  for (int i = 0; i < DP-len; ++i) d *= 10;
860  os << H::value/d << "." << H::value%d;
861  }
862  else
863  os << H::value;
864  if (DP == len)
865  os << ".";
866  }
867 };
868 
869 template<int_t N, int_t NDecPlaces, base_t DecBase>
870 struct Cout<SDecimal<SInt<N>,NDecPlaces,DecBase> >
871 {
872  static const bool S = (N>=0);
873  static const int_t AN = S ? N : -N;
874  static const int_t HW = NDigits<AN,10>::value;
875 
876  static void apply(std::ostream& os, const int_t len = 0)
877  {
878  if (!S)
879  os << "-";
880  if (NDecPlaces >= len+HW) {
881  os << "0.";
882  os.fill('0');
883  os.width(NDecPlaces-len);
884  os << std::right << AN;
885  }
886  else if (NDecPlaces < len+HW && NDecPlaces > len) {
887  int_t d = 1;
888  for (int i = 0; i < NDecPlaces-len; ++i) d *= 10;
889  os << AN/d << "." << AN%d;
890  }
891  else
892  os << AN;
893  }
894 };
895 
896 } // namespace MF
897 
898 #endif /*__metafunc_h*/

Generated on Mon Feb 10 2014 for Generative Fast Fourier Transforms (GFFT) by DoxyGen 1.8.3.1