CMS 3D CMS Logo

Factorize.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_Factorize_h
2 #define PhysicsTools_Utilities_Factorize_h
3 
8 #include <boost/type_traits.hpp>
9 #include <boost/mpl/and.hpp>
10 #include <boost/mpl/not.hpp>
11 #include <boost/mpl/int.hpp>
12 #include <boost/mpl/if.hpp>
13 
15 
16 namespace funct {
17  // find a common divider
18 
19  TEMPL(T1) struct Divides0 {
20  static const bool value = false;
21  typedef A arg;
22  typedef NUM(1) type;
23  GET(arg, num<1>());
24  };
25 
26  TEMPL(T2) struct Divides :
27  public Divides0<A> { };
28 
29  TEMPL(T2) struct Divides<PROD_S(A, B), void> :
30  public Divides0<PROD_S(A, B)> { };
31 
33  public Divides<A, void> { };
34 
35  TEMPL(T1) struct ParametricDiv1<A, false> {
36  static const bool value = true;
37  typedef A arg;
38  typedef arg type;
39  GET(arg, _);
40  };
41 
42  TEMPL(T1) struct Divides<A, A> :
43  public ParametricDiv1<A> { };
44 
45  TEMPL(T2) struct Divides<PROD_S(A, B), PROD_S(A, B)> :
46  public ParametricDiv1<PROD_S(A, B)> { };
47 
48  TEMPL(N1T1) struct Divides<POWER_S(A, NUM(n)),
49  POWER_S(A, NUM(n))> :
50  public ParametricDiv1<POWER_S(A, NUM(n))> { };
51 
53  public Divides<POWER(A, NUM(n)), void> { };
54 
55  TEMPL(N2T1) struct ParametricDivN<n, m, A, false> {
56  static const bool value = true;
57  typedef POWER(A, NUM(n)) arg;
58  static const int p = ::boost::mpl::if_c<(n <m),
59  ::boost::mpl::int_<n>, ::boost::mpl::int_<m> >::type::value;
60  typedef POWER(A, NUM(p)) type;
61  typedef DecomposePower<A, NUM(n)> Dec;
62  GET(arg, pow(Dec::getBase(_), num<p>()));
63  };
64 
65  TEMPL(N2T1) struct Divides<POWER_S(A, NUM(n)),
66  POWER_S(A, NUM(m))> :
67  public ParametricDivN<n, m, A> { };
68 
69  TEMPL(N1T1) struct Divides<A, POWER_S(A, NUM(n))> :
70  public ParametricDivN<1, n, A> { };
71 
72  TEMPL(N1T1) struct Divides<POWER_S(A, NUM(n)), A> :
73  public ParametricDivN<n, 1, A> { };
74 
75  namespace tmpl {
76 
77  template<int n, bool positive = (n>= 0)>
78  struct abs { enum { value = n }; };
79 
80  template<int n>
81  struct abs<n, false> { enum { value = -n }; };
82 
83  }
84 
85  TEMPL(N2) struct Divides<NUM(n), NUM(m)> {
87  static const bool value = (gcd != 1);
88  typedef NUM(n) arg;
89  typedef NUM(gcd) type;
90  GET(arg, num<gcd>());
91  };
92 
93  TEMPL(N1) struct Divides<NUM(n), NUM(n)> {
94  static const bool value = true;
95  typedef NUM(n) arg;
96  typedef arg type;
97  GET(arg, _);
98  };
99 
100  TEMPL(T2) struct Divides<A, MINUS_S(B)> :
101  public Divides<A, B> { };
102 
103  TEMPL(T3) struct Divides<PROD_S(A, B), MINUS_S(C)> :
104  public Divides<PROD_S(A, B), C> { };
105 
106  TEMPL(T2) struct Divides<MINUS_S(A), B> {
107  typedef Divides<A, B> Div;
108  static const bool value = Div::value;
109  typedef MINUS_S(A) arg;
110  typedef typename Div::type type;
111  GET(arg, Div::get(_._));
112  };
113 
114  TEMPL(T2) struct Divides<MINUS_S(A), MINUS_S(B)> {
115  typedef Divides<A, B> Div;
116  static const bool value = Div::value;
117  typedef MINUS_S(A) arg;
118  typedef typename Div::type type;
119  GET(arg, Div::get(_._));
120  };
121 
122  TEMPL(T3) struct Divides<MINUS_S(A), PROD_S(B, C)> {
123  typedef Divides<A, PROD_S(B, C)> Div;
124  static const bool value = Div::value;
125  typedef MINUS_S(A) arg;
126  typedef typename Div::type type;
127  GET(arg, Div::get(_._));
128  };
129 
130  TEMPL(T3) struct Divides<A, PROD_S(B, C)> {
131  typedef A arg;
132  typedef Divides<arg, void> D0;
133  typedef Divides<arg, B> D1;
134  typedef Divides<arg, C> D2;
135  typedef typename ::boost::mpl::if_<D1, D1,
137  static const bool value = Div::value;
138  typedef typename Div::type type;
139  GET(arg, Div::get(_));
140  };
141 
142  TEMPL(T3) struct Divides<PROD_S(A, B), C> {
143  typedef PROD_S(A, B) arg;
144  typedef Divides<arg, void> D0;
145  typedef Divides<A, C> D1;
146  typedef Divides<B, C> D2;
147  typedef typename ::boost::mpl::if_<D1, D1,
149  typedef typename Div::type type;
150  static const bool value = Div::value;
152  GET(arg, Div::get(D::get(_)));
153  };
154 
155  TEMPL(T4) struct Divides<PROD_S(A, B), PROD_S(C, D)> {
156  typedef PROD_S(A, B) arg;
157  typedef Divides<arg, void> D0;
158  typedef Divides<arg, C> D1;
159  typedef Divides<arg, D> D2;
160  typedef typename ::boost::mpl::if_<D1, D1,
162  static const bool value = Div::value;
163  typedef typename Div::type type;
164  GET(arg, Div::get(_));
165  };
166 
167  /*
168  TEMPL(T4) struct Divides<RATIO_S(A, B), RATIO_S(C, D)> {
169  typedef RATIO_S(A, B) arg;
170  typedef Divides<B, D> Div;
171  static const bool value = Div::value;
172  DEF_TYPE(RATIO(NUM(1), typename Div::type))
173  GET(arg, num(1) / Div::get(_))
174  };
175  */
176 
177  // general factorization algorithm
179  struct FactorizeSum {
180  typedef SUM_S(A, B) type;
181  COMBINE(A, B, type(_1, _2));
182  };
183 
184  TEMPL(T2) struct FactorizeSum<A, B, true> {
185  typedef typename Divides<A, B>::type F;
186  typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type;
187  inline static type combine(const A& _1, const B& _2) {
188  const F& f = Divides<A, B>::get(_1);
189  return f * ((_1 / f) + (_2 / f));
190  }
191  };
192 
193  TEMPL(T3) struct Sum<PROD_S(A, B), C> :
194  public FactorizeSum<PROD_S(A, B), C> { };
195 
196  TEMPL(T3) struct Sum<A, PROD_S(B, C)> :
197  public FactorizeSum<A, PROD_S(B, C)> { };
198 
199  TEMPL(T3) struct Sum<MINUS_S(PROD_S(A, B)), C> :
200  public FactorizeSum<MINUS_S(PROD_S(A, B)), C> { };
201 
202  TEMPL(T3) struct Sum<A, MINUS_S(PROD_S(B, C))> :
203  public FactorizeSum<A, MINUS_S(PROD_S(B, C))> { };
204 
205  TEMPL(T4) struct Sum<PROD_S(A, B), PROD_S(C, D)> :
206  public FactorizeSum<PROD_S(A, B), PROD_S(C, D)> { };
207 
208  TEMPL(T4) struct Sum<MINUS_S(PROD_S(A, B)),
209  MINUS_S(PROD_S(C, D))> :
210  public FactorizeSum<MINUS_S(PROD_S(A, B)),
211  MINUS_S(PROD_S(C, D))> { };
212 
213  TEMPL(T4) struct Sum<PROD_S(A, B),
214  MINUS_S(PROD_S(C, D))> :
215  public FactorizeSum<PROD_S(A, B),
216  MINUS_S(PROD_S(C, D))> { };
217 
218  TEMPL(T4) struct Sum<MINUS_S(PROD_S(A, B)),
219  PROD_S(C, D)> :
220  public FactorizeSum<MINUS_S(PROD_S(A, B)),
221  PROD_S(C, D)> { };
222 
223  TEMPL(N1T2) struct Sum<PROD_S(A, B), NUM(n)> :
224  public FactorizeSum<PROD_S(A, B), NUM(n)> { };
225 
226  TEMPL(N1T2) struct Sum<NUM(n), PROD_S(A, B)> :
227  public FactorizeSum<NUM(n), PROD_S(A, B)> { };
228 
229  /*
230  TEMPL(T4) struct Sum<SUM_S(A, B), PROD_S(C, D)> :
231  public FactorizeSum<SUM_S(A, B), PROD_S(C, D)> { };
232 
233  TEMPL(T4) struct Sum<SUM_S(A, B), MINUS_S(PROD_S(C, D))> :
234  public FactorizeSum<SUM_S(A, B), MINUS_S(PROD_S(C, D))> { };
235 
236  TEMPL(T4) struct Sum<PROD_S(A, B), SUM_S(C, D)> :
237  public FactorizeSum<PROD_S(A, B), SUM_S(C, D)> { };
238  */
239 
240  /*
241  template <TYPT4, bool factor = Divides<B, D>::value>
242  struct FactorizeSumRatio {
243  DEF_TYPE(SUM_S(RATIO_S(A, B), RATIO_S(C, D)))
244  COMBINE(A, B, type(_1, _2))
245  };
246 
247  TEMPL(T4) struct FactorizeSumRatio<A, B, C, D, true> {
248  typedef typename Divides<B, D>::type F;
249  DEF_TYPE(PROD(RATIO(NUM(1), F),
250  SUM(RATIO(PROD(A, F), B),
251  RATIO(PROD(C, F), D))))
252  inline static type combine(const RATIO_S(A, B)& _1,
253  const RATIO_S(C, D)& _2) {
254  const F& f = Divides<B, D>::get(_1);
255  return (num(1) / f) * ((_1._1 * f) / _1._2 + (_2._1 * f) / _2._2);
256  }
257  };
258 
259  TEMPL(T4) struct Sum<RATIO_S(A, B), RATIO_S(C, D)> :
260  public FactorizeSum<RATIO_S(A, B), RATIO_S(C, D)> { };
261  */
262 }
263 
265 
266 #endif
static const bool value
Definition: Factorize.h:108
type
Definition: HCALResponse.h:21
Divides< B, C > D2
Definition: Factorize.h:146
const Numerical< n > & num()
Definition: Numerical.h:16
typedef POWER(A, NUM(n)) arg
Definition: Abs.h:5
MINUS_S(B)>
Definition: Factorize.h:100
Divides< arg, void > D0
Definition: Factorize.h:144
PROD_S(A, B)>
Definition: Factorize.h:45
A arg
Definition: Factorize.h:37
#define SUM_S(A, B)
static type combine(const A &_1, const B &_2)
Definition: Factorize.h:187
Divides< A, C > D1
Definition: Factorize.h:145
#define RATIO(A, B)
double f[11][100]
Definition: value.py:1
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:151
#define SUM(A, B)
TEMPL(T1) struct Divides0
Definition: Factorize.h:19
arg type
Definition: Factorize.h:38
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
GET(arg, _)
Definition: Sum.h:26
#define COMBINE(A, B, RES)
static const int p
Definition: Factorize.h:58
NUM(n))
Definition: Factorize.h:93
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
static type get(const PROD_S(A, B)&_)
Definition: Primitive.h:171
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
T get(const Candidate &c)
Definition: component.h:55
::boost::mpl::if_< D1, D1, typename::boost::mpl::if_< D2, D2, D0 >::type >::type Div
Definition: Factorize.h:148