CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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; }
188  enum { value = ::boost::type_traits::ice_not<
190  };
191  struct prod2 {
192  typedef G A; typedef H B; typedef F C;
193  typedef RATIO_S(A, B) base;
194  typedef RATIO(A, B) AB;
195  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
196  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
197  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
198  enum { value = ::boost::type_traits::ice_not<
200  };
201 
202  typedef typename
203  ::boost::mpl::if_<prod1,
204  prod1,
205  typename ::boost::mpl::if_<prod2,
206  prod2,
207  prod0
208  >::type
211  inline static type combine(const PROD_S(F, G)& fg, const H& h) {
212  const F& f = fg._1;
213  const G& g = fg._2;
214  const typename prod::A & a = prod::a(f, g, h);
215  const typename prod::B & b = prod::b(f, g, h);
216  const typename prod::C & c = prod::c(f, g, h);
217  return AuxProductRatio<prod>::combine(a, b, c);
218  }
219  };
220 
221  // simplify c / ( a * b )
222  // try ( c / a ) / b and ( c / b ) / a, otherwise leave c / ( a * b )
223 
224  template <typename Prod, bool simplify = Prod::value>
226  typedef RATIO(typename Prod::AB, typename Prod::C) type;
227  inline static type combine(const typename Prod::A& a,
228  const typename Prod::B& b,
229  const typename Prod::C& c) { return (b / a) / c; }
230  };
231 
232  template<typename Prod>
233  struct AuxProductRatio2<Prod, false> {
234  typedef RATIO_S(typename Prod::C, typename Prod::AB) type;
235  inline static type combine(const typename Prod::A& a,
236  const typename Prod::B& b,
237  const typename Prod::C& c) { return type(c, a * b); }
238  };
239 
240  template<typename F, typename G, typename H>
241  struct RatioP2 {
242  struct prod0 {
243  typedef F A; typedef G B; typedef H C;
244  typedef PROD_S(A, B) AB;
245  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
246  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
247  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
248  enum { value = false };
249  };
250  struct prod1 {
251  typedef F A; typedef H B; typedef G C;
252  typedef RATIO_S(B, A) base;
253  typedef RATIO(B, A) AB;
254  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
255  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
256  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
257  enum { value = ::boost::type_traits::ice_not<
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; }
267  enum { value = ::boost::type_traits::ice_not<
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;
317  enum { value = ::boost::type_traits::ice_not<
319  };
320  struct ratio2 {
321  typedef RATIO_S(B, C) base;
322  typedef RATIO(B, C) type;
323  enum { value = ::boost::type_traits::ice_not<
325  };
326  typedef AuxSumRatio<A, B, C,
328  typedef typename aux::type type;
329  COMBINE(SUM_S(A, B), C, aux::combine(_1, _2));
330  };
331 
332  TEMPL(T3) struct Ratio<SUM_S(A, B), C> :
333  public RatioSimpl<A, B, C> { };
334 
335  TEMPL(T4) struct Ratio<SUM_S(A, B), PROD_S(C, D)> :
336  public RatioSimpl<A, B, PROD_S(C, D)> { };
337 
338  TEMPL(N1T2) struct Ratio<SUM_S(A, B), NUM(n)> :
339  public RatioSimpl<A, B, NUM(n)> { };
340 
341 }
342 
344 
345 #endif
static const bool value
Definition: Factorize.h:107
#define TYPN1
const Numerical< n > & num()
Definition: Numerical.h:16
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)
#define TYPT2
Definition: Simplify_begin.h:7
static type combine(const typename Sum< A, B >::type &_1, const typename Sum< B, A >::type &_2)
Definition: SimplifyRatio.h:94
MINUS_S(B)>
Definition: Factorize.h:99
#define MINUS(A)
double_binary B
Definition: DDStreamer.cc:234
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)
AuxSumRatio< A, B, C,::boost::type_traits::ice_or< ratio1::value, ratio2::value >::value > aux
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]
#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)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#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
string const
Definition: compareJSON.py:14
static const B & b(const F &f, const G &g, const H &h)
AuxProductRatio2< prod >::type type
arg type
Definition: Factorize.h:37
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