Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:33:32

0001 #ifndef PhysicsTools_Utilities_SimplifyTrigonometric_h
0002 #define PhysicsTools_Utilities_SimplifyTrigonometric_h
0003 
0004 #include "PhysicsTools/Utilities/interface/Sin.h"
0005 #include "PhysicsTools/Utilities/interface/Cos.h"
0006 #include "PhysicsTools/Utilities/interface/Tan.h"
0007 #include "PhysicsTools/Utilities/interface/Sin2Cos2.h"
0008 #include "PhysicsTools/Utilities/interface/Minus.h"
0009 #include "PhysicsTools/Utilities/interface/Product.h"
0010 #include "PhysicsTools/Utilities/interface/Ratio.h"
0011 #include "PhysicsTools/Utilities/interface/Sum.h"
0012 #include "PhysicsTools/Utilities/interface/ParametricTrait.h"
0013 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
0014 
0015 namespace funct {
0016   // sin(-a) = - sin(a)
0017   SIN_RULE(TYPT1, MINUS_S(A), MINUS(SIN(A)), -sin(_._));
0018 
0019   // cos(-a) = cos(a)
0020   COS_RULE(TYPT1, MINUS_S(A), COS(A), cos(_._));
0021 
0022   // tan(-a) = - tan(a)
0023   TAN_RULE(TYPT1, MINUS_S(A), MINUS(TAN(A)), -tan(_._));
0024 
0025   // sin(x) * x = x * sin(x)
0026   PROD_RULE(TYPT1, SIN_S(A), A, PROD(A, SIN(A)), _2* _1);
0027 
0028   // cos(x) * x = x * cos(x)
0029   PROD_RULE(TYPT1, COS_S(A), A, PROD(A, COS(A)), _2* _1);
0030 
0031   // tan(x) * x = x * tan(x)
0032   PROD_RULE(TYPT1, TAN_S(A), A, PROD(A, TAN(A)), _2* _1);
0033 
0034   // sin(a) / cos(a) = tan(a)
0035   template <TYPT1, bool parametric = Parametric<A>::value>
0036   struct SimplifySCRatio {
0037     typedef RATIO_S(SIN(A), COS(A)) type;
0038     COMBINE(SIN_S(A), COS_S(A), _1 / _2);
0039   };
0040 
0041   TEMPL(T1) struct SimplifySCRatio<A, false> {
0042     typedef TAN_S(A) type;
0043     COMBINE(SIN_S(A), COS_S(A), type(_1._));
0044   };
0045 
0046   TEMPL(T1) struct Ratio<SIN_S(A), COS_S(A)> : public SimplifySCRatio<A> {};
0047 
0048   // sin(a) / tan(a) = cos(a)
0049   template <TYPT1, bool parametric = Parametric<A>::value>
0050   struct SimplifySTRatio {
0051     typedef RATIO_S(SIN(A), TAN(A)) type;
0052     COMBINE(SIN_S(A), TAN_S(A), _1 / _2);
0053   };
0054 
0055   TEMPL(T1) struct SimplifySTRatio<A, false> {
0056     typedef COS_S(A) type;
0057     COMBINE(SIN_S(A), TAN_S(A), type(_1._));
0058   };
0059 
0060   TEMPL(T1) struct Ratio<SIN_S(A), TAN_S(A)> : public SimplifySTRatio<A> {};
0061 
0062   // cos(a) * tan(a) = sin(a)
0063   template <TYPT1, bool parametric = Parametric<A>::value>
0064   struct SimplifySTProduct {
0065     typedef PROD(COS(A), TAN(A)) type;
0066     COMBINE(COS_S(A), TAN_S(A), _1* _2);
0067   };
0068 
0069   TEMPL(T1) struct SimplifySTProduct<A, false> {
0070     typedef SIN(A) type;
0071     COMBINE(COS_S(A), TAN_S(A), sin(_1._));
0072   };
0073 
0074   TEMPL(T1) struct Product<COS_S(A), TAN_S(A)> : public SimplifySTProduct<A> {};
0075 
0076   // cos(a) * sin(a) => sin(a) * cos(a)
0077   TEMPL(T1) struct Product<COS_S(A), SIN_S(A)> {
0078     typedef PROD(SIN(A), COS(A)) type;
0079     COMBINE(COS_S(A), SIN_S(A), _2* _1);
0080   };
0081 
0082   // cos(a)^b * tan(a)^b = sin(a)^b
0083   template <TYPT2, bool parametric = Parametric<A>::value || Parametric<B>::value>
0084   struct SimplifySTnProduct {
0085     typedef PROD(POWER(COS(A), B), POWER(TAN(A), B)) type;
0086     COMBINE(POWER_S(COS_S(A), B), POWER_S(TAN_S(A), B), _1* _2);
0087   };
0088 
0089   TEMPL(T2) struct SimplifySTnProduct<A, B, false> {
0090     typedef POWER(SIN(A), B) type;
0091     COMBINE(POWER_S(COS_S(A), B), POWER_S(TAN_S(A), B), pow(sin(_1._1._), _1._2));
0092   };
0093 
0094   TEMPL(T2) struct Product<POWER_S(COS_S(A), B), POWER_S(TAN_S(A), B)> : public SimplifySTnProduct<A, B> {};
0095 
0096   TEMPL(N1T1)
0097   struct Product<POWER_S(COS_S(A), NUM(n)), POWER_S(TAN_S(A), NUM(n))> : public SimplifySTnProduct<A, NUM(n)> {};
0098 
0099   // n cos(a)^2 + m sin(a)^2 = min(n, m) +
0100   //        (n - min(n, m)) cos(a)^2 + (m - min(n, m)) sin(a)^2
0101   template <TYPN2T1, bool parametric = Parametric<A>::value>
0102   struct SimpifyS2C2Sum {
0103     typedef SUM(PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A))) type;
0104     COMBINE(PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A)), _1 + _2);
0105   };
0106 
0107   TEMPL(N2T1) struct SimpifyS2C2Sum<n, m, A, false> {
0108     static constexpr int p = n < m ? n : m;
0109     typedef SUM(SUM(PROD(NUM(n - p), SIN2(A)), PROD(NUM(m - p), COS2(A))), NUM(p)) type;
0110     COMBINE(PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A)), (num<n - p>() * _1._2 + num<m - p>() * _2._2) + num<p>());
0111   };
0112 
0113   TEMPL(T1) struct Sum<POWER_S(SIN_S(A), NUM(2)), POWER_S(COS_S(A), NUM(2))> : public SimpifyS2C2Sum<1, 1, A> {};
0114 
0115   TEMPL(T1) struct Sum<POWER_S(COS_S(A), NUM(2)), POWER_S(SIN_S(A), NUM(2))> {
0116     typedef SUM(SIN2(A), COS2(A)) type;
0117     inline static type combine(const COS2(A) & _1, const SIN2(A) & _2) {
0118       return Sum<SIN2(A), COS2(A)>::combine(_2, _1);
0119     }
0120   };
0121 
0122   TEMPL(N2T1)
0123   struct Sum<PROD_S(NUM(n), POWER_S(SIN_S(A), NUM(2))), PROD_S(NUM(m), POWER_S(COS_S(A), NUM(2)))>
0124       : public SimpifyS2C2Sum<n, m, A> {};
0125 
0126   TEMPL(N2T1) struct Sum<PROD_S(NUM(m), POWER_S(COS_S(A), NUM(2))), PROD_S(NUM(n), POWER_S(SIN_S(A), NUM(2)))> {
0127     typedef SUM(PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A))) type;
0128     inline static type combine(const PROD(NUM(m), COS2(A)) & _1, const PROD(NUM(n), SIN2(A)) & _2) {
0129       return Sum<PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A))>::combine(_2, _1);
0130     }
0131   };
0132 
0133 }  // namespace funct
0134 
0135 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
0136 
0137 #endif