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
00018 SIN_RULE(TYPT1, MINUS_S(A), MINUS(SIN(A)), -sin(_._));
00019
00020
00021 COS_RULE(TYPT1, MINUS_S(A), COS(A), cos(_._));
00022
00023
00024 TAN_RULE(TYPT1, MINUS_S(A), MINUS(TAN(A)), -tan(_._));
00025
00026
00027 PROD_RULE(TYPT1, SIN_S(A), A, PROD(A, SIN(A)), _2 * _1 );
00028
00029
00030 PROD_RULE(TYPT1, COS_S(A), A, PROD(A, COS(A)), _2 * _1 );
00031
00032
00033 PROD_RULE(TYPT1, TAN_S(A), A, PROD(A, TAN(A)), _2 * _1 );
00034
00035
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
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
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
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
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
00109
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