Generative Fast Fourier Transforms (GFFT)  0.3
gfftfactor.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 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 __gfftfactor_h
16 #define __gfftfactor_h
17 
22 #include "sint.h"
23 
24 namespace GFFT {
25 
26 
27 template<class TList> struct Print;
28 
29 template<> struct Print<Loki::NullType> { };
30 
31 template<class Head, class Tail>
32 struct Print<Loki::Typelist<Head,Tail> > {
33  typedef typename Print<Tail>::Result Result;
34 };
35 
36 
37 template<int_t N, int_t Factor,
38 bool C = (N % Factor == 0)>
39 struct IsMultipleOf;
40 
41 template<int_t N, int_t Factor>
42 struct IsMultipleOf<N, Factor, true> {
43  static const int_t value = IsMultipleOf<N/Factor, Factor>::value + 1;
44 };
45 
46 template<int_t N, int_t Factor>
47 struct IsMultipleOf<N, Factor, false> {
48  static const int_t value = 0;
49 };
50 
51 template<int_t Factor>
52 struct IsMultipleOf<0, Factor, true> {
53  static const int_t value = 0;
54 };
55 
56 template<int_t N, int_t K,
57 template<int_t> class IntHolder = SInt,
58 int_t AddPower = 0,
59 bool C1 = ((6*K+1)*(6*K+1) <= N),
60 bool C2 = ((N % (6*K+1) == 0) || (N % (6*K+5) == 0))>
61 struct FactorizationLoop;
62 
63 template<int_t N, int_t K,
64 template<int_t> class IntHolder, int_t AddPower>
65 struct FactorizationLoop<N, K, IntHolder, AddPower, true, true>
66 {
67  static const int_t Candidate1 = 6*K + 1;
68  static const int_t Candidate2 = 6*K + 5;
69  static const int_t P1 = IsMultipleOf<N, Candidate1>::value + AddPower;
70  static const int_t P2 = IsMultipleOf<N, Candidate2>::value + AddPower;
71  static const int_t F1 = IPow<Candidate1, P1>::value;
72  static const int_t F2 = IPow<Candidate2, P2>::value;
73  typedef Pair<IntHolder<Candidate1>, IntHolder<P1> > T1;
74  typedef Pair<IntHolder<Candidate2>, IntHolder<P2> > T2;
75 
76  static const int_t NextN = N/F1/F2;
77  typedef typename FactorizationLoop<NextN, K+1, IntHolder, AddPower>::Result NextIter;
78 
79  typedef typename Loki::Select<(P1>0) && (P2>0),
80  Loki::Typelist<T1, Loki::Typelist<T2, NextIter> >,
81  typename Loki::Select<(P1>0), Loki::Typelist<T1, NextIter>,
82  typename Loki::Select<(P2>0), Loki::Typelist<T2, NextIter>, NextIter>::Result>::Result>::Result Result;
83 };
84 
85 template<int_t N, int_t K,
86 template<int_t> class IntHolder, int_t AddPower>
87 struct FactorizationLoop<N, K, IntHolder, AddPower, true, false>
88 : public FactorizationLoop<N, K+1, IntHolder, AddPower> {};
89 
90 template<int_t N, int_t K,
91 template<int_t> class IntHolder, int_t AddPower, bool C>
92 struct FactorizationLoop<N, K, IntHolder, AddPower, false, C>
93 {
94  typedef Pair<IntHolder<N>, IntHolder<1+AddPower> > T;
95  typedef Loki::Typelist<T, Loki::NullType> Result;
96 };
97 
98 template<int_t K,
99 template<int_t> class IntHolder, int_t AddPower, bool C>
100 struct FactorizationLoop<1, K, IntHolder, AddPower, false, C>
101 {
102  typedef Loki::NullType Result;
103 };
104 
105 
106 typedef TYPELIST_5(SInt<2>, SInt<3>, SInt<5>, SInt<7>, SInt<11>) InitialPrimesList;
107 
108 template<typename Num,
109 template<int_t> class IntHolder = SInt,
110 typename StartList = InitialPrimesList,
111 int_t AddPower = 0>
112 struct Factorization;
113 
114 // Factorization using trial deletion from InitialPrimesList
115 template<int_t N, template<int_t> class IntHolder, typename H, typename Tail, int_t AddPower>
116 struct Factorization<SIntID<N>, IntHolder, Loki::Typelist<H,Tail>, AddPower>
117 {
118  //static const int_t N = Num::value;
119  static const int_t P = IsMultipleOf<N, H::value>::value;
120  typedef SIntID<N / IPow<H::value,P>::value> NextNum;
121  typedef typename Factorization<NextNum,IntHolder,Tail,AddPower>::Result Next;
122  typedef typename Loki::Select<(P > 0),
123  Loki::Typelist<Pair<IntHolder<H::value>, IntHolder<P+AddPower> >, Next>, Next>::Result Result;
124 };
125 
126 // Further factorization
127 template<int_t N, template<int_t> class IntHolder, int_t AddPower>
128 struct Factorization<SIntID<N>, IntHolder, Loki::NullType, AddPower>
129 : public FactorizationLoop<N, 2, IntHolder, AddPower> {};
130 
131 // End of factorization
132 template<template<int_t> class IntHolder, typename H, typename Tail, int_t AddPower>
133 struct Factorization<SIntID<1>, IntHolder, Loki::Typelist<H,Tail>, AddPower> {
134  typedef Loki::NullType Result;
135 };
136 
137 
138 template<int_t M, int_t P>
139 struct PowerHolder;
140 
141 // The power is predefined, no factorization needed
142 template<int_t M, int_t P,
143 template<int_t> class IntHolder, typename StartList, int_t AddPower>
144 struct Factorization<PowerHolder<M,P>, IntHolder, StartList, AddPower>
145 : public Factorization<SIntID<M>, IntHolder, StartList, P-1> { };
146 
147 
148 } //namespace DFT
149 
150 #endif /*__gfftfactor_h*/

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