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 
10 
11 namespace funct {
12 
13  // a * ( b * c ) = ( a * b ) * c
14  PROD_RULE(TYPT3, A, PROD_S(B, C),
15  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
71  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),
84  (_2 * _1._1) * _1._2);
85 
86  // ( a * b ) * ( c * d ) => ( ( a * b ) * c ) * d
87  PROD_RULE(TYPT4, PROD_S(A, B), PROD_S(C, D),
88  PROD(PROD(PROD(A, B), C), D),
89  (_1 * _2._1) * _2._2);
90 
91  // n/m * ( a / k ) = n/(m+k) * a
93  PROD(FRACT(n, m + k), A), (fract<n, m + k>() * _2._1));
94 
95  // ( a / b ) * n = ( n a ) / b
97  RATIO(PROD(NUM(n), A), B), (_2 * _1._1) / _1._2);
98 
99  // ( a / b ) * c = ( a * c ) / b
100  PROD_RULE(TYPT3, RATIO_S(A, B), C,
101  RATIO(PROD(A, C), B), (_1._1 * _2) / _1._2);
102 
103  // 0 * 1 = 0 ( avoid template ambiguity )
104  PROD_RULE(TYP0, NUM(0), NUM(1), NUM(0), num<0>());
105 
106  // ( a / b ) * ( c / d )= a * c / ( b * d )
108  RATIO(PROD(A, C), PROD(B, D)),
109  (_1._1 * _2._1)/(_1._2 * _2._2));
110 
111  // a^b * a^c => a^( b + c )
114  typedef POWER( A, B ) arg1;
115  typedef POWER( A, C ) arg2;
116  typedef PROD_S( arg1, arg2 ) type;
117  COMBINE( arg1, arg2, type( _1, _2 ) );
118  };
119 
120  TEMPL( T3 )
121  struct SimplifyPowerProduct< A, B, C, false > {
122  typedef POWER( A, B ) arg1;
123  typedef POWER( A, C ) arg2;
124  typedef POWER( A, SUM( B, C ) ) type;
125  inline static type combine( const arg1 & _1, const arg2 & _2 )
126  { return pow( DecomposePower< A, B >::getBase( _1 ),
128  DecomposePower< A, C >::getExp( _2 ) ) ); }
129  };
130 
131  TEMPL( T3 ) struct Product< POWER_S( A, B ),POWER_S( A, C ) > :
132  public SimplifyPowerProduct< A, B, C > { };
133 
134  TEMPL( T2 ) struct Product< POWER_S( A, B ),POWER_S( A, B ) > :
135  public SimplifyPowerProduct< A, B, B > { };
136 
137  TEMPL( T2 ) struct Product< A, POWER_S( A, B ) > :
138  public SimplifyPowerProduct< A, NUM( 1 ), B > { };
139 
140  TEMPL( N1T1 ) struct Product< A, POWER_S( A, NUM( n ) ) > :
141  public SimplifyPowerProduct< A, NUM( 1 ), NUM( n ) > { };
142 
143  TEMPL( T2 ) struct Product< POWER_S( A, B ), A > :
144  public SimplifyPowerProduct< A, B, NUM( 1 ) > { };
145 
146  TEMPL( N1T1 ) struct Product< POWER_S( A, NUM( n ) ), A > :
147  public SimplifyPowerProduct< A, NUM( n ), NUM( 1 ) > { };
148 
149  TEMPL( T1 ) struct Product< A, A > :
150  public SimplifyPowerProduct< A, NUM( 1 ), NUM( 1 ) > { };
151 
152  TEMPL( T2 ) struct Product< PROD_S( A, B ), PROD_S( A, B ) > :
153  public SimplifyPowerProduct< PROD( A, B ), NUM( 1 ), NUM( 1 ) > { };
154 
155  TEMPL( T1 ) struct Product< MINUS_S( A ), MINUS_S( A ) > :
156  public SimplifyPowerProduct< MINUS_S( A ), NUM( 1 ), NUM( 1 ) > { };
157 
158 
159  // n * n = n ^ 2
160  PROD_RULE(TYPN1, NUM(n), NUM(n), NUM(n*n), num<n*n>());
161 
162  // a/ b * ( c * d ) = ( a * c * d ) / b
163  PROD_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D),
164  RATIO(PROD(PROD(A, C), D), B),
165  ((_1._1 * _2._1) * _2._2) / _1._2);
166 
167  // simplify f * g * h regardless of the order
168  template <typename Prod, bool simplify = Prod::value> struct AuxProduct {
169  typedef PROD(typename Prod::AB, typename Prod::C) type;
170  COMBINE(typename Prod::AB, typename Prod::C, _1 * _2);
171  };
172 
173  template<typename Prod> struct AuxProduct<Prod, false> {
174  typedef PROD_S(typename Prod::AB, typename Prod::C) type;
175  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
176  };
177 
178  template<typename F, typename G, typename H>
179  struct Product<PROD_S(F, G), H> {
180  struct prod0 {
181  typedef F A; typedef G B; typedef H C;
182  typedef PROD_S(A, B) AB;
183  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
184  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
185  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
186  enum { value = false };
187  };
188  struct prod1 {
189  typedef F A; typedef H B; typedef G C;
190  typedef PROD_S(A, B) base;
191  typedef PROD(A, B) AB;
192  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
193  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
194  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
196  };
197  struct prod2 {
198  typedef G A; typedef H B; typedef F C;
199  typedef PROD_S(A, B) base;
200  typedef PROD(A, B) AB;
201  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
202  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
203  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
205  };
206 
207  typedef typename
208  ::boost::mpl::if_ <prod1, prod1,
211  typedef typename AuxProduct<prod>::type type;
212  inline static type combine(const ProductStruct<F, G>& fg, const H& h) {
213  const F& f = fg._1;
214  const G& g = fg._2;
215  const typename prod::A & a = prod::a(f, g, h);
216  const typename prod::B & b = prod::b(f, g, h);
217  const typename prod::C & c = prod::c(f, g, h);
218  return AuxProduct<prod>::combine(a * b, c);
219  }
220  };
221 
222 }
223 
225 
226 #endif
#define TYPN1
type
Definition: HCALResponse.h:21
#define TYPN2
typedef POWER(A, NUM(n)) arg
Definition: Abs.h:5
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
#define TYPT2
Definition: Simplify_begin.h:7
MINUS_S(B)>
Definition: Factorize.h:99
#define MINUS(A)
double_binary B
Definition: DDStreamer.cc:248
PROD_S(A, B)>
Definition: Factorize.h:44
POWER_S(A, NUM(n))>
Definition: Factorize.h:48
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)
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:520
Definition: value.py:1
#define TYPT4
Definition: Simplify_begin.h:9
#define PROD_RULE(TMPL, T1, T2, RES, COMB)
int k[5][pyjets_maxn]
::boost::mpl::if_< prod1, prod1, typename::boost::mpl::if_< prod2, prod2, prod0 >::type >::type prod
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:18
double b
Definition: hdecay.h:120
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
double a
Definition: hdecay.h:121
#define TYPT3
Definition: Simplify_begin.h:8
#define COMBINE(A, B, RES)
NUM(n))
Definition: Factorize.h:92
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
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:40
#define TYPT1
Definition: Simplify_begin.h:6