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 #include <boost/mpl/if.hpp>
12 
14 
15 namespace funct {
16 
17  // A + ( B + C ) => ( A + B ) + C
18  SUM_RULE(TYPT3, A, SUM_S(B, C),
19  SUM(SUM(A, B), C), (_1 + _2._1) + _2._2);
20 
21  // ( A + B ) + ( C + D ) => ( ( A + B ) + C ) + D
22  SUM_RULE(TYPT4, SUM_S(A, B), SUM_S(C, D),
23  SUM(SUM(SUM(A, B), C), D), (_1 + _2._1) + _2._2);
24 
25  // n + A = A + n
26  SUM_RULE(TYPN1T1, NUM(n), A, SUM(A, NUM(n)), _2 + _1);
27 
28  // n + ( A + B )= ( A + B ) + n
29  SUM_RULE(TYPN1T2, NUM(n), SUM_S(A, B), SUM(SUM_S(A, B), NUM(n)), _2 + _1);
30 
31  // A + 0 = A
32  SUM_RULE(TYPT1, A, NUM(0), A, _1);
33 
34  // 0 + 0 = 0
35  SUM_RULE(TYP0, NUM(0), NUM(0), NUM(0), num<0>());
36 
37  // ( A * B ) + 0 = ( A * B )
38  SUM_RULE(TYPT2, PROD_S(A, B), NUM(0), PROD_S(A, B), _1);
39 
40  // 0 + ( A * B ) = ( A * B )
41  SUM_RULE(TYPT2, NUM(0), PROD_S(A, B), PROD_S(A, B), _2);
42 
43  // 0 - ( A * B ) = - ( A * B )
45 
46  // ( A + B ) + 0 = ( A + B )
47  SUM_RULE(TYPT2, SUM_S(A, B), NUM(0), SUM_S(A, B), _1);
48 
49  // 0 + ( A + B ) = ( A + B )
50  SUM_RULE(TYPT2, NUM(0), SUM_S(A, B), SUM_S(A, B), _2);
51 
52  // A - ( -B ) = A + B
53  DIFF_RULE(TYPT2, A, MINUS_S(B), SUM(A, B), _1 + _2._);
54 
55  // n * A + m * A => ( n + m ) * A
58  typedef PROD(NUM(n), A) arg1;
59  typedef PROD(NUM(m), A) arg2;
60  typedef SUM_S(arg1, arg2) type;
61  COMBINE(arg1, arg2, type(_1, _2));
62  };
63 
64  TEMPL(N2T1)
66  typedef PROD(NUM(n + m), A) type;
67  typedef DecomposeProduct<PROD(NUM(n), A), A> Dec;
68  COMBINE(PROD(NUM(n), A), PROD(NUM(m), A),
69  num<n + m>() * Dec::get(_1));
70  };
71 
72  TEMPL(T1)
73  struct ParametricSimplifiedSum<1, 1, A, true> {
75  COMBINE(A, A, type(_1, _2));
76  };
77 
78  TEMPL(T1)
79  struct ParametricSimplifiedSum<1, 1, A, false> {
80  typedef PROD(NUM(2), A) type;
81  COMBINE( A, A, num<2>() * _1 );
82  };
83 
84  TEMPL(N2T1)
85  struct Sum<PROD_S(NUM(n), A), PROD_S(NUM(m), A) > :
86  public ParametricSimplifiedSum<n, m, A> { };
87 
88  TEMPL(N1T1)
89  struct Sum<A, PROD_S(NUM(n), A) > :
90  public ParametricSimplifiedSum<1, n, A> { };
91 
92  TEMPL(N1T1)
93  struct Sum<PROD_S(NUM(n), A) , A> :
94  public ParametricSimplifiedSum<n, 1, A> { };
95 
96  TEMPL(T1)
97  struct Sum<A, A> :
98  public ParametricSimplifiedSum<1, 1, A> { };
99 
100  TEMPL(T1)
101  struct Sum<MINUS_S(A), MINUS_S(A) > :
102  public ParametricSimplifiedSum<1, 1, MINUS_S(A) > { };
103 
104  TEMPL(T2)
105  struct Sum< MINUS_S(PROD_S(A, B)),
106  MINUS_S(PROD_S(A, B)) > :
107  public ParametricSimplifiedSum< 1, 1, MINUS_S(PROD_S(A, B)) > { };
108 
109  TEMPL(N1)
110  struct Sum< NUM(n), NUM(n) > :
111  public ParametricSimplifiedSum< 1, 1, NUM(n) > { };
112 
113  TEMPL(T2)
114  struct Sum< PROD_S(A, B), PROD_S(A, B) > :
115  public ParametricSimplifiedSum< 1, 1, PROD_S(A, B) > { };
116 
117  TEMPL(N1T1)
118  struct Sum< PROD_S(NUM(n), A),
119  PROD_S(NUM(n), A) > :
120  public ParametricSimplifiedSum< 1, 1, PROD_S(NUM(n), A) > { };
121 
122  // simplify f + g + h regardless of the order
123  template <typename Prod, bool simplify = Prod::value>
124  struct AuxSum {
125  typedef SUM(typename Prod::AB, typename Prod::C) type;
126  COMBINE(typename Prod::AB, typename Prod::C, _1 + _2);
127  };
128 
129  template<typename Prod>
130  struct AuxSum<Prod, false> {
131  typedef SUM_S(typename Prod::AB, typename Prod::C) type;
132  COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
133  };
134 
135  template<typename F, typename G, typename H>
136  struct SimplSumOrd {
137  struct prod0 {
138  typedef F A; typedef G B; typedef H C;
139  typedef SUM_S(A, B) AB;
140  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
141  inline static const B& b(const F& f, const G& g, const H& h) { return g; }
142  inline static const C& c(const F& f, const G& g, const H& h) { return h; }
143  enum { value = false };
144  };
145  struct prod1 {
146  typedef F A; typedef H B; typedef G C;
147  typedef SUM_S(A, B) base;
148  typedef SUM(A, B) AB;
149  inline static const A& a(const F& f, const G& g, const H& h) { return f; }
150  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
151  inline static const C& c(const F& f, const G& g, const H& h) { return g; }
153  };
154  struct prod2 {
155  typedef G A; typedef H B; typedef F C;
156  typedef SUM_S(A, B) base;
157  typedef SUM(A, B) AB;
158  inline static const A& a(const F& f, const G& g, const H& h) { return g; }
159  inline static const B& b(const F& f, const G& g, const H& h) { return h; }
160  inline static const C& c(const F& f, const G& g, const H& h) { return f; }
162  };
163 
164  typedef typename
165  ::boost::mpl::if_ <prod1,
166  prod1,
167  typename ::boost::mpl::if_ <prod2,
168  prod2,
169  prod0
170  >::type
172  typedef typename AuxSum< prod >::type type;
173  inline static type combine(const SUM_S(F, G)& fg, const H& h) {
174  const F& f = fg._1;
175  const G& g = fg._2;
176  const typename prod::A & a = prod::a(f, g, h);
177  const typename prod::B & b = prod::b(f, g, h);
178  const typename prod::C & c = prod::c(f, g, h);
179  return AuxSum< prod >::combine(a + b, c);
180  }
181  };
182 
183  TEMPL(T3)
184  struct Sum<SUM_S(A, B), C> :
185  public SimplSumOrd<A, B, C> { };
186 
187  TEMPL(T4)
188  struct Sum< SUM_S(A, B), PROD_S(C, D) > :
189  public SimplSumOrd< A, B, PROD_S(C, D) > { };
190 
191 }
192 
194 
195 #endif
::boost::mpl::if_< prod1, prod1, typename::boost::mpl::if_< prod2, prod2, prod0 >::type >::type prod
Definition: SimplifySum.h:171
AuxSum< prod >::type type
Definition: SimplifySum.h:172
const Numerical< n > & num()
Definition: Numerical.h:16
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:141
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:159
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:151
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
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:160
PROD_S(A, B)>
Definition: Factorize.h:46
SumStruct< arg1, arg2 > type
Definition: SimplifySum.h:60
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:173
#define SUM_RULE(TMPL, T1, T2, RES, COMB)
#define TYP0
Definition: Simplify_begin.h:4
#define TYPN1T2
double f[11][100]
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Definition: value.py:1
static const std::string B
static type combine(const typename Prod::AB &_1, const typename Prod::C &_2)
Definition: SimplifySum.h:126
#define TYPT4
Definition: Simplify_begin.h:9
static const B & b(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:150
static const C & c(const F &f, const G &g, const H &h)
Definition: SimplifySum.h:142
#define SUM(A, B)
TEMPL(T1) struct Divides0
Definition: Factorize.h:20
double b
Definition: hdecay.h:120
#define DIFF_RULE(TMPL, T1, T2, RES, COMB)
typedef PROD(F, SUM(RATIO(A, F), RATIO(B, F))) type
double a
Definition: hdecay.h:121
Definition: Sum.h:26
#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 type get(const PROD_S(A, B)&_)
Definition: Primitive.h:171
#define TYPT1
Definition: Simplify_begin.h:6