CMS 3D CMS Logo

SimplifySum.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_SimplifySum_h
2 #define PhysicsTools_Utilities_SimplifySum_h
3 
10 #include <type_traits>
11 
13 
14 namespace funct {
15 
16  // A + ( B + C ) => ( A + B ) + C
17  SUM_RULE(TYPT3, A, SUM_S(B, C), SUM(SUM(A, B), C), (_1 + _2._1) + _2._2);
18 
19  // ( A + B ) + ( C + D ) => ( ( A + B ) + C ) + D
20  SUM_RULE(TYPT4, SUM_S(A, B), SUM_S(C, D), SUM(SUM(SUM(A, B), C), D), (_1 + _2._1) + _2._2);
21 
22  // n + A = A + n
23  SUM_RULE(TYPN1T1, NUM(n), A, SUM(A, NUM(n)), _2 + _1);
24 
25  // n + ( A + B )= ( A + B ) + n
26  SUM_RULE(TYPN1T2, NUM(n), SUM_S(A, B), SUM(SUM_S(A, B), NUM(n)), _2 + _1);
27 
28  // A + 0 = A
29  SUM_RULE(TYPT1, A, NUM(0), A, _1);
30 
31  // 0 + 0 = 0
32  SUM_RULE(TYP0, NUM(0), NUM(0), NUM(0), num<0>());
33 
34  // ( A * B ) + 0 = ( A * B )
35  SUM_RULE(TYPT2, PROD_S(A, B), NUM(0), PROD_S(A, B), _1);
36 
37  // 0 + ( A * B ) = ( A * B )
38  SUM_RULE(TYPT2, NUM(0), PROD_S(A, B), PROD_S(A, B), _2);
39 
40  // 0 - ( A * B ) = - ( A * B )
42 
43  // ( A + B ) + 0 = ( A + B )
44  SUM_RULE(TYPT2, SUM_S(A, B), NUM(0), SUM_S(A, B), _1);
45 
46  // 0 + ( A + B ) = ( A + B )
47  SUM_RULE(TYPT2, NUM(0), SUM_S(A, B), SUM_S(A, B), _2);
48 
49  // A - ( -B ) = A + B
50  DIFF_RULE(TYPT2, A, MINUS_S(B), SUM(A, B), _1 + _2._);
51 
52  // n * A + m * A => ( n + m ) * A
55  typedef PROD(NUM(n), A) arg1;
56  typedef PROD(NUM(m), A) arg2;
57  typedef SUM_S(arg1, arg2) type;
58  COMBINE(arg1, arg2, type(_1, _2));
59  };
60 
61  TEMPL(N2T1)
63  typedef PROD(NUM(n + m), A) type;
65  COMBINE(PROD(NUM(n), A), PROD(NUM(m), A), num<n + m>() * Dec::get(_1));
66  };
67 
68  TEMPL(T1)
69  struct ParametricSimplifiedSum<1, 1, A, true> {
71  COMBINE(A, A, type(_1, _2));
72  };
73 
74  TEMPL(T1)
75  struct ParametricSimplifiedSum<1, 1, A, false> {
76  typedef PROD(NUM(2), A) type;
77  COMBINE(A, A, num<2>() * _1);
78  };
79 
80  TEMPL(N2T1)
81  struct Sum<PROD_S(NUM(n), A), PROD_S(NUM(m), A)> : public ParametricSimplifiedSum<n, m, A> {};
82 
83  TEMPL(N1T1)
84  struct Sum<A, PROD_S(NUM(n), A)> : public ParametricSimplifiedSum<1, n, A> {};
85 
86  TEMPL(N1T1)
87  struct Sum<PROD_S(NUM(n), A), A> : public ParametricSimplifiedSum<n, 1, A> {};
88 
89  TEMPL(T1)
90  struct Sum<A, A> : public ParametricSimplifiedSum<1, 1, A> {};
91 
92  TEMPL(T1)
93  struct Sum<MINUS_S(A), MINUS_S(A)> : public ParametricSimplifiedSum<1, 1, MINUS_S(A)> {};
94 
95  TEMPL(T2)
96  struct Sum<MINUS_S(PROD_S(A, B)), MINUS_S(PROD_S(A, B))>
97  : public ParametricSimplifiedSum<1, 1, MINUS_S(PROD_S(A, B))> {};
98 
99  TEMPL(N1)
100  struct Sum<NUM(n), NUM(n)> : public ParametricSimplifiedSum<1, 1, NUM(n)> {};
101 
102  TEMPL(T2)
103  struct Sum<PROD_S(A, B), PROD_S(A, B)> : public ParametricSimplifiedSum<1, 1, PROD_S(A, B)> {};
104 
105  TEMPL(N1T1)
106  struct Sum<PROD_S(NUM(n), A), PROD_S(NUM(n), A)> : public ParametricSimplifiedSum<1, 1, PROD_S(NUM(n), A)> {};
107 
108  // simplify f + g + h regardless of the order
109  template <typename Prod, bool simplify = Prod::value>
110  struct AuxSum {
111  typedef SUM(typename Prod::AB, typename Prod::C) type;
112  COMBINE(typename Prod::AB, typename Prod::C, _1 + _2);
113  };
114 
115  template <typename Prod>
116  struct AuxSum<Prod, false> {
117  typedef SUM_S(typename Prod::AB, typename Prod::C) type;
118  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
119  };
120 
121  template <typename F, typename G, typename H>
122  struct SimplSumOrd {
123  struct prod0 {
124  typedef F A;
125  typedef G B;
126  typedef H C;
127  typedef SUM_S(A, B) AB;
128  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
129  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
130  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
131  enum { value = false };
132  };
133  struct prod1 {
134  typedef F A;
135  typedef H B;
136  typedef G C;
137  typedef SUM_S(A, B) base;
138  typedef SUM(A, B) AB;
139  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
140  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
141  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
143  };
144  struct prod2 {
145  typedef G A;
146  typedef H B;
147  typedef F C;
148  typedef SUM_S(A, B) base;
149  typedef SUM(A, B) AB;
150  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
151  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
152  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
154  };
155 
156  typedef
159  typedef typename AuxSum<prod>::type type;
160  inline static type combine(const SUM_S(F, G) & fg, const H& h) {
161  const F& f = fg._1;
162  const G& g = fg._2;
163  const typename prod::A& a = prod::a(f, g, h);
164  const typename prod::B& b = prod::b(f, g, h);
165  const typename prod::C& c = prod::c(f, g, h);
166  return AuxSum<prod>::combine(a + b, c);
167  }
168  };
169 
170  TEMPL(T3)
171  struct Sum<SUM_S(A, B), C> : public SimplSumOrd<A, B, C> {};
172 
173  TEMPL(T4)
174  struct Sum<SUM_S(A, B), PROD_S(C, D)> : public SimplSumOrd<A, B, PROD_S(C, D)> {};
175 
176 } // namespace funct
177 
179 
180 #endif
AuxSum< prod >::type type
Definition: SimplifySum.h:159
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:129
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:151
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:141
Definition: APVGainStruct.h:7
Definition: Abs.h:5
#define TYPT2
Definition: Simplify_begin.h:7
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:139
Product< Numerical< n >, A >::type arg1
Definition: SimplifySum.h:55
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:150
PROD_S(B, C)>
Definition: Factorize.h:114
typedef MINUS_S(A) arg
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:152
SumStruct< A, B > base
Definition: SimplifySum.h:137
SumStruct< arg1, arg2 > type
Definition: SimplifySum.h:57
SumStruct< A, B > AB
Definition: SimplifySum.h:127
static const A & a(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:128
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
Sum< A, B >::type AB
Definition: SimplifySum.h:138
TEMPL(T2) struct Divides B
Definition: Factorize.h:24
#define TYPN1T1
#define SUM_S(A, B)
static type combine(const SumStruct< F, G > &fg, const H &h)
Definition: SimplifySum.h:160
#define SUM_RULE(TMPL, T1, T2, RES, COMB)
Product< Numerical< m >, A >::type arg2
Definition: SimplifySum.h:56
#define TYP0
Definition: Simplify_begin.h:4
#define TYPN1T2
SumStruct< typename Prod::AB, typename Prod::C > type
Definition: SimplifySum.h:117
double f[11][100]
Sum< typename Prod::AB, typename Prod::C >::type type
Definition: SimplifySum.h:111
Definition: value.py:1
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
Definition: SimplifySum.h:112
#define TYPT4
Definition: Simplify_begin.h:9
DecomposeProduct< typename Product< Numerical< n >, A >::type, A > Dec
Definition: SimplifySum.h:64
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:140
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:130
SumStruct< A, B > base
Definition: SimplifySum.h:148
#define SUM(A, B)
TEMPL(T1) struct Divides0
Definition: Factorize.h:15
double b
Definition: hdecay.h:120
#define DIFF_RULE(TMPL, T1, T2, RES, COMB)
arg type
Definition: Factorize.h:32
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
double a
Definition: hdecay.h:121
Definition: Sum.h:18
Product< Numerical< 2 >, A >::type type
Definition: SimplifySum.h:76
#define TYPT3
Definition: Simplify_begin.h:8
#define COMBINE(A, B, RES)
Definition: APVGainStruct.h:7
#define get
PROD_S(A, B)> NUM(n))
Definition: Factorize.h:87
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
Product< Numerical< n+m >, A >::type type
Definition: SimplifySum.h:63
#define TYPT1
Definition: Simplify_begin.h:6
Sum< A, B >::type AB
Definition: SimplifySum.h:149
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
Definition: SimplifySum.h:158