1 // @(#)root/mathcore:$Id$ 2 // Authors: L. Moneta, J.T. Offermann, E.G.P. Bos 2013-2018 3 // 4 /********************************************************************** 5 * * 6 * Copyright (c) 2013 , LCG ROOT MathLib Team * 7 * * 8 **********************************************************************/ 9 /* 10 * NumericalDerivator.h 11 * 12 * Original version created on: Aug 14, 2013 13 * Authors: L. Moneta, J. T. Offermann 14 * Modified version created on: Sep 27, 2017 15 * Author: E. G. P. Bos 16 */ 17 18 #ifndef ROOT_Minuit2_NumericalDerivator 19 #define ROOT_Minuit2_NumericalDerivator 20 21 #include <Math/IFunctionfwd.h> 22 23 #include <vector> 24 #include "Fit/ParameterSettings.h" 25 #include "Minuit2/SinParameterTransformation.h" 26 #include "Minuit2/SqrtUpParameterTransformation.h" 27 #include "Minuit2/SqrtLowParameterTransformation.h" 28 #include "Minuit2/MnMachinePrecision.h" 29 30 namespace ROOT { 31 namespace Minuit2 { 32 33 // Holds all necessary derivatives and associated numbers (per parameter) used in the NumericalDerivator class. 34 struct DerivatorElement { 35 double derivative; 36 double second_derivative; 37 double step_size; 38 }; 39 40 class NumericalDerivator { 41 public: 42 explicit NumericalDerivator(bool always_exactly_mimic_minuit2 = true); 43 NumericalDerivator(const NumericalDerivator &other); 44 NumericalDerivator(double step_tolerance, double grad_tolerance, unsigned int ncycles, double error_level, 45 bool always_exactly_mimic_minuit2 = true); 46 47 void SetupDifferentiate(const ROOT::Math::IBaseFunctionMultiDim *function, const double *cx, 48 const std::vector<ROOT::Fit::ParameterSettings> ¶meters); 49 std::vector<DerivatorElement> Differentiate(const ROOT::Math::IBaseFunctionMultiDim *function, const double *x, 50 const std::vector<ROOT::Fit::ParameterSettings> ¶meters, 51 const std::vector<DerivatorElement> &previous_gradient); 52 53 DerivatorElement PartialDerivative(const ROOT::Math::IBaseFunctionMultiDim *function, const double *x, 54 const std::vector<ROOT::Fit::ParameterSettings> ¶meters, 55 unsigned int i_component, DerivatorElement previous); 56 DerivatorElement FastPartialDerivative(const ROOT::Math::IBaseFunctionMultiDim *function, 57 const std::vector<ROOT::Fit::ParameterSettings> ¶meters, 58 unsigned int i_component, const DerivatorElement &previous); 59 DerivatorElement operator()(const ROOT::Math::IBaseFunctionMultiDim *function, const double *x, 60 const std::vector<ROOT::Fit::ParameterSettings> ¶meters, unsigned int i_component, 61 const DerivatorElement &previous); 62 GetValue()63 double GetValue() const { return fVal; } SetStepTolerance(double value)64 inline void SetStepTolerance(double value) { fStepTolerance = value; } SetGradTolerance(double value)65 inline void SetGradTolerance(double value) { fGradTolerance = value; } SetNCycles(unsigned int value)66 inline void SetNCycles(unsigned int value) { fNCycles = value; } SetErrorLevel(double value)67 inline void SetErrorLevel(double value) { fUp = value; } 68 69 double Int2ext(const ROOT::Fit::ParameterSettings ¶meter, double val) const; 70 double Ext2int(const ROOT::Fit::ParameterSettings ¶meter, double val) const; 71 double DInt2Ext(const ROOT::Fit::ParameterSettings ¶meter, double val) const; 72 73 void SetInitialGradient(const ROOT::Math::IBaseFunctionMultiDim *function, 74 const std::vector<ROOT::Fit::ParameterSettings> ¶meters, 75 std::vector<DerivatorElement> &gradient); 76 AlwaysExactlyMimicMinuit2()77 inline bool AlwaysExactlyMimicMinuit2() const { return fAlwaysExactlyMimicMinuit2; } SetAlwaysExactlyMimicMinuit2(bool flag)78 inline void SetAlwaysExactlyMimicMinuit2(bool flag) { fAlwaysExactlyMimicMinuit2 = flag; } 79 80 private: 81 double fStepTolerance = 0.5; 82 double fGradTolerance = 0.1; 83 double fUp = 1; 84 double fVal = 0; 85 86 std::vector<double> fVx; 87 std::vector<double> fVxExternal; 88 std::vector<double> fVxFValCache; 89 double fDfmin; 90 double fVrysml; 91 92 // MODIFIED: Minuit2 determines machine precision in a slightly different way than 93 // std::numeric_limits<double>::epsilon()). We go with the Minuit2 one. 94 ROOT::Minuit2::MnMachinePrecision fPrecision; 95 96 ROOT::Minuit2::SinParameterTransformation fDoubleLimTrafo; 97 ROOT::Minuit2::SqrtUpParameterTransformation fUpperLimTrafo; 98 ROOT::Minuit2::SqrtLowParameterTransformation fLowerLimTrafo; 99 100 unsigned int fNCycles = 2; 101 bool fAlwaysExactlyMimicMinuit2; 102 103 }; 104 105 std::ostream &operator<<(std::ostream &out, const DerivatorElement &value); 106 107 } // namespace Minuit2 108 } // namespace ROOT 109 110 #endif // ROOT_Minuit2_NumericalDerivator 111