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),
17  PROD(PROD(A, B), C), (_1 * _2._1) * _2._2);
18 
19  // 0 * a = 0
20  PROD_RULE(TYPT1, NUM(0), A, NUM(0), num<0>());
21 
22  // 0 * n = 0
23  PROD_RULE(TYPN1, NUM(0), NUM(n), NUM(0), num<0>());
24 
25  // 0 * ( a * b ) => 0
26  PROD_RULE(TYPT2, NUM(0), PROD_S(A, B), NUM(0), num<0>());
27 
28  // 1 * a = a
29  PROD_RULE(TYPT1, NUM(1), A, A, _2);
30 
31  // avoid template ambiguities
32  // 1 * n = n
33  PROD_RULE(TYPN1, NUM(1), NUM(n), NUM(n), _2);
34 
35  // 1 * (n/m) = (n/m)
36  PROD_RULE(TYPN2, NUM(1), FRACT_S(n, m), FRACT_S(n, m), _2);
37 
38  // 1 * 1 = 1
39  PROD_RULE(TYP0, NUM(1), NUM(1), NUM(1), num<1>());
40 
41  // ( - 1 ) * a = - a
42  PROD_RULE(TYPT1, NUM(-1), A, MINUS_S(A), -_2);
43 
44  // ( - 1 ) * n = -n
45  PROD_RULE(TYPN1, NUM(-1), NUM(n), NUM(-n), num<-n>());
46 
47  // 1 * ( a * b ) => ( a * b )
48  PROD_RULE(TYPT2, NUM(1), PROD_S(A, B), PROD_S(A, B), _2);
49 
50  // a * ( -b ) = - ( a * b )
51  PROD_RULE(TYPT2, A, MINUS_S(B), MINUS(PROD(A, B)), -(_1 * _2._));
52 
53  // n * ( -a ) = - ( n * a )
54  PROD_RULE(TYPN1T1, NUM(n), MINUS_S(A), MINUS(PROD(NUM(n), A)), -(_1 * _2._ ));
55 
56  // ( a * b ) * ( -c )= - ( ( a * b ) * c )
57  PROD_RULE(TYPT3, PROD_S(A, B), MINUS_S(C), MINUS(PROD(PROD(A, B), C)), -(_1 * _2._));
58 
59  // 1 * ( -a ) = -a
60  PROD_RULE(TYPT1, NUM(1), MINUS_S(A), MINUS(A), _2);
61 
62  // ( - a ) * ( - b ) = a * b
63  PROD_RULE(TYPT2, MINUS_S(A), MINUS_S(B), PROD(A, B), _1._ * _2._);
64 
65  // ( -a ) * b = -( a * b )
66  PROD_RULE(TYPT2, MINUS_S(A), B, MINUS(PROD(A, B)), -(_1._ * _2));
67 
68  // a * ( b / c ) = ( a * b ) / c
69  PROD_RULE(TYPT3, A, RATIO_S(B, C), RATIO(PROD(A, B), C), (_1 * _2._1)/_2._2);
70 
71  // n * ( a / b ) = ( n * a ) / b
73  RATIO(PROD(NUM(n), A), B), (_1 * _2._1)/_2._2);
74 
75  // 1 * ( a / b ) = a / b
76  PROD_RULE(TYPT2, NUM(1), RATIO_S(A, B), RATIO(A, B), _2);
77 
78  // 0 * ( a / b ) = 0
79  PROD_RULE(TYPT2, NUM(0), RATIO_S(A, B), NUM(0), num<0>());
80 
81  // a * n = n * a
82  PROD_RULE(TYPN1T1, A, NUM(n), PROD(NUM(n), A), _2 * _1);
83 
84  // ( a * b ) n = ( n * a ) * b
85  PROD_RULE(TYPN1T2, PROD_S(A, B), NUM(n), PROD(PROD(NUM(n), A), B),
86  (_2 * _1._1) * _1._2);
87 
88  // ( a * b ) * ( c * d ) => ( ( a * b ) * c ) * d
89  PROD_RULE(TYPT4, PROD_S(A, B), PROD_S(C, D),
90  PROD(PROD(PROD(A, B), C), D),
91  (_1 * _2._1) * _2._2);
92 
93  // n/m * ( a / k ) = n/(m+k) * a
95  PROD(FRACT(n, m + k), A), (fract<n, m + k>() * _2._1));
96 
97  // ( a / b ) * n = ( n a ) / b
99  RATIO(PROD(NUM(n), A), B), (_2 * _1._1) / _1._2);
100 
101  // ( a / b ) * c = ( a * c ) / b
102  PROD_RULE(TYPT3, RATIO_S(A, B), C,
103  RATIO(PROD(A, C), B), (_1._1 * _2) / _1._2);
104 
105  // 0 * 1 = 0 ( avoid template ambiguity )
106  PROD_RULE(TYP0, NUM(0), NUM(1), NUM(0), num<0>());
107 
108  // ( a / b ) * ( c / d )= a * c / ( b * d )
110  RATIO(PROD(A, C), PROD(B, D)),
111  (_1._1 * _2._1)/(_1._2 * _2._2));
112 
113  // a^b * a^c => a^( b + c )
116  typedef POWER( A, B ) arg1;
117  typedef POWER( A, C ) arg2;
118  typedef PROD_S( arg1, arg2 ) type;
119  COMBINE( arg1, arg2, type( _1, _2 ) );
120  };
121 
122  TEMPL( T3 )
123  struct SimplifyPowerProduct< A, B, C, false > {
124  typedef POWER( A, B ) arg1;
125  typedef POWER( A, C ) arg2;
126  typedef POWER( A, SUM( B, C ) ) type;
127  inline static type combine( const arg1 & _1, const arg2 & _2 )
128  { return pow( DecomposePower< A, B >::getBase( _1 ),
130  DecomposePower< A, C >::getExp( _2 ) ) ); }
131  };
132 
133  TEMPL( T3 ) struct Product< POWER_S( A, B ),POWER_S( A, C ) > :
134  public SimplifyPowerProduct< A, B, C > { };
135 
136  TEMPL( T2 ) struct Product< POWER_S( A, B ),POWER_S( A, B ) > :
137  public SimplifyPowerProduct< A, B, B > { };
138 
139  TEMPL( T2 ) struct Product< A, POWER_S( A, B ) > :
140  public SimplifyPowerProduct< A, NUM( 1 ), B > { };
141 
142  TEMPL( N1T1 ) struct Product< A, POWER_S( A, NUM( n ) ) > :
143  public SimplifyPowerProduct< A, NUM( 1 ), NUM( n ) > { };
144 
145  TEMPL( T2 ) struct Product< POWER_S( A, B ), A > :
146  public SimplifyPowerProduct< A, B, NUM( 1 ) > { };
147 
148  TEMPL( N1T1 ) struct Product< POWER_S( A, NUM( n ) ), A > :
149  public SimplifyPowerProduct< A, NUM( n ), NUM( 1 ) > { };
150 
151  TEMPL( T1 ) struct Product< A, A > :
152  public SimplifyPowerProduct< A, NUM( 1 ), NUM( 1 ) > { };
153 
154  TEMPL( T2 ) struct Product< PROD_S( A, B ), PROD_S( A, B ) > :
155  public SimplifyPowerProduct< PROD( A, B ), NUM( 1 ), NUM( 1 ) > { };
156 
157  TEMPL( T1 ) struct Product< MINUS_S( A ), MINUS_S( A ) > :
158  public SimplifyPowerProduct< MINUS_S( A ), NUM( 1 ), NUM( 1 ) > { };
159 
160 
161  // n * n = n ^ 2
162  PROD_RULE(TYPN1, NUM(n), NUM(n), NUM(n*n), num<n*n>());
163 
164  // a/ b * ( c * d ) = ( a * c * d ) / b
165  PROD_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D),
166  RATIO(PROD(PROD(A, C), D), B),
167  ((_1._1 * _2._1) * _2._2) / _1._2);
168 
169  // simplify f * g * h regardless of the order
170  template <typename Prod, bool simplify = Prod::value> struct AuxProduct {
171  typedef PROD(typename Prod::AB, typename Prod::C) type;
172  COMBINE(typename Prod::AB, typename Prod::C, _1 * _2);
173  };
174 
175  template<typename Prod> struct AuxProduct<Prod, false> {
176  typedef PROD_S(typename Prod::AB, typename Prod::C) type;
177  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
178  };
179 
180  template<typename F, typename G, typename H>
181  struct Product<PROD_S(F, G), H> {
182  struct prod0 {
183  typedef F A; typedef G B; typedef H C;
184  typedef PROD_S(A, B) AB;
185  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
186  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
187  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
188  enum { value = false };
189  };
190  struct prod1 {
191  typedef F A; typedef H B; typedef G C;
192  typedef PROD_S(A, B) base;
193  typedef PROD(A, B) AB;
194  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
195  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
196  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
198  };
199  struct prod2 {
200  typedef G A; typedef H B; typedef F C;
201  typedef PROD_S(A, B) base;
202  typedef PROD(A, B) AB;
203  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
204  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
205  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
207  };
208 
209  typedef typename
210  ::boost::mpl::if_ <prod1, prod1,
213  typedef typename AuxProduct<prod>::type type;
214  inline static type combine(const ProductStruct<F, G>& fg, const H& h) {
215  const F& f = fg._1;
216  const G& g = fg._2;
217  const typename prod::A & a = prod::a(f, g, h);
218  const typename prod::B & b = prod::b(f, g, h);
219  const typename prod::C & c = prod::c(f, g, h);
220  return AuxProduct<prod>::combine(a * b, c);
221  }
222  };
223 
224 }
225 
227 
228 #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:101
#define MINUS(A)
PROD_S(A, B)>
Definition: Factorize.h:46
POWER_S(A, NUM(n))>
Definition: Factorize.h:50
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:521
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:20
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:94
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