CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/PhysicsTools/Utilities/interface/SimplifyTrigonometric.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_SimplifyTrigonometric_h
00002 #define PhysicsTools_Utilities_SimplifyTrigonometric_h
00003 
00004 #include "PhysicsTools/Utilities/interface/Sin.h"
00005 #include "PhysicsTools/Utilities/interface/Cos.h"
00006 #include "PhysicsTools/Utilities/interface/Tan.h"
00007 #include "PhysicsTools/Utilities/interface/Sin2Cos2.h"
00008 #include "PhysicsTools/Utilities/interface/Minus.h"
00009 #include "PhysicsTools/Utilities/interface/Product.h"
00010 #include "PhysicsTools/Utilities/interface/Ratio.h"
00011 #include "PhysicsTools/Utilities/interface/Sum.h"
00012 #include "PhysicsTools/Utilities/interface/ParametricTrait.h"
00013 
00014 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
00015 
00016 namespace funct {
00017   // sin(-a) = - sin(a)
00018   SIN_RULE(TYPT1, MINUS_S(A), MINUS(SIN(A)), -sin(_._));
00019 
00020   // cos(-a) = cos(a)
00021   COS_RULE(TYPT1, MINUS_S(A), COS(A), cos(_._));
00022 
00023   // tan(-a) = - tan(a)
00024   TAN_RULE(TYPT1, MINUS_S(A), MINUS(TAN(A)), -tan(_._));
00025     
00026   // sin(x) * x = x * sin(x)
00027   PROD_RULE(TYPT1, SIN_S(A), A, PROD(A, SIN(A)), _2 * _1 );
00028 
00029   // cos(x) * x = x * cos(x)
00030   PROD_RULE(TYPT1, COS_S(A), A, PROD(A, COS(A)), _2 * _1 );
00031 
00032   // tan(x) * x = x * tan(x)
00033   PROD_RULE(TYPT1, TAN_S(A), A, PROD(A, TAN(A)), _2 * _1 );
00034 
00035   // sin(a) / cos(a) = tan(a)
00036   template<TYPT1, bool parametric = Parametric<A>::value> 
00037   struct SimplifySCRatio {
00038     typedef RATIO_S(SIN(A), COS(A)) type;
00039     COMBINE(SIN_S(A), COS_S(A), _1 / _2);
00040   };
00041   
00042   TEMPL(T1) struct SimplifySCRatio<A, false> {
00043     typedef TAN_S(A) type;
00044     COMBINE(SIN_S(A), COS_S(A), type(_1._));
00045   };
00046 
00047   TEMPL(T1) struct Ratio<SIN_S(A), COS_S(A)> : 
00048     public SimplifySCRatio<A> { };
00049 
00050   // sin(a) / tan(a) = cos(a)
00051   template<TYPT1, bool parametric = Parametric<A>::value> 
00052   struct SimplifySTRatio {
00053     typedef RATIO_S(SIN(A), TAN(A)) type;
00054     COMBINE(SIN_S(A), TAN_S(A), _1 / _2);
00055   };
00056   
00057   TEMPL(T1) struct SimplifySTRatio<A, false> {
00058     typedef COS_S(A) type;
00059     COMBINE(SIN_S(A), TAN_S(A), type(_1._));
00060   };
00061 
00062   TEMPL(T1) struct Ratio<SIN_S(A), TAN_S(A)> : 
00063     public SimplifySTRatio<A> { };
00064   
00065   // cos(a) * tan(a) = sin(a)
00066   template<TYPT1, bool parametric = Parametric<A>::value> 
00067   struct SimplifySTProduct {
00068     typedef PROD(COS(A), TAN(A)) type;
00069     COMBINE(COS_S(A), TAN_S(A), _1 * _2);
00070   };
00071   
00072   TEMPL(T1) struct SimplifySTProduct<A, false> {
00073     typedef SIN(A) type;
00074     COMBINE(COS_S(A), TAN_S(A), sin(_1._));
00075   };
00076 
00077   TEMPL(T1) struct Product<COS_S(A), TAN_S(A)> :
00078     public SimplifySTProduct<A> { };
00079 
00080   // cos(a) * sin(a) => sin(a) * cos(a)
00081   TEMPL(T1) struct Product<COS_S(A), SIN_S(A)> {
00082     typedef PROD(SIN(A), COS(A)) type;
00083     COMBINE(COS_S(A), SIN_S(A), _2 * _1);
00084   };
00085   
00086   // cos(a)^b * tan(a)^b = sin(a)^b
00087   template<TYPT2,
00088     bool parametric = Parametric<A>::value || Parametric<B>::value>
00089   struct SimplifySTnProduct {
00090     typedef PROD(POWER(COS(A), B), POWER(TAN(A), B)) type;
00091     COMBINE(POWER_S(COS_S(A), B), POWER_S(TAN_S(A), B), _1 * _2);
00092   };
00093   
00094   TEMPL(T2) struct SimplifySTnProduct<A, B, false> {
00095     typedef POWER(SIN(A), B) type;
00096     COMBINE(POWER_S(COS_S(A), B), POWER_S(TAN_S(A), B),
00097             pow(sin(_1._1._), _1._2 ));
00098   };
00099   
00100   TEMPL(T2) struct Product<POWER_S(COS_S(A), B), 
00101     POWER_S(TAN_S(A), B)> :
00102     public SimplifySTnProduct<A, B> { };
00103   
00104   TEMPL(N1T1) struct Product<POWER_S(COS_S(A), NUM(n)), 
00105     POWER_S(TAN_S(A), NUM(n))> :
00106     public SimplifySTnProduct<A, NUM(n)> { };
00107   
00108   // n cos(a)^2 + m sin(a)^2 = min(n, m) + 
00109   //        (n - min(n, m)) cos(a)^2 + (m - min(n, m)) sin(a)^2
00110   template<TYPN2T1, bool parametric = Parametric<A>::value>
00111   struct SimpifyS2C2Sum {
00112     typedef SUM(PROD(NUM(n), SIN2(A)), 
00113                 PROD(NUM(m), COS2(A))) type;
00114     COMBINE(PROD(NUM(n), SIN2(A)), 
00115             PROD(NUM(m), COS2(A)), _1 + _2);
00116   };
00117   
00118   TEMPL(N2T1) struct SimpifyS2C2Sum<n, m, A, false> {
00119     static const int p = ::boost::mpl::if_c<(n <m), 
00120       ::boost::mpl::int_<n>, ::boost::mpl::int_<m> >::type::value;
00121     typedef SUM(SUM(PROD(NUM(n - p), SIN2(A)), 
00122                     PROD(NUM(m - p), COS2(A))), NUM(p)) type;
00123     COMBINE(PROD(NUM(n), SIN2(A)), 
00124             PROD(NUM(m), COS2(A)), (num<n - p>() * _1._2 + 
00125                                     num<m - p>() * _2._2) + num<p>());
00126   };
00127   
00128   TEMPL(T1) struct Sum<POWER_S(SIN_S(A), NUM(2)), 
00129     POWER_S(COS_S(A), NUM(2))> :
00130     public SimpifyS2C2Sum<1, 1, A> { };
00131   
00132   TEMPL(T1) struct Sum<POWER_S(COS_S(A), NUM(2)), 
00133     POWER_S(SIN_S(A), NUM(2))> {
00134     typedef SUM(SIN2(A), COS2(A)) type;
00135       inline static type combine(const COS2(A) & _1, const SIN2(A) & _2)
00136       { return Sum<SIN2(A), COS2(A)>::combine(_2, _1); }
00137   };
00138   
00139   TEMPL(N2T1) struct Sum<PROD_S(NUM(n), POWER_S(SIN_S(A), NUM(2))), 
00140     PROD_S(NUM(m), POWER_S(COS_S(A), NUM(2)))> :
00141     public SimpifyS2C2Sum<n, m, A> { };
00142   
00143   TEMPL(N2T1) struct Sum<PROD_S(NUM(m), POWER_S(COS_S(A), NUM(2))), 
00144     PROD_S(NUM(n), POWER_S(SIN_S(A), NUM(2)))> {
00145     typedef SUM(PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A))) type;
00146       inline static type combine(const PROD(NUM(m), COS2(A))& _1, 
00147                                   const PROD(NUM(n), SIN2(A))& _2)
00148         { return Sum<PROD(NUM(n), SIN2(A)), PROD(NUM(m), COS2(A))>::combine(_2, _1); }
00149   };
00150 
00151 }
00152 
00153 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
00154 
00155 #endif