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
13 template <class Function>
\r
14 Bool_t EquationSolver<Function>::Brent(Function& theFunction) {
\r
15 const Double_t precision = 3.0e-8;
\r
17 // Check the interval before start
\r
18 if(fA > fB || TMath::Abs(fA-fB) <= fTolerance) {
\r
19 std::cerr << "EquationSolver::Brent: The interval must be properly set." << std::endl;
\r
22 Double_t fa = theFunction(fA);
\r
23 Double_t fb = theFunction(fB);
\r
25 std::cerr << "EquationSolver::Brent: The interval must include a root." << std::endl;
\r
32 //Double_t fd = 0.0;
\r
34 //Double_t fe = 0.0;
\r
36 for(Int_t i=0; i < fMaxIter; i++) {
\r
37 // Rename a,b,c and adjust bounding interval d
\r
44 if(TMath::Abs(fc) < TMath::Abs(fb)) {
\r
52 Double_t Tol1 = 2.0*precision*TMath::Abs(fB) + 0.5*fTolerance;
\r
53 Double_t xm = 0.5*(c-fB);
\r
54 if(TMath::Abs(xm) <= Tol1 || fb == 0.0) {
\r
58 // Inverse quadratic interpolation
\r
59 if(TMath::Abs(e) >= Tol1 && TMath::Abs(fa) > TMath::Abs(fb)) {
\r
70 p = s*(2.0*xm*q*(q-r)-(fB-fA)*(r-1.0));
\r
71 q = (q-1.0)*(r-1.0)*(s-1.0);
\r
76 Double_t min1 = 3.0*xm*q-TMath::Abs(Tol1*q);
\r
77 Double_t min2 = TMath::Abs(e*q);
\r
78 if (2.0*p < TMath::Min(min1,min2)) {
\r
90 // Bounds decreasing too slowly, use bisection
\r
94 // Move last guess to a
\r
97 if (TMath::Abs(d) > Tol1) fB += d;
\r
99 if (xm >= 0.0) fB += TMath::Abs(Tol1);
\r
100 else fB -= TMath::Abs(Tol1);
\r
102 fb = theFunction(fB);
\r
104 std::cerr << "EquationSolver::Brent: Number of iterations exceeded." << std::endl;
\r
108 template <class Function>
\r
109 void EquationSolver<Function>::SetIntervalLimits(const Double_t Limit1, const Double_t Limit2) {
\r
110 if(TMath::Abs(Limit1-Limit2) <= fTolerance) {
\r
111 std::cerr << "EquationSolver::SetIntervalLimits: Interval must be wider than tolerance." << std::endl;
\r
114 if(Limit1 < Limit2) {
\r