File indexing completed on 2024-04-06 12:24:21
0001 #ifndef PhysicsTools_Utilities_SimplifyProduct_h
0002 #define PhysicsTools_Utilities_SimplifyProduct_h
0003
0004 #include "PhysicsTools/Utilities/interface/Product.h"
0005 #include "PhysicsTools/Utilities/interface/Fraction.h"
0006 #include "PhysicsTools/Utilities/interface/DecomposePower.h"
0007 #include "PhysicsTools/Utilities/interface/ParametricTrait.h"
0008 #include <type_traits>
0009
0010 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
0011
0012 namespace funct {
0013
0014
0015 PROD_RULE(TYPT3, A, PROD_S(B, C), PROD(PROD(A, B), C), (_1 * _2._1) * _2._2);
0016
0017
0018 PROD_RULE(TYPT1, NUM(0), A, NUM(0), num<0>());
0019
0020
0021 PROD_RULE(TYPN1, NUM(0), NUM(n), NUM(0), num<0>());
0022
0023
0024 PROD_RULE(TYPT2, NUM(0), PROD_S(A, B), NUM(0), num<0>());
0025
0026
0027 PROD_RULE(TYPT1, NUM(1), A, A, _2);
0028
0029
0030
0031 PROD_RULE(TYPN1, NUM(1), NUM(n), NUM(n), _2);
0032
0033
0034 PROD_RULE(TYPN2, NUM(1), FRACT_S(n, m), FRACT_S(n, m), _2);
0035
0036
0037 PROD_RULE(TYP0, NUM(1), NUM(1), NUM(1), num<1>());
0038
0039
0040 PROD_RULE(TYPT1, NUM(-1), A, MINUS_S(A), -_2);
0041
0042
0043 PROD_RULE(TYPN1, NUM(-1), NUM(n), NUM(-n), num<-n>());
0044
0045
0046 PROD_RULE(TYPT2, NUM(1), PROD_S(A, B), PROD_S(A, B), _2);
0047
0048
0049 PROD_RULE(TYPT2, A, MINUS_S(B), MINUS(PROD(A, B)), -(_1* _2._));
0050
0051
0052 PROD_RULE(TYPN1T1, NUM(n), MINUS_S(A), MINUS(PROD(NUM(n), A)), -(_1* _2._));
0053
0054
0055 PROD_RULE(TYPT3, PROD_S(A, B), MINUS_S(C), MINUS(PROD(PROD(A, B), C)), -(_1* _2._));
0056
0057
0058 PROD_RULE(TYPT1, NUM(1), MINUS_S(A), MINUS(A), _2);
0059
0060
0061 PROD_RULE(TYPT2, MINUS_S(A), MINUS_S(B), PROD(A, B), _1._* _2._);
0062
0063
0064 PROD_RULE(TYPT2, MINUS_S(A), B, MINUS(PROD(A, B)), -(_1._* _2));
0065
0066
0067 PROD_RULE(TYPT3, A, RATIO_S(B, C), RATIO(PROD(A, B), C), (_1 * _2._1) / _2._2);
0068
0069
0070 PROD_RULE(TYPN1T2, NUM(n), RATIO_S(A, B), RATIO(PROD(NUM(n), A), B), (_1 * _2._1) / _2._2);
0071
0072
0073 PROD_RULE(TYPT2, NUM(1), RATIO_S(A, B), RATIO(A, B), _2);
0074
0075
0076 PROD_RULE(TYPT2, NUM(0), RATIO_S(A, B), NUM(0), num<0>());
0077
0078
0079 PROD_RULE(TYPN1T1, A, NUM(n), PROD(NUM(n), A), _2* _1);
0080
0081
0082 PROD_RULE(TYPN1T2, PROD_S(A, B), NUM(n), PROD(PROD(NUM(n), A), B), (_2 * _1._1) * _1._2);
0083
0084
0085 PROD_RULE(TYPT4, PROD_S(A, B), PROD_S(C, D), PROD(PROD(PROD(A, B), C), D), (_1 * _2._1) * _2._2);
0086
0087
0088 PROD_RULE(TYPN3T1, FRACT_S(n, m), RATIO_S(A, NUM(k)), PROD(FRACT(n, m + k), A), (fract<n, m + k>() * _2._1));
0089
0090
0091 PROD_RULE(TYPN1T2, RATIO_S(A, B), NUM(n), RATIO(PROD(NUM(n), A), B), (_2 * _1._1) / _1._2);
0092
0093
0094 PROD_RULE(TYPT3, RATIO_S(A, B), C, RATIO(PROD(A, C), B), (_1._1 * _2) / _1._2);
0095
0096
0097 PROD_RULE(TYP0, NUM(0), NUM(1), NUM(0), num<0>());
0098
0099
0100 PROD_RULE(TYPT4, RATIO_S(A, B), RATIO_S(C, D), RATIO(PROD(A, C), PROD(B, D)), (_1._1 * _2._1) / (_1._2 * _2._2));
0101
0102
0103 template <TYPT3, bool parametric = Parametric<A>::value>
0104 struct SimplifyPowerProduct {
0105 typedef POWER(A, B) arg1;
0106 typedef POWER(A, C) arg2;
0107 typedef PROD_S(arg1, arg2) type;
0108 COMBINE(arg1, arg2, type(_1, _2));
0109 };
0110
0111 TEMPL(T3)
0112 struct SimplifyPowerProduct<A, B, C, false> {
0113 typedef POWER(A, B) arg1;
0114 typedef POWER(A, C) arg2;
0115 typedef POWER(A, SUM(B, C)) type;
0116 inline static type combine(const arg1& _1, const arg2& _2) {
0117 return pow(DecomposePower<A, B>::getBase(_1),
0118 (DecomposePower<A, B>::getExp(_1) + DecomposePower<A, C>::getExp(_2)));
0119 }
0120 };
0121
0122 TEMPL(T3) struct Product<POWER_S(A, B), POWER_S(A, C)> : public SimplifyPowerProduct<A, B, C> {};
0123
0124 TEMPL(T2) struct Product<POWER_S(A, B), POWER_S(A, B)> : public SimplifyPowerProduct<A, B, B> {};
0125
0126 TEMPL(T2) struct Product<A, POWER_S(A, B)> : public SimplifyPowerProduct<A, NUM(1), B> {};
0127
0128 TEMPL(N1T1) struct Product<A, POWER_S(A, NUM(n))> : public SimplifyPowerProduct<A, NUM(1), NUM(n)> {};
0129
0130 TEMPL(T2) struct Product<POWER_S(A, B), A> : public SimplifyPowerProduct<A, B, NUM(1)> {};
0131
0132 TEMPL(N1T1) struct Product<POWER_S(A, NUM(n)), A> : public SimplifyPowerProduct<A, NUM(n), NUM(1)> {};
0133
0134 TEMPL(T1) struct Product<A, A> : public SimplifyPowerProduct<A, NUM(1), NUM(1)> {};
0135
0136 TEMPL(T2) struct Product<PROD_S(A, B), PROD_S(A, B)> : public SimplifyPowerProduct<PROD(A, B), NUM(1), NUM(1)> {};
0137
0138 TEMPL(T1) struct Product<MINUS_S(A), MINUS_S(A)> : public SimplifyPowerProduct<MINUS_S(A), NUM(1), NUM(1)> {};
0139
0140
0141 PROD_RULE(TYPN1, NUM(n), NUM(n), NUM(n* n), num<n * n>());
0142
0143
0144 PROD_RULE(TYPT4, RATIO_S(A, B), PROD_S(C, D), RATIO(PROD(PROD(A, C), D), B), ((_1._1 * _2._1) * _2._2) / _1._2);
0145
0146
0147 template <typename Prod, bool simplify = Prod::value>
0148 struct AuxProduct {
0149 typedef PROD(typename Prod::AB, typename Prod::C) type;
0150 COMBINE(typename Prod::AB, typename Prod::C, _1* _2);
0151 };
0152
0153 template <typename Prod>
0154 struct AuxProduct<Prod, false> {
0155 typedef PROD_S(typename Prod::AB, typename Prod::C) type;
0156 COMBINE(typename Prod::AB, typename Prod::C, type(_1, _2));
0157 };
0158
0159 template <typename F, typename G, typename H>
0160 struct Product<PROD_S(F, G), H> {
0161 struct prod0 {
0162 typedef F A;
0163 typedef G B;
0164 typedef H C;
0165 typedef PROD_S(A, B) AB;
0166 inline static const A& a(const F& f, const G& g, const H& h) { return f; }
0167 inline static const B& b(const F& f, const G& g, const H& h) { return g; }
0168 inline static const C& c(const F& f, const G& g, const H& h) { return h; }
0169 enum { value = false };
0170 };
0171 struct prod1 {
0172 typedef F A;
0173 typedef H B;
0174 typedef G C;
0175 typedef PROD_S(A, B) base;
0176 typedef PROD(A, B) AB;
0177 inline static const A& a(const F& f, const G& g, const H& h) { return f; }
0178 inline static const B& b(const F& f, const G& g, const H& h) { return h; }
0179 inline static const C& c(const F& f, const G& g, const H& h) { return g; }
0180 enum { value = not ::std::is_same<AB, base>::value };
0181 };
0182 struct prod2 {
0183 typedef G A;
0184 typedef H B;
0185 typedef F C;
0186 typedef PROD_S(A, B) base;
0187 typedef PROD(A, B) AB;
0188 inline static const A& a(const F& f, const G& g, const H& h) { return g; }
0189 inline static const B& b(const F& f, const G& g, const H& h) { return h; }
0190 inline static const C& c(const F& f, const G& g, const H& h) { return f; }
0191 enum { value = not ::std::is_same<AB, base>::value };
0192 };
0193
0194 typedef
0195 typename std::conditional<prod1::value, prod1, typename std::conditional<prod2::value, prod2, prod0>::type>::type
0196 prod;
0197 typedef typename AuxProduct<prod>::type type;
0198 inline static type combine(const ProductStruct<F, G>& fg, const H& h) {
0199 const F& f = fg._1;
0200 const G& g = fg._2;
0201 const typename prod::A& a = prod::a(f, g, h);
0202 const typename prod::B& b = prod::b(f, g, h);
0203 const typename prod::C& c = prod::c(f, g, h);
0204 return AuxProduct<prod>::combine(a * b, c);
0205 }
0206 };
0207
0208 }
0209
0210 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
0211
0212 #endif