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