3 Nikolai Amelin, Ludmila Malinina, Timur Pocheptsov (C) JINR/Dubna
\r
4 amelin@sunhe.jinr.ru, malinina@sunhe.jinr.ru, pocheptsov@sunhe.jinr.ru
\r
8 //This equation solver class is taken from GEANT4 and modified!!
\r
11 template <class Function>
\r
12 Bool_t NAEquationSolver<Function>::Brent(Function& theFunction) {
\r
13 const Double_t precision = 3.0e-8;
\r
15 // Check the interval before start
\r
16 if(fA > fB || Abs(fA-fB) <= fTolerance) {
\r
17 std::cerr << "NAEquationSolver::Brent: The interval must be properly set." << std::endl;
\r
20 Double_t fa = theFunction(fA);
\r
21 Double_t fb = theFunction(fB);
\r
23 std::cerr << "NAEquationSolver::Brent: The interval must include a root." << std::endl;
\r
30 //Double_t fd = 0.0;
\r
32 //Double_t fe = 0.0;
\r
34 for(Int_t i=0; i < fMaxIter; i++) {
\r
35 // Rename a,b,c and adjust bounding interval d
\r
42 if(Abs(fc) < Abs(fb)) {
\r
50 Double_t Tol1 = 2.0*precision*Abs(fB) + 0.5*fTolerance;
\r
51 Double_t xm = 0.5*(c-fB);
\r
52 if(Abs(xm) <= Tol1 || fb == 0.0) {
\r
56 // Inverse quadratic interpolation
\r
57 if(Abs(e) >= Tol1 && Abs(fa) > Abs(fb)) {
\r
68 p = s*(2.0*xm*q*(q-r)-(fB-fA)*(r-1.0));
\r
69 q = (q-1.0)*(r-1.0)*(s-1.0);
\r
74 Double_t min1 = 3.0*xm*q-Abs(Tol1*q);
\r
75 Double_t min2 = Abs(e*q);
\r
76 if (2.0*p < Min(min1,min2)) {
\r
88 // Bounds decreasing too slowly, use bisection
\r
92 // Move last guess to a
\r
95 if (Abs(d) > Tol1) fB += d;
\r
97 if (xm >= 0.0) fB += Abs(Tol1);
\r
98 else fB -= Abs(Tol1);
\r
100 fb = theFunction(fB);
\r
102 std::cerr << "NAEquationSolver::Brent: Number of iterations exceeded." << std::endl;
\r
106 template <class Function>
\r
107 void NAEquationSolver<Function>::SetIntervalLimits(const Double_t Limit1, const Double_t Limit2) {
\r
108 if(Abs(Limit1-Limit2) <= fTolerance) {
\r
109 std::cerr << "NAEquationSolver::SetIntervalLimits: Interval must be wider than tolerance." << std::endl;
\r
112 if(Limit1 < Limit2) {
\r