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
funct::Product< ProductStruct< F, G >, H >::prod0::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:167
funct::DecomposeProduct
Definition: DecomposeProduct.h:8
funct::AuxProduct
Definition: SimplifyProduct.h:148
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:114
funct::SimplifyPowerProduct::arg1
Power< A, B >::type arg1
Definition: SimplifyProduct.h:105
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:29
funct::Product< ProductStruct< F, G >, H >::combine
static type combine(const ProductStruct< F, G > &fg, const H &h)
Definition: SimplifyProduct.h:198
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
funct::Product< ProductStruct< F, G >, H >::prod0::AB
ProductStruct< A, B > AB
Definition: SimplifyProduct.h:165
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:24
DecomposePower.h
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:174
funct::ProductStruct
Definition: Product.h:6
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:168
funct::Product< ProductStruct< F, G >, H >::prod2::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:189
funct::Product< ProductStruct< F, G >, H >::prod2::B
H B
Definition: SimplifyProduct.h:184
h
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
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:177
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:175
funct::Product< ProductStruct< F, G >, H >::prod2::A
G A
Definition: SimplifyProduct.h:183
funct::SimplifyPowerProduct::arg2
Power< A, C >::type arg2
Definition: SimplifyProduct.h:106
funct::Product< ProductStruct< F, G >, H >::prod1::AB
Product< A, B >::type AB
Definition: SimplifyProduct.h:176
funct::AuxProduct< Prod, false >::type
ProductStruct< typename Prod::AB, typename Prod::C > type
Definition: SimplifyProduct.h:155
funct::SimplifyPowerProduct< A, B, C, false >::arg1
Power< A, B >::type arg1
Definition: SimplifyProduct.h:113
funct::PowerStruct
Definition: Power.h:7
funct::ProductStruct::_2
B _2
Definition: Product.h:13
funct::SimplifyPowerProduct< A, B, C, false >::combine
static type combine(const arg1 &_1, const arg2 &_2)
Definition: SimplifyProduct.h:116
TYPN1
#define TYPN1
Definition: Simplify_begin.h:11
funct::Product< ProductStruct< F, G >, H >::prod2::base
ProductStruct< A, B > base
Definition: SimplifyProduct.h:186
funct::m
m
Definition: Factorize.h:45
h
dqmdumpme.k
k
Definition: dqmdumpme.py:60
funct::Product< ProductStruct< F, G >, H >::prod0::A
F A
Definition: SimplifyProduct.h:162
funct::Product< ProductStruct< F, G >, H >::prod2::c
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:190
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:166
ParametricTrait.h
a
double a
Definition: hdecay.h:119
gainCalibHelper::gainCalibPI::type
type
Definition: SiPixelGainCalibHelper.h:40
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:15
funct::AuxProduct::combine
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
Definition: SimplifyProduct.h:150
funct::Product< ProductStruct< F, G >, H >::prod
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
Definition: SimplifyProduct.h:196
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:197
funct::Product< ProductStruct< F, G >, H >::prod2::AB
Product< A, B >::type AB
Definition: SimplifyProduct.h:187
funct::SimplifyPowerProduct< A, B, C, false >::type
Power< A, typename Sum< B, C >::type >::type type
Definition: SimplifyProduct.h:115
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
gen::C
C
Definition: PomwigHadronizer.cc:78
funct::Product< ProductStruct< F, G >, H >::prod2::C
F C
Definition: SimplifyProduct.h:185
funct::Product< ProductStruct< F, G >, H >::prod2::a
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:188
relativeConstraints.value
value
Definition: relativeConstraints.py:53
funct::NUM
PROD_S(A, B)> NUM(n))
Definition: Factorize.h:87
funct::Product
Definition: Product.h:17
funct::Product< ProductStruct< F, G >, H >::prod1::B
H B
Definition: SimplifyProduct.h:173
COMBINE
#define COMBINE(A, B, RES)
Definition: Simplify_begin.h:70
TYPT3
#define TYPT3
Definition: Simplify_begin.h:8
data-class-funcs.H
H
Definition: data-class-funcs.py:33
funct::AuxProduct::type
Product< typename Prod::AB, typename Prod::C >::type type
Definition: SimplifyProduct.h:149
funct::Product< ProductStruct< F, G >, H >::prod1::c
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:179
funct::Product< ProductStruct< F, G >, H >::prod1::A
F A
Definition: SimplifyProduct.h:172
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
funct::Product< ProductStruct< F, G >, H >::prod0::C
H C
Definition: SimplifyProduct.h:164
Simplify_begin.h
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:56
funct::PROD
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
funct::ProductStruct::_1
A _1
Definition: Product.h:12
funct::SimplifyPowerProduct::type
ProductStruct< arg1, arg2 > type
Definition: SimplifyProduct.h:107
cmssw_cycle_finder.G
G
Definition: cmssw_cycle_finder.py:154
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:163
funct::SimplifyPowerProduct
Definition: SimplifyProduct.h:104
funct::Product< ProductStruct< F, G >, H >::prod1::b
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifyProduct.h:178