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)
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
funct::Product< ProductStruct< F, G >, H >::prod0::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:168
class-composition.H
H
Definition: class-composition.py:31
funct::DecomposeProduct
Definition: DecomposeProduct.h:8
funct::AuxProduct
Definition: SimplifyProduct.h:149
SUM
#define SUM(A, B)
Definition: Simplify_begin.h:52
funct::SimplifyPowerProduct< A, B, C, false >::arg2
Power< A, C >::type arg2
Definition: SimplifyProduct.h:115
funct::SimplifyPowerProduct::arg1
Power< A, B >::type arg1
Definition: SimplifyProduct.h:106
Product.h
TYPN1T1
#define TYPN1T1
Definition: Simplify_begin.h:16
POWER_S
#define POWER_S(A, B)
Definition: Simplify_begin.h:41
TYP0
#define TYP0
Definition: Simplify_begin.h:4
funct::false
false
Definition: Factorize.h:34
funct::Product< ProductStruct< F, G >, H >::combine
static type combine(const ProductStruct< F, G > &fg, const H &h)
Definition: SimplifyProduct.h:197
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
funct::Product< ProductStruct< F, G >, H >::prod0::AB
ProductStruct< A, B > AB
Definition: SimplifyProduct.h:166
Fraction.h
FRACT_S
#define FRACT_S(N, M)
Definition: Simplify_begin.h:42
funct::PROD_S
PROD_S(B, C)>
Definition: Factorize.h:114
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
funct::B
TEMPL(T2) struct Divides B
Definition: Factorize.h:29
DecomposePower.h
h
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
Definition: L1TUtmAlgorithmRcd.h:4
RATIO_S
#define RATIO_S(A, B)
Definition: Simplify_begin.h:40
TYPT4
#define TYPT4
Definition: Simplify_begin.h:9
funct::Product< ProductStruct< F, G >, H >::prod1::C
G C
Definition: SimplifyProduct.h:175
callgraph.G
G
Definition: callgraph.py:13
funct::ProductStruct
Definition: Product.h:7
funct::C
C
Definition: Factorize.h:133
funct::Product< ProductStruct< F, G >, H >::prod0::c
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:169
funct::Product< ProductStruct< F, G >, H >::prod2::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:190
funct::Product< ProductStruct< F, G >, H >::prod2::B
H B
Definition: SimplifyProduct.h:185
TYPT1
#define TYPT1
Definition: Simplify_begin.h:6
funct::Product< ProductStruct< F, G >, H >::prod1::a
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:178
funct::POWER
typedef POWER(A, NUM(n)) arg
MINUS
#define MINUS(A)
Definition: Simplify_begin.h:54
F
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
TYPN3T1
#define TYPN3T1
Definition: Simplify_begin.h:20
TYPT2
#define TYPT2
Definition: Simplify_begin.h:7
RATIO
#define RATIO(A, B)
Definition: Simplify_begin.h:56
funct::Product< ProductStruct< F, G >, H >::prod1::base
ProductStruct< A, B > base
Definition: SimplifyProduct.h:176
funct::Product< ProductStruct< F, G >, H >::prod2::A
G A
Definition: SimplifyProduct.h:184
funct::SimplifyPowerProduct::arg2
Power< A, C >::type arg2
Definition: SimplifyProduct.h:107
funct::Product< ProductStruct< F, G >, H >::prod1::AB
Product< A, B >::type AB
Definition: SimplifyProduct.h:177
funct::AuxProduct< Prod, false >::type
ProductStruct< typename Prod::AB, typename Prod::C > type
Definition: SimplifyProduct.h:156
funct::SimplifyPowerProduct< A, B, C, false >::arg1
Power< A, B >::type arg1
Definition: SimplifyProduct.h:114
funct::PowerStruct
Definition: Power.h:8
funct::ProductStruct::_2
B _2
Definition: Product.h:14
funct::SimplifyPowerProduct< A, B, C, false >::combine
static type combine(const arg1 &_1, const arg2 &_2)
Definition: SimplifyProduct.h:117
TYPN1
#define TYPN1
Definition: Simplify_begin.h:11
funct::Product< ProductStruct< F, G >, H >::prod2::base
ProductStruct< A, B > base
Definition: SimplifyProduct.h:187
funct::m
m
Definition: Factorize.h:50
h
dqmdumpme.k
k
Definition: dqmdumpme.py:60
funct::Product< ProductStruct< F, G >, H >::prod0::A
F A
Definition: SimplifyProduct.h:163
funct::Product< ProductStruct< F, G >, H >::prod2::c
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:191
b
double b
Definition: hdecay.h:118
funct::Product< ProductStruct< F, G >, H >::prod0::a
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:167
funct::Product< ProductStruct< F, G >, H >::prod
::boost::mpl::if_< prod1, prod1, typename ::boost::mpl::if_< prod2, prod2, prod0 >::type >::type prod
Definition: SimplifyProduct.h:195
ParametricTrait.h
a
double a
Definition: hdecay.h:119
prod1Switch_cff.prod1
prod1
Definition: prod1Switch_cff.py:9
funct::MINUS_S
typedef MINUS_S(A) arg
TYPN2
#define TYPN2
Definition: Simplify_begin.h:12
A
PROD_RULE
#define PROD_RULE(TMPL, T1, T2, RES, COMB)
Definition: Simplify_begin.h:95
value
Definition: value.py:1
funct::TEMPL
TEMPL(T1) struct Divides0
Definition: Factorize.h:20
funct::AuxProduct::combine
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
Definition: SimplifyProduct.h:151
HltBtagPostValidation_cff.c
c
Definition: HltBtagPostValidation_cff.py:31
TYPN1T2
#define TYPN1T2
Definition: Simplify_begin.h:17
Simplify_end.h
funct::Product< ProductStruct< F, G >, H >::type
AuxProduct< prod >::type type
Definition: SimplifyProduct.h:196
funct::Product< ProductStruct< F, G >, H >::prod2::AB
Product< A, B >::type AB
Definition: SimplifyProduct.h:188
funct::SimplifyPowerProduct< A, B, C, false >::type
Power< A, typename Sum< B, C >::type >::type type
Definition: SimplifyProduct.h:116
TtFullHadDaughter::B
static const std::string B
Definition: TtFullHadronicEvent.h:9
funct::DecomposePower
Definition: DecomposePower.h:8
MaterialEffects_cfi.A
A
Definition: MaterialEffects_cfi.py:11
type
type
Definition: HCALResponse.h:21
gen::C
C
Definition: PomwigHadronizer.cc:76
funct::Product< ProductStruct< F, G >, H >::prod2::C
F C
Definition: SimplifyProduct.h:186
funct::Product< ProductStruct< F, G >, H >::prod2::a
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:189
relativeConstraints.value
value
Definition: relativeConstraints.py:53
funct::NUM
PROD_S(A, B)> NUM(n))
Definition: Factorize.h:87
funct::Product
Definition: Product.h:18
funct::Product< ProductStruct< F, G >, H >::prod1::B
H B
Definition: SimplifyProduct.h:174
COMBINE
#define COMBINE(A, B, RES)
Definition: Simplify_begin.h:70
TYPT3
#define TYPT3
Definition: Simplify_begin.h:8
funct::AuxProduct::type
Product< typename Prod::AB, typename Prod::C >::type type
Definition: SimplifyProduct.h:150
funct::Product< ProductStruct< F, G >, H >::prod1::c
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:180
funct::Product< ProductStruct< F, G >, H >::prod1::A
F A
Definition: SimplifyProduct.h:173
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30
funct::Product< ProductStruct< F, G >, H >::prod0::C
H C
Definition: SimplifyProduct.h:165
Simplify_begin.h
funct::PROD
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
funct::ProductStruct::_1
A _1
Definition: Product.h:13
funct::SimplifyPowerProduct::type
ProductStruct< arg1, arg2 > type
Definition: SimplifyProduct.h:108
funct
Definition: Abs.h:5
FRACT
#define FRACT(N, M)
Definition: Simplify_begin.h:36
g
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
funct::Product< ProductStruct< F, G >, H >::prod0::B
G B
Definition: SimplifyProduct.h:164
funct::SimplifyPowerProduct
Definition: SimplifyProduct.h:105
funct::Product< ProductStruct< F, G >, H >::prod1::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:179