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