42 ClassImp(TMVA::RootFinder);
47 TMVA::RootFinder::RootFinder(TMVA::MethodBase *method ,
51 Double_t absTolerance )
52 : fRootMin( rootMin ),
54 fMaxIter( maxIterations ),
55 fAbsTol ( absTolerance ),
56 fLogger ( new MsgLogger(
"RootFinder") )
64 TMVA::RootFinder::~RootFinder(
void )
72 Double_t TMVA::RootFinder::Root( Double_t refValue )
74 Double_t a = fRootMin, b = fRootMax;
75 Double_t fa = fMethod->GetValueForRoot( a ) - refValue;
76 Double_t fb = fMethod->GetValueForRoot( b ) - refValue;
78 Log() << kWARNING <<
"<Root> initial interval w/o root: "
79 <<
"(a=" << a <<
", b=" << b <<
"),"
80 <<
" (Eff_a=" << fMethod->GetValueForRoot( a )
81 <<
", Eff_b=" << fMethod->GetValueForRoot( b ) <<
"), "
82 <<
"(fa=" << fa <<
", fb=" << fb <<
"), "
83 <<
"refValue = " << refValue << Endl;
87 Bool_t ac_equal(kFALSE);
89 Double_t c = 0, d = 0, e = 0;
90 for (Int_t iter= 0; iter <= fMaxIter; iter++) {
91 if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0)) {
99 if (TMath::Abs(fc) < TMath::Abs(fb)) {
102 fa = fb; fb = fc; fc = fa;
105 Double_t tol = 0.5 * 2.2204460492503131e-16 * TMath::Abs(b);
106 Double_t m = 0.5 * (c - b);
107 if (fb == 0 || TMath::Abs(m) <= tol || TMath::Abs(fb) < fAbsTol)
return b;
110 if (TMath::Abs (e) < tol || TMath::Abs (fa) <= TMath::Abs (fb)) { d = m; e = m; }
114 Double_t s = fb / fa;
116 if (ac_equal) { p = 2 * m * s; q = 1 - s; }
118 q = fa / fc; r = fb / fc;
119 p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
120 q = (q - 1) * (r - 1) * (s - 1);
126 Double_t min1 = 3 * m * q - TMath::Abs (tol * q);
127 Double_t min2 = TMath::Abs (e * q);
128 if (2 * p < (min1 < min2 ? min1 : min2)) {
132 else { d = m; e = m; }
137 if (TMath::Abs(d) > tol) b += d;
138 else b += (m > 0 ? +tol : -tol);
140 fb = fMethod->GetValueForRoot( b ) - refValue;
145 Log() << kWARNING <<
"<Root> maximum iterations (" << fMaxIter
146 <<
") reached before convergence" << Endl;