File indexing completed on 2024-04-06 12:24:22
0001 #ifndef PhysicsTools_Utilities_SimplifySum_h
0002 #define PhysicsTools_Utilities_SimplifySum_h
0003
0004 #include "PhysicsTools/Utilities/interface/Sum.h"
0005 #include "PhysicsTools/Utilities/interface/Difference.h"
0006 #include "PhysicsTools/Utilities/interface/Product.h"
0007 #include "PhysicsTools/Utilities/interface/Numerical.h"
0008 #include "PhysicsTools/Utilities/interface/DecomposeProduct.h"
0009 #include "PhysicsTools/Utilities/interface/ParametricTrait.h"
0010 #include <type_traits>
0011
0012 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
0013
0014 namespace funct {
0015
0016
0017 SUM_RULE(TYPT3, A, SUM_S(B, C), SUM(SUM(A, B), C), (_1 + _2._1) + _2._2);
0018
0019
0020 SUM_RULE(TYPT4, SUM_S(A, B), SUM_S(C, D), SUM(SUM(SUM(A, B), C), D), (_1 + _2._1) + _2._2);
0021
0022
0023 SUM_RULE(TYPN1T1, NUM(n), A, SUM(A, NUM(n)), _2 + _1);
0024
0025
0026 SUM_RULE(TYPN1T2, NUM(n), SUM_S(A, B), SUM(SUM_S(A, B), NUM(n)), _2 + _1);
0027
0028
0029 SUM_RULE(TYPT1, A, NUM(0), A, _1);
0030
0031
0032 SUM_RULE(TYP0, NUM(0), NUM(0), NUM(0), num<0>());
0033
0034
0035 SUM_RULE(TYPT2, PROD_S(A, B), NUM(0), PROD_S(A, B), _1);
0036
0037
0038 SUM_RULE(TYPT2, NUM(0), PROD_S(A, B), PROD_S(A, B), _2);
0039
0040
0041 SUM_RULE(TYPT2, NUM(0), MINUS_S(PROD_S(A, B)), MINUS_S(PROD_S(A, B)), _2);
0042
0043
0044 SUM_RULE(TYPT2, SUM_S(A, B), NUM(0), SUM_S(A, B), _1);
0045
0046
0047 SUM_RULE(TYPT2, NUM(0), SUM_S(A, B), SUM_S(A, B), _2);
0048
0049
0050 DIFF_RULE(TYPT2, A, MINUS_S(B), SUM(A, B), _1 + _2._);
0051
0052
0053 template <TYPN2T1, bool parametric = Parametric<A>::value == 1>
0054 struct ParametricSimplifiedSum {
0055 typedef PROD(NUM(n), A) arg1;
0056 typedef PROD(NUM(m), A) arg2;
0057 typedef SUM_S(arg1, arg2) type;
0058 COMBINE(arg1, arg2, type(_1, _2));
0059 };
0060
0061 TEMPL(N2T1)
0062 struct ParametricSimplifiedSum<n, m, A, false> {
0063 typedef PROD(NUM(n + m), A) type;
0064 typedef DecomposeProduct<PROD(NUM(n), A), A> Dec;
0065 COMBINE(PROD(NUM(n), A), PROD(NUM(m), A), num<n + m>() * Dec::get(_1));
0066 };
0067
0068 TEMPL(T1)
0069 struct ParametricSimplifiedSum<1, 1, A, true> {
0070 typedef SumStruct<A, A> type;
0071 COMBINE(A, A, type(_1, _2));
0072 };
0073
0074 TEMPL(T1)
0075 struct ParametricSimplifiedSum<1, 1, A, false> {
0076 typedef PROD(NUM(2), A) type;
0077 COMBINE(A, A, num<2>() * _1);
0078 };
0079
0080 TEMPL(N2T1)
0081 struct Sum<PROD_S(NUM(n), A), PROD_S(NUM(m), A)> : public ParametricSimplifiedSum<n, m, A> {};
0082
0083 TEMPL(N1T1)
0084 struct Sum<A, PROD_S(NUM(n), A)> : public ParametricSimplifiedSum<1, n, A> {};
0085
0086 TEMPL(N1T1)
0087 struct Sum<PROD_S(NUM(n), A), A> : public ParametricSimplifiedSum<n, 1, A> {};
0088
0089 TEMPL(T1)
0090 struct Sum<A, A> : public ParametricSimplifiedSum<1, 1, A> {};
0091
0092 TEMPL(T1)
0093 struct Sum<MINUS_S(A), MINUS_S(A)> : public ParametricSimplifiedSum<1, 1, MINUS_S(A)> {};
0094
0095 TEMPL(T2)
0096 struct Sum<MINUS_S(PROD_S(A, B)), MINUS_S(PROD_S(A, B))>
0097 : public ParametricSimplifiedSum<1, 1, MINUS_S(PROD_S(A, B))> {};
0098
0099 TEMPL(N1)
0100 struct Sum<NUM(n), NUM(n)> : public ParametricSimplifiedSum<1, 1, NUM(n)> {};
0101
0102 TEMPL(T2)
0103 struct Sum<PROD_S(A, B), PROD_S(A, B)> : public ParametricSimplifiedSum<1, 1, PROD_S(A, B)> {};
0104
0105 TEMPL(N1T1)
0106 struct Sum<PROD_S(NUM(n), A), PROD_S(NUM(n), A)> : public ParametricSimplifiedSum<1, 1, PROD_S(NUM(n), A)> {};
0107
0108
0109 template <typename Prod, bool simplify = Prod::value>
0110 struct AuxSum {
0111 typedef SUM(typename Prod::AB, typename Prod::C) type;
0112 COMBINE(typename Prod::AB, typename Prod::C, _1 + _2);
0113 };
0114
0115 template <typename Prod>
0116 struct AuxSum<Prod, false> {
0117 typedef SUM_S(typename Prod::AB, typename Prod::C) type;
0118 COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
0119 };
0120
0121 template <typename F, typename G, typename H>
0122 struct SimplSumOrd {
0123 struct prod0 {
0124 typedef F A;
0125 typedef G B;
0126 typedef H C;
0127 typedef SUM_S(A, B) AB;
0128 inline static const A& a(const F& f, const G& g, const H& h) { return f; }
0129 inline static const B& b(const F& f, const G& g, const H& h) { return g; }
0130 inline static const C& c(const F& f, const G& g, const H& h) { return h; }
0131 enum { value = false };
0132 };
0133 struct prod1 {
0134 typedef F A;
0135 typedef H B;
0136 typedef G C;
0137 typedef SUM_S(A, B) base;
0138 typedef SUM(A, B) AB;
0139 inline static const A& a(const F& f, const G& g, const H& h) { return f; }
0140 inline static const B& b(const F& f, const G& g, const H& h) { return h; }
0141 inline static const C& c(const F& f, const G& g, const H& h) { return g; }
0142 enum { value = not ::std::is_same<AB, base>::value };
0143 };
0144 struct prod2 {
0145 typedef G A;
0146 typedef H B;
0147 typedef F C;
0148 typedef SUM_S(A, B) base;
0149 typedef SUM(A, B) AB;
0150 inline static const A& a(const F& f, const G& g, const H& h) { return g; }
0151 inline static const B& b(const F& f, const G& g, const H& h) { return h; }
0152 inline static const C& c(const F& f, const G& g, const H& h) { return f; }
0153 enum { value = not ::std::is_same<AB, base>::value };
0154 };
0155
0156 typedef
0157 typename std::conditional<prod1::value, prod1, typename std::conditional<prod2::value, prod2, prod0>::type>::type
0158 prod;
0159 typedef typename AuxSum<prod>::type type;
0160 inline static type combine(const SUM_S(F, G) & fg, const H& h) {
0161 const F& f = fg._1;
0162 const G& g = fg._2;
0163 const typename prod::A& a = prod::a(f, g, h);
0164 const typename prod::B& b = prod::b(f, g, h);
0165 const typename prod::C& c = prod::c(f, g, h);
0166 return AuxSum<prod>::combine(a + b, c);
0167 }
0168 };
0169
0170 TEMPL(T3)
0171 struct Sum<SUM_S(A, B), C> : public SimplSumOrd<A, B, C> {};
0172
0173 TEMPL(T4)
0174 struct Sum<SUM_S(A, B), PROD_S(C, D)> : public SimplSumOrd<A, B, PROD_S(C, D)> {};
0175
0176 }
0177
0178 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
0179
0180 #endif