Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef PhysicsTools_Utilities_Derivative_h
0002 #define PhysicsTools_Utilities_Derivative_h
0003 
0004 #include "PhysicsTools/Utilities/interface/Functions.h"
0005 #include "PhysicsTools/Utilities/interface/Fraction.h"
0006 #include <type_traits>
0007 
0008 #include "PhysicsTools/Utilities/interface/Simplify_begin.h"
0009 
0010 namespace funct {
0011 
0012   template <typename X, typename A>
0013   struct Derivative {
0014     typedef NUM(0) type;
0015     GET(A, num<0>());
0016   };
0017 
0018   TEMPL(XT1) DERIV(X, A) derivative(const A& _) { return Derivative<X, A>::get(_); }
0019 
0020   TEMPL(XT1) struct Independent : public ::std::is_same<DERIV(X, A), NUM(0)> {};
0021 
0022   // dx / dx = 1
0023   DERIV_RULE(TYPX, X, NUM(1), num<1>());
0024 
0025   // d exp(x) / dx = exp(x)
0026   DERIV_RULE(TYPXT1, EXP_S(A), PROD(EXP(A), DERIV(X, A)), _* derivative<X>(_._));
0027 
0028   // d log(x) / dx = 1 / x
0029   DERIV_RULE(TYPXT1, LOG_S(A), PROD(RATIO(NUM(1), A), DERIV(X, A)), (num<1>() / _._) * derivative<X>(_._));
0030 
0031   // d abs(x) / dx = sgn(x)
0032   DERIV_RULE(TYPXT1, ABS_S(A), PROD(SGN(A), DERIV(X, A)), sgn(_._) * derivative<X>(_._));
0033 
0034   // d sin(x) / dx = cos(x)
0035   DERIV_RULE(TYPXT1, SIN_S(A), PROD(COS(A), DERIV(X, A)), cos(_._) * derivative<X>(_._));
0036 
0037   // d cos(x) / dx = - sin(x)
0038   DERIV_RULE(TYPXT1, COS_S(A), MINUS(PROD(SIN(A), DERIV(X, A))), -(sin(_._) * derivative<X>(_._)));
0039 
0040   // d tan(x) / dx = 1 / cos(x)^2
0041   DERIV_RULE(TYPXT1,
0042              TAN_S(A),
0043              PROD(RATIO(NUM(1), SQUARE(COS(A))), DERIV(X, A)),
0044              (num<1>() / sqr(cos(_._))) * derivative<X>(_._));
0045 
0046   // d/dx (f + g) = d/dx f + d/dx g
0047   DERIV_RULE(TYPXT2, SUM_S(A, B), SUM(DERIV(X, A), DERIV(X, B)), derivative<X>(_._1) + derivative<X>(_._2));
0048 
0049   // d/dx (-f) = - d/dx f
0050   DERIV_RULE(TYPXT1, MINUS_S(A), MINUS(DERIV(X, A)), -derivative<X>(_._));
0051 
0052   // d/dx (f * g) =  d/dx f * g + f * d/dx g
0053   DERIV_RULE(TYPXT2,
0054              PROD_S(A, B),
0055              SUM(PROD(DERIV(X, A), B), PROD(A, DERIV(X, B))),
0056              derivative<X>(_._1) * _._2 + _._1 * derivative<X>(_._2));
0057 
0058   // d/dx (f / g) =  (d/dx f * g - f * d/dx g) / g^2
0059   DERIV_RULE(TYPXT2,
0060              RATIO_S(A, B),
0061              RATIO(DIFF(PROD(DERIV(X, A), B), PROD(A, DERIV(X, B))), SQUARE(B)),
0062              (derivative<X>(_._1) * _._2 - _._1 * derivative<X>(_._2)) / sqr(_._2));
0063 
0064   // d/dx f ^ n  = n f ^ (n - 1) d/dx f
0065   DERIV_RULE(TYPXN1T1,
0066              POWER_S(A, NUM(n)),
0067              PROD(PROD(NUM(n), POWER(A, NUM(n - 1))), DERIV(X, A)),
0068              _._2* pow(_._1, num<n - 1>()) * derivative<X>(_._1));
0069 
0070   // d/dx f ^ n/m  = n/m f ^ (n/m - 1) d/dx f
0071   DERIV_RULE(TYPXN2T1,
0072              POWER_S(A, FRACT_S(n, m)),
0073              PROD(PROD(FRACT(n, m), POWER(A, FRACT(n - m, n))), DERIV(X, A)),
0074              _._2* pow(_._1, fract<n - m, m>()) * derivative<X>(_._1));
0075 
0076   // d sqrt(x) / dx =  1/2 1/sqrt(x)
0077   DERIV_RULE(TYPXT1,
0078              SQRT_S(A),
0079              PROD(PROD(FRACT(1, 2), RATIO(NUM(1), SQRT(A))), DERIV(X, A)),
0080              (fract<1, 2>() * (num<1>() / sqrt(_._))) * derivative<X>(_._));
0081 }  // namespace funct
0082 
0083 #include "PhysicsTools/Utilities/interface/Simplify_end.h"
0084 
0085 #endif