38 ClassImp(RooBrentRootFinder);
45 RooBrentRootFinder::RooBrentRootFinder(
const RooAbsFunc&
function) :
46 RooAbsRootFinder(function),
47 _tol(2.2204460492503131e-16)
59 Bool_t RooBrentRootFinder::findRoot(Double_t &result, Double_t xlo, Double_t xhi, Double_t value)
const
61 _function->saveXVec() ;
63 Double_t a(xlo),b(xhi);
64 Double_t fa= (*_function)(&a) - value;
65 Double_t fb= (*_function)(&b) - value;
67 oocxcoutD((TObject*)0,Eval) <<
"RooBrentRootFinder::findRoot(" << _function->getName() <<
"): initial interval does not bracket a root: ("
68 << a <<
"," << b <<
"), value = " << value <<
" f[xlo] = " << fa <<
" f[xhi] = " << fb << endl;
72 Bool_t ac_equal(kFALSE);
74 Double_t c(0),d(0),e(0);
75 for(Int_t iter= 0; iter <= MaxIterations; iter++) {
77 if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0)) {
86 if (fabs (fc) < fabs (fb)) {
96 Double_t tol = 0.5 * _tol * fabs(b);
97 Double_t m = 0.5 * (c - b);
100 if (fb == 0 || fabs(m) <= tol) {
103 _function->restoreXVec() ;
107 if (fabs (e) < tol || fabs (fa) <= fabs (fb)) {
115 Double_t s = fb / fa;
124 p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
125 q = (q - 1) * (r - 1) * (s - 1);
135 Double_t min1= 3 * m * q - fabs (tol * q);
136 Double_t min2= fabs (e * q);
137 if (2 * p < (min1 < min2 ? min1 : min2)) {
152 if (fabs (d) > tol) {
156 b += (m > 0 ? +tol : -tol);
158 fb= (*_function)(&b) - value;
162 oocoutE((TObject*)0,Eval) <<
"RooBrentRootFinder::findRoot(" << _function->getName() <<
"): maximum iterations exceeded." << endl;
165 _function->restoreXVec() ;