CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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; }
195  enum { value = ::boost::type_traits::ice_not<
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; }
205  enum { value = ::boost::type_traits::ice_not<
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
static const bool value
Definition: Factorize.h:107
#define TYPN1
type
Definition: HCALResponse.h:21
#define TYPN2
typedef POWER(A, NUM(n)) arg
#define TYPT2
Definition: Simplify_begin.h:7
MINUS_S(B)>
Definition: Factorize.h:99
#define MINUS(A)
double_binary B
Definition: DDStreamer.cc:234
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]
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define TYPT4
Definition: Simplify_begin.h:9
#define PROD_RULE(TMPL, T1, T2, RES, COMB)
tuple G
Definition: callgraph.py:12
::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)
static type combine(const arg1 &_1, const arg2 &_2)
TEMPL(T1) struct Divides0
Definition: Factorize.h:18
double b
Definition: hdecay.h:120
string const
Definition: compareJSON.py:14
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
def template
Definition: svgfig.py:520