CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/PhysicsTools/Utilities/interface/Derivative.h

Go to the documentation of this file.
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   // dx / dx = 1 
00026   DERIV_RULE(TYPX, X, NUM(1), num<1>());
00027 
00028   // d exp(x) / dx = exp(x)
00029   DERIV_RULE(TYPXT1, EXP_S(A), PROD(EXP(A), DERIV(X, A)), _ * derivative<X>(_._));
00030   
00031   // d log(x) / dx = 1 / x
00032   DERIV_RULE(TYPXT1, LOG_S(A), PROD(RATIO(NUM(1), A), DERIV(X, A)),
00033              (num<1>() / _._) * derivative<X>(_._));
00034   
00035   // d abs(x) / dx = sgn(x)
00036   DERIV_RULE(TYPXT1, ABS_S(A), PROD(SGN(A), DERIV(X, A)),
00037              sgn(_._) * derivative<X>(_._));
00038 
00039   // d sin(x) / dx = cos(x)
00040   DERIV_RULE(TYPXT1, SIN_S(A), PROD(COS(A), DERIV(X, A)),
00041              cos(_._) * derivative<X>(_._));
00042 
00043   // d cos(x) / dx = - sin(x)
00044   DERIV_RULE(TYPXT1, COS_S(A), MINUS(PROD(SIN(A), DERIV(X, A))),
00045              - (sin(_._) * derivative<X>(_._)));
00046 
00047   // d tan(x) / dx = 1 / cos(x)^2
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   // d/dx (f + g) = d/dx f + d/dx g
00053   DERIV_RULE(TYPXT2, SUM_S(A, B), SUM(DERIV(X, A), DERIV(X, B)),
00054              derivative<X>(_._1) + derivative<X>(_._2));
00055   
00056   // d/dx (-f) = - d/dx f
00057   DERIV_RULE(TYPXT1, MINUS_S(A), MINUS(DERIV(X, A)),
00058              - derivative<X>(_._));
00059 
00060   // d/dx (f * g) =  d/dx f * g + f * d/dx g
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   // d/dx (f / g) =  (d/dx f * g - f * d/dx g) / g^2
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   // d/dx f ^ n  = n f ^ (n - 1) d/dx f
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   // d/dx f ^ n/m  = n/m f ^ (n/m - 1) d/dx f
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   // d sqrt(x) / dx =  1/2 1/sqrt(x)
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