CMS 3D CMS Logo

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