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 
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)
35  struct SimplifyNegativeRatio<n, A, false> {
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)> :
41  public SimplifyNegativeRatio<n, A> { };
42 
43  // ( -a ) / b = - ( a / b )
44  RATIO_RULE(TYPT2, MINUS_S(A), B, MINUS(RATIO(A, B)), -(_1._ / _2));
45 
46  // ( -a ) / n = - ( a / n )
47  RATIO_RULE(TYPN1T1, MINUS_S(A), NUM(n), MINUS(RATIO(A, NUM(n))), -(_1._ / _2));
48 
49  //TEMPL( N1T2 struct Ratio<PROD_S( A, B ), NUM( n )> :
50  // public SimplifyNegativeRatio<n, PROD_S( A, B )> { };
51 
52  // n / ( m * a ) = (n/m) * a
53  /* WRONG!!
54  RATIO_RULE(TYPN2T1, NUM(n), PROD_S(NUM(m), A), \
55  PROD(FRACT(n, m), A), (fract<n, m>() * _2._2));
56  */
57  // ( a / b ) / c = a / ( b * c )
58  RATIO_RULE(TYPT3, RATIO_S(A, B), C, \
59  RATIO(A, PROD(B, C)), _1._1 / (_1._2 * _2));
60 
61  // ( a / b ) / n = a / ( n * b )
62  RATIO_RULE(TYPN1T2, RATIO_S(A, B), NUM(n), \
63  RATIO(A, PROD(NUM(n), B)), _1._1 / (_2 * _1._2));
64 
65  // ( a / b ) / ( c * d ) = a / ( b * c * d )
66  RATIO_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D), \
67  RATIO(A, PROD(PROD(B, C), D)), _1._1 / (_1._2 * _2));
68 
69  // ( a * b ) / ( c / d ) = ( a * b * d ) / c
70  RATIO_RULE(TYPT4, PROD_S(A, B), RATIO_S(C, D), \
71  RATIO(PROD(PROD(A, B), D), C), (_1 * _2._2) / _2._1);
72 
73  // ( n * a ) / ( m * b ) = ( n/m ) ( a / b )
74  RATIO_RULE(TYPN2T2, PROD_S(NUM(n), A), PROD_S(NUM(m), B), \
75  PROD_S(FRACT(n, m), RATIO(A, B)), \
76  (PROD_S(FRACT(n, m), RATIO(A, B))((fract<n, m>()), (_1._2 / _2._2))));
77 
78  // a / ( b / c ) = a * c / b
79  RATIO_RULE(TYPT3, A, RATIO_S(B, C), \
80  RATIO(PROD(A, C), B), (_1 * _2._2) / _2._1);
81 
82  // ( a + b ) / ( c / d ) = ( a + b ) * d / c
83  RATIO_RULE(TYPT4, SUM_S(A, B), RATIO_S(C, D), \
84  RATIO(PROD(SUM(A, B), D), C), (_1 * _2._2) / _2._1);
85 
86  // ( a / b ) / ( c / d )= a * d / ( b * c )
87  RATIO_RULE(TYPT4, RATIO_S(A, B), RATIO_S(C, D), \
88  RATIO(PROD(A, D), PROD(B, C)), \
89  (_1._1 * _2._2) / (_1._2 * _2._1));
90 
91  // ( a + b ) / ( b + a ) = 1
92  template<TYPT2,
93  bool parametric = (Parametric<A>::value == 1) ||
94  (Parametric<B>::value == 1)>
96  typedef RATIO_S(SUM(A, B), SUM(B, A)) type;
97  COMBINE(SUM(A, B), SUM(B, A), type(_1, _2));
98  };
99 
100  TEMPL(T2) struct SimplifyRatioSum<A, B, false> {
101  typedef NUM(1) type;
102  COMBINE(SUM(A, B), SUM(B, A), num<1>());
103  };
104 
105  TEMPL(T2) struct Ratio<SUM_S(A, B), SUM_S(B, A)> :
106  public SimplifyRatioSum<A, B> { };
107 
108  // a^b / a^c => a^( b - c)
111  typedef POWER(A, B) arg1;
112  typedef POWER(A, C) arg2;
113  typedef RATIO_S(arg1, arg2) type;
114  COMBINE(arg1, arg2, type(_1, _2));
115  };
116 
117  TEMPL(T3)
118  struct SimplifyPowerRatio<A, B, C, false> {
119  typedef POWER(A, B) arg1;
120  typedef POWER(A, C) arg2;
121  typedef POWER(A, DIFF(B, C)) type;
122  inline static type combine(const arg1& _1, const arg2& _2) {
126  };
127 
128  TEMPL(T3) struct Ratio<POWER_S(A, B), POWER_S(A, C)> :
129  public SimplifyPowerRatio<A, B, C> { };
130 
131  TEMPL(T2) struct Ratio<POWER_S(A, B), POWER_S(A, B)> :
132  public SimplifyPowerRatio<A, B, B> { };
133 
134  TEMPL(T2) struct Ratio<A, POWER_S(A, B)> :
135  public SimplifyPowerRatio<A, NUM(1), B> { };
136 
137  TEMPL(N1T1) struct Ratio<A, POWER_S(A, NUM(n))> :
138  public SimplifyPowerRatio<A, NUM(1), NUM(n)> { };
139 
140  TEMPL(T2) struct Ratio<POWER_S(A, B), A> :
141  public SimplifyPowerRatio<A, B, NUM(1)>{ };
142 
143  TEMPL(N1T1) struct Ratio<POWER_S(A, NUM(n)), A> :
144  public SimplifyPowerRatio<A, NUM(n), NUM(1)> { };
145 
146  TEMPL(T1) struct Ratio<A, A> :
147  public SimplifyPowerRatio<A, NUM(1), NUM(1)> { };
148 
149  TEMPL(T2) struct Ratio<PROD_S(A, B), PROD_S(A, B)> :
150  public SimplifyPowerRatio<PROD_S(A, B), NUM(1), NUM(1)> { };
151 
152  TEMPL(N1T1) struct Ratio<PROD_S(NUM(n), A), PROD_S(NUM(n), A)> :
153  public SimplifyPowerRatio<PROD_S(NUM(n), A), NUM(1), NUM(1)> { };
154 
155  RATIO_RULE(TYPN1, NUM(n), NUM(n), NUM(1), num<1>());
156 
157  // simplify ( f * g ) / h
158  // try ( f / h ) * g and ( g / h ) * f, otherwise leave ( f * g ) / h
159 
160  template <typename Prod, bool simplify = Prod::value> struct AuxProductRatio {
161  typedef PROD(typename Prod::AB, typename Prod::C) type;
162  inline static type combine(const typename Prod::A& a,
163  const typename Prod::B& b,
164  const typename Prod::C& c) { return (a / b) * c; }
165  };
166 
167  template<typename Prod> struct AuxProductRatio<Prod, false> {
168  typedef RATIO_S(typename Prod::AB, typename Prod::C) type;
169  inline static type combine(const typename Prod::A& a,
170  const typename Prod::B& b,
171  const typename Prod::C& c) { return type(a * b, c); }
172  };
173 
174  template<typename F, typename G, typename H>
175  struct RatioP1 {
176  struct prod0 {
177  typedef F A; typedef G B; typedef H C;
178  typedef PROD_S(A, B) AB;
179  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
180  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
181  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
182  enum { value = false };
183  };
184  struct prod1 {
185  typedef F A; typedef H B; typedef G C;
186  typedef RATIO_S(A, B) base;
187  typedef RATIO(A, B) AB;
188  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
189  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
190  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
192  };
193  struct prod2 {
194  typedef G A; typedef H B; typedef F C;
195  typedef RATIO_S(A, B) base;
196  typedef RATIO(A, B) AB;
197  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
198  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
199  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
201  };
202 
203  typedef typename
204  ::boost::mpl::if_<prod1,
205  prod1,
206  typename ::boost::mpl::if_<prod2,
207  prod2,
208  prod0
209  >::type
212  inline static type combine(const PROD_S(F, G)& fg, const H& h) {
213  const F& f = fg._1;
214  const G& g = fg._2;
215  const typename prod::A & a = prod::a(f, g, h);
216  const typename prod::B & b = prod::b(f, g, h);
217  const typename prod::C & c = prod::c(f, g, h);
218  return AuxProductRatio<prod>::combine(a, b, c);
219  }
220  };
221 
222  // simplify c / ( a * b )
223  // try ( c / a ) / b and ( c / b ) / a, otherwise leave c / ( a * b )
224 
225  template <typename Prod, bool simplify = Prod::value>
227  typedef RATIO(typename Prod::AB, typename Prod::C) type;
228  inline static type combine(const typename Prod::A& a,
229  const typename Prod::B& b,
230  const typename Prod::C& c) { return (b / a) / c; }
231  };
232 
233  template<typename Prod>
234  struct AuxProductRatio2<Prod, false> {
235  typedef RATIO_S(typename Prod::C, typename Prod::AB) type;
236  inline static type combine(const typename Prod::A& a,
237  const typename Prod::B& b,
238  const typename Prod::C& c) { return type(c, a * b); }
239  };
240 
241  template<typename F, typename G, typename H>
242  struct RatioP2 {
243  struct prod0 {
244  typedef F A; typedef G B; typedef H C;
245  typedef PROD_S(A, B) AB;
246  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
247  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
248  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
249  enum { value = false };
250  };
251  struct prod1 {
252  typedef F A; typedef H B; typedef G 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 f; }
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 g; }
259  };
260  struct prod2 {
261  typedef G A; typedef H B; typedef F C;
262  typedef RATIO_S(B, A) base;
263  typedef RATIO(B, A) AB;
264  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
265  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
266  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
268  };
269 
270  typedef typename
271  ::boost::mpl::if_<prod1,
272  prod1,
273  typename ::boost::mpl::if_<prod2,
274  prod2,
275  prod0
276  >::type
279  inline static type combine(const H& h, const PROD_S(F, G)& fg) {
280  const F& f = fg._1;
281  const G& g = fg._2;
282  const typename prod::A & a = prod::a(f, g, h);
283  const typename prod::B & b = prod::b(f, g, h);
284  const typename prod::C & c = prod::c(f, g, h);
285  return AuxProductRatio2<prod>::combine(a, b, c);
286  }
287  };
288 
289  TEMPL(T3) struct Ratio<PROD_S(A, B), C> :
290  public RatioP1<A, B, C> { };
291 
292  TEMPL(N1T2) struct Ratio<PROD_S(A, B), NUM(n)> :
293  public RatioP1<A, B, NUM(n)> { };
294 
295  TEMPL(T3) struct Ratio<C, PROD_S(A, B)> :
296  public RatioP2<A, B, C> { };
297 
298  TEMPL(T4) struct Ratio<PROD_S(C, D), PROD_S(A, B)> :
299  public RatioP2<A, B, PROD_S(C, D)> { };
300 
301  // simplify ( a + b ) / c trying to simplify ( a / c ) and ( b / c )
302  template <TYPT3, bool simplify = false> struct AuxSumRatio {
303  typedef RATIO_S(SUM_S(A, B), C) type;
304  COMBINE(SUM_S(A, B), C, type(_1, _2));
305  };
306 
307  TEMPL(T3) struct AuxSumRatio<A, B, C, true> {
308  typedef SUM(RATIO(A, C), RATIO(B, C)) type;
309  COMBINE(SUM_S(A, B), C, (_1._1 / _2) + (_1._2 / _2));
310  };
311 
312  TEMPL(T3) struct RatioSimpl {
313  struct ratio1 {
314  typedef RATIO_S(A, C) base;
315  typedef RATIO(A, C) type;
317  };
318  struct ratio2 {
319  typedef RATIO_S(B, C) base;
320  typedef RATIO(B, C) type;
322  };
324  typedef typename aux::type type;
325  COMBINE(SUM_S(A, B), C, aux::combine(_1, _2));
326  };
327 
328  TEMPL(T3) struct Ratio<SUM_S(A, B), C> :
329  public RatioSimpl<A, B, C> { };
330 
331  TEMPL(T4) struct Ratio<SUM_S(A, B), PROD_S(C, D)> :
332  public RatioSimpl<A, B, PROD_S(C, D)> { };
333 
334  TEMPL(N1T2) struct Ratio<SUM_S(A, B), NUM(n)> :
335  public RatioSimpl<A, B, NUM(n)> { };
336 
337 }
338 
340 
341 #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:100
#define MINUS(A)
PROD_S(A, B)>
Definition: Factorize.h:45
POWER_S(A, NUM(n))>
Definition: Factorize.h:49
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:187
#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:19
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:96
#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:93
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