CMS 3D CMS Logo

SimplifyRatio.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_SimplifyRatio_h
2 #define PhysicsTools_Utilities_SimplifyRatio_h
3 
11 
13 
14 #include <boost/mpl/if.hpp>
15 #include <type_traits>
16 
17 namespace funct {
18 
19  // 0 / a = 0
20  RATIO_RULE(TYPT1, NUM(0), A, NUM(0) , num<0>());
21 
22  // a / 1 = a
23  RATIO_RULE(TYPT1, A, NUM(1), A, _1);
24 
25  // ( a * b )/ 1 = a * b
26  RATIO_RULE(TYPT2, PROD_S(A, B), NUM(1), PROD(A, B), _1);
27 
28  // a / ( -n ) = - ( a / n )
29  template <int n, typename A, bool positive = (n>= 0)>
31  typedef RATIO_S(A, NUM(n)) type;
32  COMBINE(A, NUM(n), type(_1, _2));
33  };
34 
35  TEMPL(N1T1)
36  struct SimplifyNegativeRatio<n, A, false> {
37  typedef MINUS(RATIO(A, NUM(-n))) type;
38  COMBINE(A, NUM(n), - (_1 / num<-n>()));
39  };
40 
41  TEMPL(N1T1) struct Ratio<A, NUM(n)> :
42  public SimplifyNegativeRatio<n, A> { };
43 
44  // ( -a ) / b = - ( a / b )
45  RATIO_RULE(TYPT2, MINUS_S(A), B, MINUS(RATIO(A, B)), -(_1._ / _2));
46 
47  // ( -a ) / n = - ( a / n )
48  RATIO_RULE(TYPN1T1, MINUS_S(A), NUM(n), MINUS(RATIO(A, NUM(n))), -(_1._ / _2));
49 
50  //TEMPL( N1T2 struct Ratio<PROD_S( A, B ), NUM( n )> :
51  // public SimplifyNegativeRatio<n, PROD_S( A, B )> { };
52 
53  // n / ( m * a ) = (n/m) * a
54  /* WRONG!!
55  RATIO_RULE(TYPN2T1, NUM(n), PROD_S(NUM(m), A), \
56  PROD(FRACT(n, m), A), (fract<n, m>() * _2._2));
57  */
58  // ( a / b ) / c = a / ( b * c )
59  RATIO_RULE(TYPT3, RATIO_S(A, B), C, \
60  RATIO(A, PROD(B, C)), _1._1 / (_1._2 * _2));
61 
62  // ( a / b ) / n = a / ( n * b )
63  RATIO_RULE(TYPN1T2, RATIO_S(A, B), NUM(n), \
64  RATIO(A, PROD(NUM(n), B)), _1._1 / (_2 * _1._2));
65 
66  // ( a / b ) / ( c * d ) = a / ( b * c * d )
67  RATIO_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D), \
68  RATIO(A, PROD(PROD(B, C), D)), _1._1 / (_1._2 * _2));
69 
70  // ( a * b ) / ( c / d ) = ( a * b * d ) / c
71  RATIO_RULE(TYPT4, PROD_S(A, B), RATIO_S(C, D), \
72  RATIO(PROD(PROD(A, B), D), C), (_1 * _2._2) / _2._1);
73 
74  // ( n * a ) / ( m * b ) = ( n/m ) ( a / b )
75  RATIO_RULE(TYPN2T2, PROD_S(NUM(n), A), PROD_S(NUM(m), B), \
76  PROD_S(FRACT(n, m), RATIO(A, B)), \
77  (PROD_S(FRACT(n, m), RATIO(A, B))((fract<n, m>()), (_1._2 / _2._2))));
78 
79  // a / ( b / c ) = a * c / b
80  RATIO_RULE(TYPT3, A, RATIO_S(B, C), \
81  RATIO(PROD(A, C), B), (_1 * _2._2) / _2._1);
82 
83  // ( a + b ) / ( c / d ) = ( a + b ) * d / c
84  RATIO_RULE(TYPT4, SUM_S(A, B), RATIO_S(C, D), \
85  RATIO(PROD(SUM(A, B), D), C), (_1 * _2._2) / _2._1);
86 
87  // ( a / b ) / ( c / d )= a * d / ( b * c )
88  RATIO_RULE(TYPT4, RATIO_S(A, B), RATIO_S(C, D), \
89  RATIO(PROD(A, D), PROD(B, C)), \
90  (_1._1 * _2._2) / (_1._2 * _2._1));
91 
92  // ( a + b ) / ( b + a ) = 1
93  template<TYPT2,
94  bool parametric = (Parametric<A>::value == 1) ||
95  (Parametric<B>::value == 1)>
97  typedef RATIO_S(SUM(A, B), SUM(B, A)) type;
98  COMBINE(SUM(A, B), SUM(B, A), type(_1, _2));
99  };
100 
101  TEMPL(T2) struct SimplifyRatioSum<A, B, false> {
102  typedef NUM(1) type;
103  COMBINE(SUM(A, B), SUM(B, A), num<1>());
104  };
105 
106  TEMPL(T2) struct Ratio<SUM_S(A, B), SUM_S(B, A)> :
107  public SimplifyRatioSum<A, B> { };
108 
109  // a^b / a^c => a^( b - c)
112  typedef POWER(A, B) arg1;
113  typedef POWER(A, C) arg2;
114  typedef RATIO_S(arg1, arg2) type;
115  COMBINE(arg1, arg2, type(_1, _2));
116  };
117 
118  TEMPL(T3)
119  struct SimplifyPowerRatio<A, B, C, false> {
120  typedef POWER(A, B) arg1;
121  typedef POWER(A, C) arg2;
122  typedef POWER(A, DIFF(B, C)) type;
123  inline static type combine(const arg1& _1, const arg2& _2) {
127  };
128 
129  TEMPL(T3) struct Ratio<POWER_S(A, B), POWER_S(A, C)> :
130  public SimplifyPowerRatio<A, B, C> { };
131 
132  TEMPL(T2) struct Ratio<POWER_S(A, B), POWER_S(A, B)> :
133  public SimplifyPowerRatio<A, B, B> { };
134 
135  TEMPL(T2) struct Ratio<A, POWER_S(A, B)> :
136  public SimplifyPowerRatio<A, NUM(1), B> { };
137 
138  TEMPL(N1T1) struct Ratio<A, POWER_S(A, NUM(n))> :
139  public SimplifyPowerRatio<A, NUM(1), NUM(n)> { };
140 
141  TEMPL(T2) struct Ratio<POWER_S(A, B), A> :
142  public SimplifyPowerRatio<A, B, NUM(1)>{ };
143 
144  TEMPL(N1T1) struct Ratio<POWER_S(A, NUM(n)), A> :
145  public SimplifyPowerRatio<A, NUM(n), NUM(1)> { };
146 
147  TEMPL(T1) struct Ratio<A, A> :
148  public SimplifyPowerRatio<A, NUM(1), NUM(1)> { };
149 
150  TEMPL(T2) struct Ratio<PROD_S(A, B), PROD_S(A, B)> :
151  public SimplifyPowerRatio<PROD_S(A, B), NUM(1), NUM(1)> { };
152 
153  TEMPL(N1T1) struct Ratio<PROD_S(NUM(n), A), PROD_S(NUM(n), A)> :
154  public SimplifyPowerRatio<PROD_S(NUM(n), A), NUM(1), NUM(1)> { };
155 
156  RATIO_RULE(TYPN1, NUM(n), NUM(n), NUM(1), num<1>());
157 
158  // simplify ( f * g ) / h
159  // try ( f / h ) * g and ( g / h ) * f, otherwise leave ( f * g ) / h
160 
161  template <typename Prod, bool simplify = Prod::value> struct AuxProductRatio {
162  typedef PROD(typename Prod::AB, typename Prod::C) type;
163  inline static type combine(const typename Prod::A& a,
164  const typename Prod::B& b,
165  const typename Prod::C& c) { return (a / b) * c; }
166  };
167 
168  template<typename Prod> struct AuxProductRatio<Prod, false> {
169  typedef RATIO_S(typename Prod::AB, typename Prod::C) type;
170  inline static type combine(const typename Prod::A& a,
171  const typename Prod::B& b,
172  const typename Prod::C& c) { return type(a * b, c); }
173  };
174 
175  template<typename F, typename G, typename H>
176  struct RatioP1 {
177  struct prod0 {
178  typedef F A; typedef G B; typedef H C;
179  typedef PROD_S(A, B) AB;
180  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
181  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
182  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
183  enum { value = false };
184  };
185  struct prod1 {
186  typedef F A; typedef H B; typedef G C;
187  typedef RATIO_S(A, B) base;
188  typedef RATIO(A, B) AB;
189  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
190  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
191  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
193  };
194  struct prod2 {
195  typedef G A; typedef H B; typedef F C;
196  typedef RATIO_S(A, B) base;
197  typedef RATIO(A, B) AB;
198  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
199  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
200  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
202  };
203 
204  typedef typename
205  ::boost::mpl::if_<prod1,
206  prod1,
207  typename ::boost::mpl::if_<prod2,
208  prod2,
209  prod0
210  >::type
213  inline static type combine(const PROD_S(F, G)& fg, const H& h) {
214  const F& f = fg._1;
215  const G& g = fg._2;
216  const typename prod::A & a = prod::a(f, g, h);
217  const typename prod::B & b = prod::b(f, g, h);
218  const typename prod::C & c = prod::c(f, g, h);
219  return AuxProductRatio<prod>::combine(a, b, c);
220  }
221  };
222 
223  // simplify c / ( a * b )
224  // try ( c / a ) / b and ( c / b ) / a, otherwise leave c / ( a * b )
225 
226  template <typename Prod, bool simplify = Prod::value>
228  typedef RATIO(typename Prod::AB, typename Prod::C) type;
229  inline static type combine(const typename Prod::A& a,
230  const typename Prod::B& b,
231  const typename Prod::C& c) { return (b / a) / c; }
232  };
233 
234  template<typename Prod>
235  struct AuxProductRatio2<Prod, false> {
236  typedef RATIO_S(typename Prod::C, typename Prod::AB) type;
237  inline static type combine(const typename Prod::A& a,
238  const typename Prod::B& b,
239  const typename Prod::C& c) { return type(c, a * b); }
240  };
241 
242  template<typename F, typename G, typename H>
243  struct RatioP2 {
244  struct prod0 {
245  typedef F A; typedef G B; typedef H C;
246  typedef PROD_S(A, B) AB;
247  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
248  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
249  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
250  enum { value = false };
251  };
252  struct prod1 {
253  typedef F A; typedef H B; typedef G C;
254  typedef RATIO_S(B, A) base;
255  typedef RATIO(B, A) AB;
256  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
257  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
258  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
260  };
261  struct prod2 {
262  typedef G A; typedef H B; typedef F C;
263  typedef RATIO_S(B, A) base;
264  typedef RATIO(B, A) AB;
265  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
266  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
267  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
269  };
270 
271  typedef typename
272  ::boost::mpl::if_<prod1,
273  prod1,
274  typename ::boost::mpl::if_<prod2,
275  prod2,
276  prod0
277  >::type
280  inline static type combine(const H& h, const PROD_S(F, G)& fg) {
281  const F& f = fg._1;
282  const G& g = fg._2;
283  const typename prod::A & a = prod::a(f, g, h);
284  const typename prod::B & b = prod::b(f, g, h);
285  const typename prod::C & c = prod::c(f, g, h);
286  return AuxProductRatio2<prod>::combine(a, b, c);
287  }
288  };
289 
290  TEMPL(T3) struct Ratio<PROD_S(A, B), C> :
291  public RatioP1<A, B, C> { };
292 
293  TEMPL(N1T2) struct Ratio<PROD_S(A, B), NUM(n)> :
294  public RatioP1<A, B, NUM(n)> { };
295 
296  TEMPL(T3) struct Ratio<C, PROD_S(A, B)> :
297  public RatioP2<A, B, C> { };
298 
299  TEMPL(T4) struct Ratio<PROD_S(C, D), PROD_S(A, B)> :
300  public RatioP2<A, B, PROD_S(C, D)> { };
301 
302  // simplify ( a + b ) / c trying to simplify ( a / c ) and ( b / c )
303  template <TYPT3, bool simplify = false> struct AuxSumRatio {
304  typedef RATIO_S(SUM_S(A, B), C) type;
305  COMBINE(SUM_S(A, B), C, type(_1, _2));
306  };
307 
308  TEMPL(T3) struct AuxSumRatio<A, B, C, true> {
309  typedef SUM(RATIO(A, C), RATIO(B, C)) type;
310  COMBINE(SUM_S(A, B), C, (_1._1 / _2) + (_1._2 / _2));
311  };
312 
313  TEMPL(T3) struct RatioSimpl {
314  struct ratio1 {
315  typedef RATIO_S(A, C) base;
316  typedef RATIO(A, C) type;
318  };
319  struct ratio2 {
320  typedef RATIO_S(B, C) base;
321  typedef RATIO(B, C) type;
323  };
325  typedef typename aux::type type;
326  COMBINE(SUM_S(A, B), C, aux::combine(_1, _2));
327  };
328 
329  TEMPL(T3) struct Ratio<SUM_S(A, B), C> :
330  public RatioSimpl<A, B, C> { };
331 
332  TEMPL(T4) struct Ratio<SUM_S(A, B), PROD_S(C, D)> :
333  public RatioSimpl<A, B, PROD_S(C, D)> { };
334 
335  TEMPL(N1T2) struct Ratio<SUM_S(A, B), NUM(n)> :
336  public RatioSimpl<A, B, NUM(n)> { };
337 
338 }
339 
341 
342 #endif
#define TYPN1
const Numerical< n > & num()
Definition: Numerical.h:16
AuxSumRatio< A, B, C, ratio1::value or ratio2::value > aux
typedef POWER(A, NUM(n)) arg
static const B & b(const F &f, const G &g, const H &h)
#define RATIO_RULE(TMPL, T1, T2, RES, COMB)
Definition: Abs.h:5
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
#define TYPT2
Definition: Simplify_begin.h:7
MINUS_S(B)>
Definition: Factorize.h:101
#define MINUS(A)
PROD_S(A, B)>
Definition: Factorize.h:46
POWER_S(A, NUM(n))>
Definition: Factorize.h:50
static const B & b(const F &f, const G &g, const H &h)
static const B & b(const F &f, const G &g, const H &h)
#define RATIO_S(A, B)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
::boost::mpl::if_< prod1, prod1, typename::boost::mpl::if_< prod2, prod2, prod0 >::type >::type prod
#define TYPN1T1
static const C & c(const F &f, const G &g, const H &h)
#define FRACT(N, M)
#define SUM_S(A, B)
AuxProductRatio< prod >::type type
static const B & b(const F &f, const G &g, const H &h)
static const C & c(const F &f, const G &g, const H &h)
static const B & b(const F &f, const G &g, const H &h)
static type combine(const A &_1, const B &_2)
Definition: Factorize.h:188
#define RATIO(A, B)
static type combine(const typename Prod::A &a, const typename Prod::B &b, const typename Prod::C &c)
#define TYPN1T2
double f[11][100]
Definition: value.py:1
static const std::string B
#define TYPT4
Definition: Simplify_begin.h:9
static type combine(const typename Prod::A &a, const typename Prod::B &b, const typename Prod::C &c)
#define SUM(A, B)
static type combine(const H &h, const ProductStruct< F, G > &fg)
TEMPL(T1) struct Divides0
Definition: Factorize.h:20
double b
Definition: hdecay.h:120
static const B & b(const F &f, const G &g, const H &h)
AuxProductRatio2< prod >::type type
static const C & c(const F &f, const G &g, const H &h)
static const C & c(const F &f, const G &g, const H &h)
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
#define TYPN2T2
double a
Definition: hdecay.h:121
RatioStruct< typename Sum< A, B >::type, typename Sum< B, A >::type > type
Definition: SimplifyRatio.h:97
#define TYPT3
Definition: Simplify_begin.h:8
#define COMBINE(A, B, RES)
static type combine(const ProductStruct< F, G > &fg, const H &h)
typedef DIFF(PROD(A, B1), PRIMIT(X, PROD(A1, B1))) type
NUM(n))
Definition: Factorize.h:94
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
static const C & c(const F &f, const G &g, const H &h)
static const C & c(const F &f, const G &g, const H &h)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
#define TYPT1
Definition: Simplify_begin.h:6
::boost::mpl::if_< prod1, prod1, typename::boost::mpl::if_< prod2, prod2, prod0 >::type >::type prod