00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Minuit2/InitialGradientCalculator.h"
00011 #include "Minuit2/MnFcn.h"
00012 #include "Minuit2/MnUserTransformation.h"
00013 #include "Minuit2/MnMachinePrecision.h"
00014 #include "Minuit2/MinimumParameters.h"
00015 #include "Minuit2/FunctionGradient.h"
00016 #include "Minuit2/MnStrategy.h"
00017
00018 #include <math.h>
00019
00020
00021
00022 #if defined(DEBUG) || defined(WARNINGMSG)
00023 #include "Minuit2/MnPrint.h"
00024 #endif
00025
00026
00027
00028 namespace ROOT {
00029
00030 namespace Minuit2 {
00031
00032
00033 FunctionGradient InitialGradientCalculator::operator()(const MinimumParameters& par) const {
00034
00035
00036 assert(par.IsValid());
00037
00038 unsigned int n = Trafo().VariableParameters();
00039 assert(n == par.Vec().size());
00040
00041 #ifdef DEBUG
00042 std::cout << "Initial gradient calculator - params " << par.Vec() << std::endl;
00043 #endif
00044
00045 MnAlgebraicVector gr(n), gr2(n), gst(n);
00046
00047 for(unsigned int i = 0; i < n; i++) {
00048 unsigned int exOfIn = Trafo().ExtOfInt(i);
00049
00050 double var = par.Vec()(i);
00051 double werr = Trafo().Parameter(exOfIn).Error();
00052 double sav = Trafo().Int2ext(i, var);
00053 double sav2 = sav + werr;
00054 if(Trafo().Parameter(exOfIn).HasLimits()) {
00055 if(Trafo().Parameter(exOfIn).HasUpperLimit() &&
00056 sav2 > Trafo().Parameter(exOfIn).UpperLimit())
00057 sav2 = Trafo().Parameter(exOfIn).UpperLimit();
00058 }
00059 double var2 = Trafo().Ext2int(exOfIn, sav2);
00060 double vplu = var2 - var;
00061 sav2 = sav - werr;
00062 if(Trafo().Parameter(exOfIn).HasLimits()) {
00063 if(Trafo().Parameter(exOfIn).HasLowerLimit() &&
00064 sav2 < Trafo().Parameter(exOfIn).LowerLimit())
00065 sav2 = Trafo().Parameter(exOfIn).LowerLimit();
00066 }
00067 var2 = Trafo().Ext2int(exOfIn, sav2);
00068 double vmin = var2 - var;
00069 double gsmin = 8.*Precision().Eps2()*(fabs(var) + Precision().Eps2());
00070
00071 double dirin = std::max(0.5*(fabs(vplu) + fabs(vmin)), gsmin );
00072 double g2 = 2.0*fFcn.ErrorDef()/(dirin*dirin);
00073 double gstep = std::max(gsmin, 0.1*dirin);
00074 double grd = g2*dirin;
00075 if(Trafo().Parameter(exOfIn).HasLimits()) {
00076 if(gstep > 0.5) gstep = 0.5;
00077 }
00078 gr(i) = grd;
00079 gr2(i) = g2;
00080 gst(i) = gstep;
00081 }
00082
00083 return FunctionGradient(gr, gr2, gst);
00084 }
00085
00086 FunctionGradient InitialGradientCalculator::operator()(const MinimumParameters& par, const FunctionGradient&) const {
00087
00088 return (*this)(par);
00089 }
00090
00091 const MnMachinePrecision& InitialGradientCalculator::Precision() const {
00092
00093 return fTransformation.Precision();
00094 }
00095
00096 unsigned int InitialGradientCalculator::Ncycle() const {
00097
00098 return Strategy().GradientNCycles();
00099 }
00100
00101 double InitialGradientCalculator::StepTolerance() const {
00102
00103 return Strategy().GradientStepTolerance();
00104 }
00105
00106 double InitialGradientCalculator::GradTolerance() const {
00107
00108 return Strategy().GradientTolerance();
00109 }
00110
00111
00112 }
00113
00114 }