BrentRootFinder.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: BrentRootFinder.cxx 36905 2010-11-24 15:44:34Z moneta $
00002 // Authors: David Gonzalez Maline    01/2008 
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006 , LCG ROOT MathLib Team                         *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 #include "Math/BrentRootFinder.h"
00012 #include "Math/BrentMethods.h"
00013 #include <cmath>
00014 
00015 #ifndef ROOT_Math_Error
00016 #include "Math/Error.h"
00017 #endif
00018 
00019 namespace ROOT {
00020 namespace Math {
00021 
00022 
00023 static int gDefaultNpx = 100; // default nunmber of points used in the grid to bracked the root
00024 static int gDefaultNSearch = 10;  // nnumber of time the iteration (bracketing -Brent ) is repeted
00025 
00026    BrentRootFinder::BrentRootFinder() : fFunction(0),
00027                                         fLogScan(false), fNIter(0), 
00028                                         fNpx(0), fStatus(-1), 
00029                                         fXMin(0), fXMax(0), fRoot(0) 
00030 {
00031    // default constructor (number of points used to bracket value is set to 100)
00032    fNpx = gDefaultNpx; 
00033 }
00034 
00035 void BrentRootFinder::SetDefaultNpx(int n) { gDefaultNpx = n; }
00036 
00037 void BrentRootFinder::SetDefaultNSearch(int n) { gDefaultNSearch = n; }
00038 
00039 
00040 bool BrentRootFinder::SetFunction(const ROOT::Math::IGenFunction& f, double xlow, double xup)
00041 {
00042 // Set function to solve and the interval in where to look for the root. 
00043 
00044    fFunction = &f;
00045    // invalid previous status
00046    fStatus = -1; 
00047 
00048    if (xlow >= xup) 
00049    {
00050       double tmp = xlow;
00051       xlow = xup; 
00052       xup = tmp;
00053    }
00054    fXMin = xlow;
00055    fXMax = xup;
00056 
00057    return true;
00058 }
00059 
00060 const char* BrentRootFinder::Name() const
00061 {   return "BrentRootFinder";  }
00062 
00063 
00064 bool BrentRootFinder::Solve(int maxIter, double absTol, double relTol)
00065 {
00066   // Returns the X value corresponding to the function value fy for (xmin<x<xmax).
00067 
00068    if (!fFunction) { 
00069        MATH_ERROR_MSG("BrentRootFinder::Solve", "Function has not been set");
00070        return false;
00071    }
00072 
00073    if (fLogScan && fXMin <= 0) { 
00074       MATH_ERROR_MSG("BrentRootFinder::Solve", "xmin is < 0 and log scan is set - disable it");
00075       fLogScan = false; 
00076    }
00077 
00078 
00079    const double fy = 0; // To find the root
00080    fNIter = 0; 
00081    fStatus = -1; 
00082 
00083    double xmin = fXMin;
00084    double xmax = fXMax;
00085 
00086    int maxIter1 = gDefaultNSearch;  // external loop (number of search )
00087    int maxIter2 = maxIter;          // internal loop inside the Brent algorithm 
00088 
00089    int niter1 = 0;
00090    int niter2 = 0;
00091    bool ok = false; 
00092    while (!ok){
00093       if (niter1 > maxIter1){
00094          MATH_ERROR_MSG("BrentRootFinder::Solve", "Search didn't converge");
00095          fStatus = -2; 
00096          return false;
00097       }
00098       double x = BrentMethods::MinimStep(fFunction, 4, xmin, xmax, fy, fNpx,fLogScan);
00099       x = BrentMethods::MinimBrent(fFunction, 4, xmin, xmax, x, fy, ok, niter2, absTol, relTol, maxIter2);
00100       fNIter += niter2;  // count the total number of iterations
00101       niter1++;
00102       fRoot = x; 
00103    }
00104 
00105    fStatus = 0;
00106    return true;
00107 }
00108 
00109 } // namespace Math
00110 } // namespace ROOT

Generated on Tue Jul 5 14:33:22 2011 for ROOT_528-00b_version by  doxygen 1.5.1