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 <type_traits>
15 
16 namespace funct {
17 
18  // 0 / a = 0
19  RATIO_RULE(TYPT1, NUM(0), A, NUM(0), num<0>());
20 
21  // a / 1 = a
22  RATIO_RULE(TYPT1, A, NUM(1), A, _1);
23 
24  // ( a * b )/ 1 = a * b
25  RATIO_RULE(TYPT2, PROD_S(A, B), NUM(1), PROD(A, B), _1);
26 
27  // a / ( -n ) = - ( a / n )
28  template <int n, typename A, bool positive = (n >= 0)>
30  typedef RATIO_S(A, NUM(n)) type;
31  COMBINE(A, NUM(n), type(_1, _2));
32  };
33 
34  TEMPL(N1T1)
36  typedef MINUS(RATIO(A, NUM(-n))) type;
37  COMBINE(A, NUM(n), -(_1 / num<-n>()));
38  };
39 
40  TEMPL(N1T1) struct Ratio<A, NUM(n)> : public SimplifyNegativeRatio<n, A> {};
41 
42  // ( -a ) / b = - ( a / b )
43  RATIO_RULE(TYPT2, MINUS_S(A), B, MINUS(RATIO(A, B)), -(_1._ / _2));
44 
45  // ( -a ) / n = - ( a / n )
46  RATIO_RULE(TYPN1T1, MINUS_S(A), NUM(n), MINUS(RATIO(A, NUM(n))), -(_1._ / _2));
47 
48  //TEMPL( N1T2 struct Ratio<PROD_S( A, B ), NUM( n )> :
49  // public SimplifyNegativeRatio<n, PROD_S( A, B )> { };
50 
51  // n / ( m * a ) = (n/m) * a
52  /* WRONG!!
53  RATIO_RULE(TYPN2T1, NUM(n), PROD_S(NUM(m), A), \
54  PROD(FRACT(n, m), A), (fract<n, m>() * _2._2));
55  */
56  // ( a / b ) / c = a / ( b * c )
57  RATIO_RULE(TYPT3, RATIO_S(A, B), C, RATIO(A, PROD(B, C)), _1._1 / (_1._2 * _2));
58 
59  // ( a / b ) / n = a / ( n * b )
60  RATIO_RULE(TYPN1T2, RATIO_S(A, B), NUM(n), RATIO(A, PROD(NUM(n), B)), _1._1 / (_2 * _1._2));
61 
62  // ( a / b ) / ( c * d ) = a / ( b * c * d )
63  RATIO_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D), RATIO(A, PROD(PROD(B, C), D)), _1._1 / (_1._2 * _2));
64 
65  // ( a * b ) / ( c / d ) = ( a * b * d ) / c
66  RATIO_RULE(TYPT4, PROD_S(A, B), RATIO_S(C, D), RATIO(PROD(PROD(A, B), D), C), (_1 * _2._2) / _2._1);
67 
68  // ( n * a ) / ( m * b ) = ( n/m ) ( a / b )
70  PROD_S(NUM(n), A),
71  PROD_S(NUM(m), B),
72  PROD_S(FRACT(n, m), RATIO(A, B)),
73  (PROD_S(FRACT(n, m), RATIO(A, B))((fract<n, m>()), (_1._2 / _2._2))));
74 
75  // a / ( b / c ) = a * c / b
76  RATIO_RULE(TYPT3, A, RATIO_S(B, C), RATIO(PROD(A, C), B), (_1 * _2._2) / _2._1);
77 
78  // ( a + b ) / ( c / d ) = ( a + b ) * d / c
79  RATIO_RULE(TYPT4, SUM_S(A, B), RATIO_S(C, D), RATIO(PROD(SUM(A, B), D), C), (_1 * _2._2) / _2._1);
80 
81  // ( a / b ) / ( c / d )= a * d / ( b * c )
82  RATIO_RULE(TYPT4, RATIO_S(A, B), RATIO_S(C, D), RATIO(PROD(A, D), PROD(B, C)), (_1._1 * _2._2) / (_1._2 * _2._1));
83 
84  // ( a + b ) / ( b + a ) = 1
87  typedef RATIO_S(SUM(A, B), SUM(B, A)) type;
88  COMBINE(SUM(A, B), SUM(B, A), type(_1, _2));
89  };
90 
91  TEMPL(T2) struct SimplifyRatioSum<A, B, false> {
92  typedef NUM(1) type;
93  COMBINE(SUM(A, B), SUM(B, A), num<1>());
94  };
95 
96  TEMPL(T2) struct Ratio<SUM_S(A, B), SUM_S(B, A)> : public SimplifyRatioSum<A, B> {};
97 
98  // a^b / a^c => a^( b - c)
101  typedef POWER(A, B) arg1;
102  typedef POWER(A, C) arg2;
103  typedef RATIO_S(arg1, arg2) type;
104  COMBINE(arg1, arg2, type(_1, _2));
105  };
106 
107  TEMPL(T3)
108  struct SimplifyPowerRatio<A, B, C, false> {
109  typedef POWER(A, B) arg1;
110  typedef POWER(A, C) arg2;
111  typedef POWER(A, DIFF(B, C)) type;
112  inline static type combine(const arg1& _1, const arg2& _2) {
115  }
116  };
117 
118  TEMPL(T3) struct Ratio<POWER_S(A, B), POWER_S(A, C)> : public SimplifyPowerRatio<A, B, C> {};
119 
120  TEMPL(T2) struct Ratio<POWER_S(A, B), POWER_S(A, B)> : public SimplifyPowerRatio<A, B, B> {};
121 
122  TEMPL(T2) struct Ratio<A, POWER_S(A, B)> : public SimplifyPowerRatio<A, NUM(1), B> {};
123 
124  TEMPL(N1T1) struct Ratio<A, POWER_S(A, NUM(n))> : public SimplifyPowerRatio<A, NUM(1), NUM(n)> {};
125 
126  TEMPL(T2) struct Ratio<POWER_S(A, B), A> : public SimplifyPowerRatio<A, B, NUM(1)> {};
127 
128  TEMPL(N1T1) struct Ratio<POWER_S(A, NUM(n)), A> : public SimplifyPowerRatio<A, NUM(n), NUM(1)> {};
129 
130  TEMPL(T1) struct Ratio<A, A> : public SimplifyPowerRatio<A, NUM(1), NUM(1)> {};
131 
132  TEMPL(T2) struct Ratio<PROD_S(A, B), PROD_S(A, B)> : public SimplifyPowerRatio<PROD_S(A, B), NUM(1), NUM(1)> {};
133 
134  TEMPL(N1T1)
135  struct Ratio<PROD_S(NUM(n), A), PROD_S(NUM(n), A)> : public SimplifyPowerRatio<PROD_S(NUM(n), A), NUM(1), NUM(1)> {};
136 
137  RATIO_RULE(TYPN1, NUM(n), NUM(n), NUM(1), num<1>());
138 
139  // simplify ( f * g ) / h
140  // try ( f / h ) * g and ( g / h ) * f, otherwise leave ( f * g ) / h
141 
142  template <typename Prod, bool simplify = Prod::value>
144  typedef PROD(typename Prod::AB, typename Prod::C) type;
145  inline static type combine(const typename Prod::A& a, const typename Prod::B& b, const typename Prod::C& c) {
146  return (a / b) * c;
147  }
148  };
149 
150  template <typename Prod>
151  struct AuxProductRatio<Prod, false> {
152  typedef RATIO_S(typename Prod::AB, typename Prod::C) type;
153  inline static type combine(const typename Prod::A& a, const typename Prod::B& b, const typename Prod::C& c) {
154  return type(a * b, c);
155  }
156  };
157 
158  template <typename F, typename G, typename H>
159  struct RatioP1 {
160  struct prod0 {
161  typedef F A;
162  typedef G B;
163  typedef H C;
164  typedef PROD_S(A, B) AB;
165  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
166  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
167  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
168  enum { value = false };
169  };
170  struct prod1 {
171  typedef F A;
172  typedef H B;
173  typedef G C;
174  typedef RATIO_S(A, B) base;
175  typedef RATIO(A, B) AB;
176  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
177  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
178  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
180  };
181  struct prod2 {
182  typedef G A;
183  typedef H B;
184  typedef F C;
185  typedef RATIO_S(A, B) base;
186  typedef RATIO(A, B) AB;
187  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
188  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
189  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
191  };
192 
193  typedef
197  inline static type combine(const PROD_S(F, G) & fg, const H& h) {
198  const F& f = fg._1;
199  const G& g = fg._2;
200  const typename prod::A& a = prod::a(f, g, h);
201  const typename prod::B& b = prod::b(f, g, h);
202  const typename prod::C& c = prod::c(f, g, h);
204  }
205  };
206 
207  // simplify c / ( a * b )
208  // try ( c / a ) / b and ( c / b ) / a, otherwise leave c / ( a * b )
209 
210  template <typename Prod, bool simplify = Prod::value>
212  typedef RATIO(typename Prod::AB, typename Prod::C) type;
213  inline static type combine(const typename Prod::A& a, const typename Prod::B& b, const typename Prod::C& c) {
214  return (b / a) / c;
215  }
216  };
217 
218  template <typename Prod>
219  struct AuxProductRatio2<Prod, false> {
220  typedef RATIO_S(typename Prod::C, typename Prod::AB) type;
221  inline static type combine(const typename Prod::A& a, const typename Prod::B& b, const typename Prod::C& c) {
222  return type(c, a * b);
223  }
224  };
225 
226  template <typename F, typename G, typename H>
227  struct RatioP2 {
228  struct prod0 {
229  typedef F A;
230  typedef G B;
231  typedef H C;
232  typedef PROD_S(A, B) AB;
233  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
234  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
235  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
236  enum { value = false };
237  };
238  struct prod1 {
239  typedef F A;
240  typedef H B;
241  typedef G C;
242  typedef RATIO_S(B, A) base;
243  typedef RATIO(B, A) AB;
244  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
245  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
246  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
248  };
249  struct prod2 {
250  typedef G A;
251  typedef H B;
252  typedef F C;
253  typedef RATIO_S(B, A) base;
254  typedef RATIO(B, A) AB;
255  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
256  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
257  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
259  };
260 
261  typedef
265  inline static type combine(const H& h, const PROD_S(F, G) & fg) {
266  const F& f = fg._1;
267  const G& g = fg._2;
268  const typename prod::A& a = prod::a(f, g, h);
269  const typename prod::B& b = prod::b(f, g, h);
270  const typename prod::C& c = prod::c(f, g, h);
272  }
273  };
274 
275  TEMPL(T3) struct Ratio<PROD_S(A, B), C> : public RatioP1<A, B, C> {};
276 
277  TEMPL(N1T2) struct Ratio<PROD_S(A, B), NUM(n)> : public RatioP1<A, B, NUM(n)> {};
278 
279  TEMPL(T3) struct Ratio<C, PROD_S(A, B)> : public RatioP2<A, B, C> {};
280 
281  TEMPL(T4) struct Ratio<PROD_S(C, D), PROD_S(A, B)> : public RatioP2<A, B, PROD_S(C, D)> {};
282 
283  // simplify ( a + b ) / c trying to simplify ( a / c ) and ( b / c )
284  template <TYPT3, bool simplify = false>
285  struct AuxSumRatio {
286  typedef RATIO_S(SUM_S(A, B), C) type;
287  COMBINE(SUM_S(A, B), C, type(_1, _2));
288  };
289 
290  TEMPL(T3) struct AuxSumRatio<A, B, C, true> {
291  typedef SUM(RATIO(A, C), RATIO(B, C)) type;
292  COMBINE(SUM_S(A, B), C, (_1._1 / _2) + (_1._2 / _2));
293  };
294 
295  TEMPL(T3) struct RatioSimpl {
296  struct ratio1 {
297  typedef RATIO_S(A, C) base;
298  typedef RATIO(A, C) type;
300  };
301  struct ratio2 {
302  typedef RATIO_S(B, C) base;
303  typedef RATIO(B, C) type;
305  };
307  typedef typename aux::type type;
308  COMBINE(SUM_S(A, B), C, aux::combine(_1, _2));
309  };
310 
311  TEMPL(T3) struct Ratio<SUM_S(A, B), C> : public RatioSimpl<A, B, C> {};
312 
313  TEMPL(T4) struct Ratio<SUM_S(A, B), PROD_S(C, D)> : public RatioSimpl<A, B, PROD_S(C, D)> {};
314 
315  TEMPL(N1T2) struct Ratio<SUM_S(A, B), NUM(n)> : public RatioSimpl<A, B, NUM(n)> {};
316 
317 } // namespace funct
318 
320 
321 #endif
#define TYPN1
const Numerical< n > & num()
Definition: Numerical.h:18
AuxSumRatio< A, B, C, ratio1::value or ratio2::value > aux
Power< A, B >::type arg1
typedef POWER(A, NUM(n)) arg
ProductStruct< A, B > AB
Definition: APVGainStruct.h:7
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
ProductStruct< A, B > AB
#define TYPT2
Definition: Simplify_begin.h:7
Ratio< typename Prod::AB, typename Prod::C >::type type
#define MINUS(A)
PROD_S(B, C)>
Definition: Factorize.h:114
typedef MINUS_S(A) arg
RatioStruct< A, C > base
RatioStruct< A, B > base
static const B & b(const F &f, const G &g, const H &h)
Ratio< B, A >::type AB
static const B & b(const F &f, const G &g, const H &h)
#define RATIO_S(A, B)
Ratio< B, A >::type AB
Power< A, typename Difference< B, C >::type >::type type
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
TEMPL(T2) struct Divides B
Definition: Factorize.h:24
static const A & a(const F &f, const G &g, const H &h)
#define TYPN1T1
static const C & c(const F &f, const G &g, const H &h)
#define FRACT(N, M)
RatioStruct< arg1, arg2 > type
static const A & a(const F &f, const G &g, const H &h)
#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)
Ratio< A, C >::type type
static type combine(const arg1 &_1, const arg2 &_2)
static type combine(const typename Prod::A &a, const typename Prod::B &b, const typename Prod::C &c)
static type combine(const A &_1, const B &_2)
Definition: Factorize.h:176
#define RATIO(A, B)
Ratio< A, B >::type AB
static type combine(const typename Prod::A &a, const typename Prod::B &b, const typename Prod::C &c)
RatioStruct< B, A > base
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
#define TYPN1T2
double f[11][100]
RatioStruct< typename Prod::AB, typename Prod::C > type
Definition: value.py:1
Ratio< A, B >::type AB
#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)
Minus< typename Ratio< A, Numerical< -n > >::type >::type type
Definition: SimplifyRatio.h:36
RatioStruct< typename Prod::C, typename Prod::AB > type
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
Power< A, C >::type arg2
RatioStruct< B, A > base
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:15
double b
Definition: hdecay.h:118
static const B & b(const F &f, const G &g, const H &h)
AuxProductRatio2< prod >::type type
arg type
Definition: Factorize.h:32
static const C & c(const F &f, const G &g, const H &h)
Ratio< B, C >::type type
static const C & c(const F &f, const G &g, const H &h)
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
RatioStruct< A, Numerical< n > > type
Definition: SimplifyRatio.h:30
Product< typename Prod::AB, typename Prod::C >::type type
Sum< typename Ratio< A, C >::type, typename Ratio< B, C >::type >::type type
#define TYPN2T2
RatioStruct< B, C > base
RatioStruct< SumStruct< A, B >, C > type
double a
Definition: hdecay.h:119
static const A & a(const F &f, const G &g, const H &h)
RatioStruct< typename Sum< A, B >::type, typename Sum< B, A >::type > type
Definition: SimplifyRatio.h:87
#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
Definition: APVGainStruct.h:7
PROD_S(A, B)> NUM(n))
Definition: Factorize.h:87
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define POWER_S(A, B)
static const A & a(const F &f, const G &g, const H &h)
static const C & c(const F &f, const G &g, const H &h)
RatioStruct< A, B > base
static const A & a(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:29
#define TYPT1
Definition: Simplify_begin.h:6
static const A & a(const F &f, const G &g, const H &h)