CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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;
64  typedef DecomposeProduct<PROD(NUM(n), A), A> Dec;
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
static const bool value
Definition: Factorize.h:100
AuxSum< prod >::type type
Definition: SimplifySum.h:159
const Numerical< n > & num()
Definition: Numerical.h:18
const edm::EventSetup & c
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
#define TYPT2
Definition: Simplify_begin.h:7
MINUS_S(B)>
Definition: Factorize.h:94
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:152
PROD_S(A, B)>
Definition: Factorize.h:38
SumStruct< arg1, arg2 > type
Definition: SimplifySum.h:57
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 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)
#define TYP0
Definition: Simplify_begin.h:4
#define TYPN1T2
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
Definition: SimplifySum.h:112
#define TYPT4
Definition: Simplify_begin.h:9
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
#define SUM(A, B)
TEMPL(T1) struct Divides0
Definition: Factorize.h:15
double b
Definition: hdecay.h:118
#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:119
Definition: Sum.h:18
#define TYPT3
Definition: Simplify_begin.h:8
#define COMBINE(A, B, RES)
Definition: APVGainStruct.h:7
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
static type get(const PROD_S(A, B)&_)
Definition: Primitive.h:170
#define TYPT1
Definition: Simplify_begin.h:6
def template
Definition: svgfig.py:521
std::conditional< prod1::value, prod1, typename std::conditional< prod2::value, prod2, prod0 >::type >::type prod
Definition: SimplifySum.h:158