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 
11 
12 namespace funct {
13 
14  // a * ( b * c ) = ( a * b ) * c
15  PROD_RULE(TYPT3, A, PROD_S(B, C),
16  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
72  RATIO(PROD(NUM(n), A), B), (_1 * _2._1)/_2._2);
73 
74  // 1 * ( a / b ) = a / b
75  PROD_RULE(TYPT2, NUM(1), RATIO_S(A, B), RATIO(A, B), _2);
76 
77  // 0 * ( a / b ) = 0
78  PROD_RULE(TYPT2, NUM(0), RATIO_S(A, B), NUM(0), num<0>());
79 
80  // a * n = n * a
81  PROD_RULE(TYPN1T1, A, NUM(n), PROD(NUM(n), A), _2 * _1);
82 
83  // ( a * b ) n = ( n * a ) * b
84  PROD_RULE(TYPN1T2, PROD_S(A, B), NUM(n), PROD(PROD(NUM(n), A), B),
85  (_2 * _1._1) * _1._2);
86 
87  // ( a * b ) * ( c * d ) => ( ( a * b ) * c ) * d
88  PROD_RULE(TYPT4, PROD_S(A, B), PROD_S(C, D),
89  PROD(PROD(PROD(A, B), C), D),
90  (_1 * _2._1) * _2._2);
91 
92  // n/m * ( a / k ) = n/(m+k) * a
94  PROD(FRACT(n, m + k), A), (fract<n, m + k>() * _2._1));
95 
96  // ( a / b ) * n = ( n a ) / b
98  RATIO(PROD(NUM(n), A), B), (_2 * _1._1) / _1._2);
99 
100  // ( a / b ) * c = ( a * c ) / b
101  PROD_RULE(TYPT3, RATIO_S(A, B), C,
102  RATIO(PROD(A, C), B), (_1._1 * _2) / _1._2);
103 
104  // 0 * 1 = 0 ( avoid template ambiguity )
105  PROD_RULE(TYP0, NUM(0), NUM(1), NUM(0), num<0>());
106 
107  // ( a / b ) * ( c / d )= a * c / ( b * d )
109  RATIO(PROD(A, C), PROD(B, D)),
110  (_1._1 * _2._1)/(_1._2 * _2._2));
111 
112  // a^b * a^c => a^( b + c )
115  typedef POWER( A, B ) arg1;
116  typedef POWER( A, C ) arg2;
117  typedef PROD_S( arg1, arg2 ) type;
118  COMBINE( arg1, arg2, type( _1, _2 ) );
119  };
120 
121  TEMPL( T3 )
122  struct SimplifyPowerProduct< A, B, C, false > {
123  typedef POWER( A, B ) arg1;
124  typedef POWER( A, C ) arg2;
125  typedef POWER( A, SUM( B, C ) ) type;
126  inline static type combine( const arg1 & _1, const arg2 & _2 )
127  { return pow( DecomposePower< A, B >::getBase( _1 ),
129  DecomposePower< A, C >::getExp( _2 ) ) ); }
130  };
131 
132  TEMPL( T3 ) struct Product< POWER_S( A, B ),POWER_S( A, C ) > :
133  public SimplifyPowerProduct< A, B, C > { };
134 
135  TEMPL( T2 ) struct Product< POWER_S( A, B ),POWER_S( A, B ) > :
136  public SimplifyPowerProduct< A, B, B > { };
137 
138  TEMPL( T2 ) struct Product< A, POWER_S( A, B ) > :
139  public SimplifyPowerProduct< A, NUM( 1 ), B > { };
140 
141  TEMPL( N1T1 ) struct Product< A, POWER_S( A, NUM( n ) ) > :
142  public SimplifyPowerProduct< A, NUM( 1 ), NUM( n ) > { };
143 
144  TEMPL( T2 ) struct Product< POWER_S( A, B ), A > :
145  public SimplifyPowerProduct< A, B, NUM( 1 ) > { };
146 
147  TEMPL( N1T1 ) struct Product< POWER_S( A, NUM( n ) ), A > :
148  public SimplifyPowerProduct< A, NUM( n ), NUM( 1 ) > { };
149 
150  TEMPL( T1 ) struct Product< A, A > :
151  public SimplifyPowerProduct< A, NUM( 1 ), NUM( 1 ) > { };
152 
153  TEMPL( T2 ) struct Product< PROD_S( A, B ), PROD_S( A, B ) > :
154  public SimplifyPowerProduct< PROD( A, B ), NUM( 1 ), NUM( 1 ) > { };
155 
156  TEMPL( T1 ) struct Product< MINUS_S( A ), MINUS_S( A ) > :
157  public SimplifyPowerProduct< MINUS_S( A ), NUM( 1 ), NUM( 1 ) > { };
158 
159 
160  // n * n = n ^ 2
161  PROD_RULE(TYPN1, NUM(n), NUM(n), NUM(n*n), num<n*n>());
162 
163  // a/ b * ( c * d ) = ( a * c * d ) / b
164  PROD_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D),
165  RATIO(PROD(PROD(A, C), D), B),
166  ((_1._1 * _2._1) * _2._2) / _1._2);
167 
168  // simplify f * g * h regardless of the order
169  template <typename Prod, bool simplify = Prod::value> struct AuxProduct {
170  typedef PROD(typename Prod::AB, typename Prod::C) type;
171  COMBINE(typename Prod::AB, typename Prod::C, _1 * _2);
172  };
173 
174  template<typename Prod> struct AuxProduct<Prod, false> {
175  typedef PROD_S(typename Prod::AB, typename Prod::C) type;
176  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
177  };
178 
179  template<typename F, typename G, typename H>
180  struct Product<PROD_S(F, G), H> {
181  struct prod0 {
182  typedef F A; typedef G B; typedef H C;
183  typedef PROD_S(A, B) AB;
184  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
185  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
186  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
187  enum { value = false };
188  };
189  struct prod1 {
190  typedef F A; typedef H B; typedef G C;
191  typedef PROD_S(A, B) base;
192  typedef PROD(A, B) AB;
193  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
194  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
195  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
197  };
198  struct prod2 {
199  typedef G A; typedef H B; typedef F C;
200  typedef PROD_S(A, B) base;
201  typedef PROD(A, B) AB;
202  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
203  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
204  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
206  };
207 
208  typedef typename
209  ::boost::mpl::if_ <prod1, prod1,
212  typedef typename AuxProduct<prod>::type type;
213  inline static type combine(const ProductStruct<F, G>& fg, const H& h) {
214  const F& f = fg._1;
215  const G& g = fg._2;
216  const typename prod::A & a = prod::a(f, g, h);
217  const typename prod::B & b = prod::b(f, g, h);
218  const typename prod::C & c = prod::c(f, g, h);
219  return AuxProduct<prod>::combine(a * b, c);
220  }
221  };
222 
223 }
224 
226 
227 #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:100
#define MINUS(A)
PROD_S(A, B)>
Definition: Factorize.h:45
POWER_S(A, NUM(n))>
Definition: Factorize.h:49
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
static const std::string B
#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:19
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:93
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