CMS 3D CMS Logo

SimplifyProduct.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_SimplifyProduct_h
2 #define PhysicsTools_Utilities_SimplifyProduct_h
3 
8 #include <type_traits>
9 
11 
12 namespace funct {
13 
14  // a * ( b * c ) = ( a * b ) * c
15  PROD_RULE(TYPT3, A, PROD_S(B, C), PROD(PROD(A, B), C), (_1 * _2._1) * _2._2);
16 
17  // 0 * a = 0
18  PROD_RULE(TYPT1, NUM(0), A, NUM(0), num<0>());
19 
20  // 0 * n = 0
21  PROD_RULE(TYPN1, NUM(0), NUM(n), NUM(0), num<0>());
22 
23  // 0 * ( a * b ) => 0
24  PROD_RULE(TYPT2, NUM(0), PROD_S(A, B), NUM(0), num<0>());
25 
26  // 1 * a = a
27  PROD_RULE(TYPT1, NUM(1), A, A, _2);
28 
29  // avoid template ambiguities
30  // 1 * n = n
31  PROD_RULE(TYPN1, NUM(1), NUM(n), NUM(n), _2);
32 
33  // 1 * (n/m) = (n/m)
34  PROD_RULE(TYPN2, NUM(1), FRACT_S(n, m), FRACT_S(n, m), _2);
35 
36  // 1 * 1 = 1
37  PROD_RULE(TYP0, NUM(1), NUM(1), NUM(1), num<1>());
38 
39  // ( - 1 ) * a = - a
40  PROD_RULE(TYPT1, NUM(-1), A, MINUS_S(A), -_2);
41 
42  // ( - 1 ) * n = -n
43  PROD_RULE(TYPN1, NUM(-1), NUM(n), NUM(-n), num<-n>());
44 
45  // 1 * ( a * b ) => ( a * b )
46  PROD_RULE(TYPT2, NUM(1), PROD_S(A, B), PROD_S(A, B), _2);
47 
48  // a * ( -b ) = - ( a * b )
49  PROD_RULE(TYPT2, A, MINUS_S(B), MINUS(PROD(A, B)), -(_1* _2._));
50 
51  // n * ( -a ) = - ( n * a )
52  PROD_RULE(TYPN1T1, NUM(n), MINUS_S(A), MINUS(PROD(NUM(n), A)), -(_1* _2._));
53 
54  // ( a * b ) * ( -c )= - ( ( a * b ) * c )
55  PROD_RULE(TYPT3, PROD_S(A, B), MINUS_S(C), MINUS(PROD(PROD(A, B), C)), -(_1* _2._));
56 
57  // 1 * ( -a ) = -a
58  PROD_RULE(TYPT1, NUM(1), MINUS_S(A), MINUS(A), _2);
59 
60  // ( - a ) * ( - b ) = a * b
61  PROD_RULE(TYPT2, MINUS_S(A), MINUS_S(B), PROD(A, B), _1._* _2._);
62 
63  // ( -a ) * b = -( a * b )
64  PROD_RULE(TYPT2, MINUS_S(A), B, MINUS(PROD(A, B)), -(_1._* _2));
65 
66  // a * ( b / c ) = ( a * b ) / c
67  PROD_RULE(TYPT3, A, RATIO_S(B, C), RATIO(PROD(A, B), C), (_1 * _2._1) / _2._2);
68 
69  // n * ( a / b ) = ( n * a ) / b
70  PROD_RULE(TYPN1T2, NUM(n), RATIO_S(A, B), RATIO(PROD(NUM(n), A), B), (_1 * _2._1) / _2._2);
71 
72  // 1 * ( a / b ) = a / b
73  PROD_RULE(TYPT2, NUM(1), RATIO_S(A, B), RATIO(A, B), _2);
74 
75  // 0 * ( a / b ) = 0
76  PROD_RULE(TYPT2, NUM(0), RATIO_S(A, B), NUM(0), num<0>());
77 
78  // a * n = n * a
79  PROD_RULE(TYPN1T1, A, NUM(n), PROD(NUM(n), A), _2* _1);
80 
81  // ( a * b ) n = ( n * a ) * b
82  PROD_RULE(TYPN1T2, PROD_S(A, B), NUM(n), PROD(PROD(NUM(n), A), B), (_2 * _1._1) * _1._2);
83 
84  // ( a * b ) * ( c * d ) => ( ( a * b ) * c ) * d
85  PROD_RULE(TYPT4, PROD_S(A, B), PROD_S(C, D), PROD(PROD(PROD(A, B), C), D), (_1 * _2._1) * _2._2);
86 
87  // n/m * ( a / k ) = n/(m+k) * a
88  PROD_RULE(TYPN3T1, FRACT_S(n, m), RATIO_S(A, NUM(k)), PROD(FRACT(n, m + k), A), (fract<n, m + k>() * _2._1));
89 
90  // ( a / b ) * n = ( n a ) / b
91  PROD_RULE(TYPN1T2, RATIO_S(A, B), NUM(n), RATIO(PROD(NUM(n), A), B), (_2 * _1._1) / _1._2);
92 
93  // ( a / b ) * c = ( a * c ) / b
94  PROD_RULE(TYPT3, RATIO_S(A, B), C, RATIO(PROD(A, C), B), (_1._1 * _2) / _1._2);
95 
96  // 0 * 1 = 0 ( avoid template ambiguity )
97  PROD_RULE(TYP0, NUM(0), NUM(1), NUM(0), num<0>());
98 
99  // ( a / b ) * ( c / d )= a * c / ( b * d )
100  PROD_RULE(TYPT4, RATIO_S(A, B), RATIO_S(C, D), RATIO(PROD(A, C), PROD(B, D)), (_1._1 * _2._1) / (_1._2 * _2._2));
101 
102  // a^b * a^c => a^( b + c )
105  typedef POWER(A, B) arg1;
106  typedef POWER(A, C) arg2;
107  typedef PROD_S(arg1, arg2) type;
108  COMBINE(arg1, arg2, type(_1, _2));
109  };
110 
111  TEMPL(T3)
113  typedef POWER(A, B) arg1;
114  typedef POWER(A, C) arg2;
115  typedef POWER(A, SUM(B, C)) type;
116  inline static type combine(const arg1& _1, const arg2& _2) {
119  }
120  };
121 
122  TEMPL(T3) struct Product<POWER_S(A, B), POWER_S(A, C)> : public SimplifyPowerProduct<A, B, C> {};
123 
124  TEMPL(T2) struct Product<POWER_S(A, B), POWER_S(A, B)> : public SimplifyPowerProduct<A, B, B> {};
125 
126  TEMPL(T2) struct Product<A, POWER_S(A, B)> : public SimplifyPowerProduct<A, NUM(1), B> {};
127 
128  TEMPL(N1T1) struct Product<A, POWER_S(A, NUM(n))> : public SimplifyPowerProduct<A, NUM(1), NUM(n)> {};
129 
130  TEMPL(T2) struct Product<POWER_S(A, B), A> : public SimplifyPowerProduct<A, B, NUM(1)> {};
131 
132  TEMPL(N1T1) struct Product<POWER_S(A, NUM(n)), A> : public SimplifyPowerProduct<A, NUM(n), NUM(1)> {};
133 
134  TEMPL(T1) struct Product<A, A> : public SimplifyPowerProduct<A, NUM(1), NUM(1)> {};
135 
136  TEMPL(T2) struct Product<PROD_S(A, B), PROD_S(A, B)> : public SimplifyPowerProduct<PROD(A, B), NUM(1), NUM(1)> {};
137 
138  TEMPL(T1) struct Product<MINUS_S(A), MINUS_S(A)> : public SimplifyPowerProduct<MINUS_S(A), NUM(1), NUM(1)> {};
139 
140  // n * n = n ^ 2
141  PROD_RULE(TYPN1, NUM(n), NUM(n), NUM(n* n), num<n * n>());
142 
143  // a/ b * ( c * d ) = ( a * c * d ) / b
144  PROD_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D), RATIO(PROD(PROD(A, C), D), B), ((_1._1 * _2._1) * _2._2) / _1._2);
145 
146  // simplify f * g * h regardless of the order
147  template <typename Prod, bool simplify = Prod::value>
148  struct AuxProduct {
149  typedef PROD(typename Prod::AB, typename Prod::C) type;
150  COMBINE(typename Prod::AB, typename Prod::C, _1* _2);
151  };
152 
153  template <typename Prod>
154  struct AuxProduct<Prod, false> {
155  typedef PROD_S(typename Prod::AB, typename Prod::C) type;
156  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
157  };
158 
159  template <typename F, typename G, typename H>
160  struct Product<PROD_S(F, G), H> {
161  struct prod0 {
162  typedef F A;
163  typedef G B;
164  typedef H C;
165  typedef PROD_S(A, B) AB;
166  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
167  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
168  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
169  enum { value = false };
170  };
171  struct prod1 {
172  typedef F A;
173  typedef H B;
174  typedef G C;
175  typedef PROD_S(A, B) base;
176  typedef PROD(A, B) AB;
177  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
178  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
179  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
181  };
182  struct prod2 {
183  typedef G A;
184  typedef H B;
185  typedef F C;
186  typedef PROD_S(A, B) base;
187  typedef PROD(A, B) AB;
188  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
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 f; }
192  };
193 
194  typedef
197  typedef typename AuxProduct<prod>::type type;
198  inline static type combine(const ProductStruct<F, G>& fg, const H& h) {
199  const F& f = fg._1;
200  const G& g = fg._2;
201  const typename prod::A& a = prod::a(f, g, h);
202  const typename prod::B& b = prod::b(f, g, h);
203  const typename prod::C& c = prod::c(f, g, h);
204  return AuxProduct<prod>::combine(a * b, c);
205  }
206  };
207 
208 } // namespace funct
209 
211 
212 #endif
#define TYPN1
ProductStruct< typename Prod::AB, typename Prod::C > type
#define TYPN2
ProductStruct< arg1, arg2 > type
static const A & a(const F &f, const G &g, const H &h)
typedef POWER(A, NUM(n)) arg
Definition: APVGainStruct.h:7
Definition: Abs.h:5
#define TYPT2
Definition: Simplify_begin.h:7
#define MINUS(A)
PROD_S(B, C)>
Definition: Factorize.h:114
typedef MINUS_S(A) arg
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
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 type combine(const arg1 &_1, const arg2 &_2)
#define RATIO_S(A, B)
static type combine(const ProductStruct< F, G > &fg, const H &h)
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
#define TYPN1T1
#define FRACT(N, M)
Power< A, B >::type arg1
#define FRACT_S(N, M)
static const C & c(const F &f, const G &g, const H &h)
#define RATIO(A, B)
#define TYP0
Definition: Simplify_begin.h:4
#define TYPN1T2
#define TYPN3T1
double f[11][100]
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
Product< typename Prod::AB, typename Prod::C >::type type
Definition: value.py:1
#define TYPT4
Definition: Simplify_begin.h:9
#define PROD_RULE(TMPL, T1, T2, RES, COMB)
static const B & b(const F &f, const G &g, const H &h)
#define SUM(A, B)
static const C & c(const F &f, const G &g, const H &h)
TEMPL(T1) struct Divides0
Definition: Factorize.h:15
double b
Definition: hdecay.h:120
Power< A, typename Sum< B, C >::type >::type type
arg type
Definition: Factorize.h:32
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
double a
Definition: hdecay.h:121
Power< A, C >::type arg2
#define TYPT3
Definition: Simplify_begin.h:8
#define COMBINE(A, B, RES)
Definition: APVGainStruct.h:7
static const A & a(const F &f, const G &g, const H &h)
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 B & b(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)