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