00001 #ifndef PhysicsTools_Utilities_Derivative_h
00002 #define PhysicsTools_Utilities_Derivative_h
00003
00004 #include "PhysicsTools/Utilities/interface/Functions.h"
00005 #include "PhysicsTools/Utilities/interface/Fraction.h"
00006 #include <boost/type_traits.hpp>
00007
00008 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
00009
00010 namespace funct {
00011
00012 template<typename X, typename A>
00013 struct Derivative {
00014 typedef NUM(0) type;
00015 GET(A, num<0>());
00016 };
00017
00018 TEMPL(XT1) DERIV(X, A) derivative(const A& _) {
00019 return Derivative<X, A>::get(_);
00020 }
00021
00022 TEMPL(XT1) struct Independent :
00023 public ::boost::is_same<DERIV(X, A), NUM(0)> { };
00024
00025
00026 DERIV_RULE(TYPX, X, NUM(1), num<1>());
00027
00028
00029 DERIV_RULE(TYPXT1, EXP_S(A), PROD(EXP(A), DERIV(X, A)), _ * derivative<X>(_._));
00030
00031
00032 DERIV_RULE(TYPXT1, LOG_S(A), PROD(RATIO(NUM(1), A), DERIV(X, A)),
00033 (num<1>() / _._) * derivative<X>(_._));
00034
00035
00036 DERIV_RULE(TYPXT1, ABS_S(A), PROD(SGN(A), DERIV(X, A)),
00037 sgn(_._) * derivative<X>(_._));
00038
00039
00040 DERIV_RULE(TYPXT1, SIN_S(A), PROD(COS(A), DERIV(X, A)),
00041 cos(_._) * derivative<X>(_._));
00042
00043
00044 DERIV_RULE(TYPXT1, COS_S(A), MINUS(PROD(SIN(A), DERIV(X, A))),
00045 - (sin(_._) * derivative<X>(_._)));
00046
00047
00048 DERIV_RULE(TYPXT1, TAN_S(A), PROD(RATIO(NUM(1), SQUARE(COS(A))),
00049 DERIV(X, A)),
00050 (num<1>() / sqr(cos(_._))) * derivative<X>(_._));
00051
00052
00053 DERIV_RULE(TYPXT2, SUM_S(A, B), SUM(DERIV(X, A), DERIV(X, B)),
00054 derivative<X>(_._1) + derivative<X>(_._2));
00055
00056
00057 DERIV_RULE(TYPXT1, MINUS_S(A), MINUS(DERIV(X, A)),
00058 - derivative<X>(_._));
00059
00060
00061 DERIV_RULE(TYPXT2, PROD_S(A, B), SUM(PROD(DERIV(X, A), B),
00062 PROD(A, DERIV(X, B))),
00063 derivative<X>(_._1) * _._2 + _._1 * derivative<X>(_._2));
00064
00065
00066 DERIV_RULE(TYPXT2, RATIO_S(A, B),
00067 RATIO(DIFF(PROD(DERIV(X, A), B),
00068 PROD(A, DERIV(X, B))),
00069 SQUARE(B)),
00070 (derivative<X>(_._1) * _._2 -
00071 _._1 * derivative<X>(_._2)) / sqr(_._2));
00072
00073
00074 DERIV_RULE(TYPXN1T1, POWER_S(A, NUM(n)),
00075 PROD(PROD(NUM(n), POWER(A, NUM(n - 1))), DERIV(X, A)),
00076 _._2 * pow(_._1, num<n - 1>()) * derivative<X>(_._1));
00077
00078
00079 DERIV_RULE(TYPXN2T1, POWER_S(A, FRACT_S(n, m)),
00080 PROD(PROD(FRACT(n, m), POWER(A, FRACT(n - m, n))),
00081 DERIV(X, A)),
00082 _._2 * pow(_._1, fract<n - m, m>()) * derivative<X>(_._1));
00083
00084
00085 DERIV_RULE(TYPXT1, SQRT_S(A),
00086 PROD(PROD(FRACT(1, 2), RATIO(NUM(1), SQRT(A))),
00087 DERIV(X, A)),
00088 (fract<1, 2>() * (num<1>() / sqrt(_._))) *
00089 derivative<X>(_._));
00090 }
00091
00092 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
00093
00094 #endif