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