00001 // @(#)root/mathmore:$Id: RootFinder.h 33942 2010-06-16 13:12:17Z moneta $ 00002 // Authors: L. Moneta, A. Zsenei 08/2005 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT * 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU General Public License * 00010 * as published by the Free Software Foundation; either version 2 * 00011 * of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this library (see file COPYING); if not, write * 00020 * to the Free Software Foundation, Inc., 59 Temple Place, Suite * 00021 * 330, Boston, MA 02111-1307 USA, or contact the author. * 00022 * * 00023 **********************************************************************/ 00024 00025 // Header file for class RootFinder 00026 // 00027 // Created by: moneta at Sun Nov 14 16:59:55 2004 00028 // 00029 // Last update: Sun Nov 14 16:59:55 2004 00030 // 00031 #ifndef ROOT_Math_RootFinder 00032 #define ROOT_Math_RootFinder 00033 00034 00035 #ifndef ROOT_Math_IFunctionfwd 00036 #include "Math/IFunctionfwd.h" 00037 #endif 00038 00039 #ifndef ROOT_Math_IRootFinderMethod 00040 #include "Math/IRootFinderMethod.h" 00041 #endif 00042 00043 00044 /** 00045 @defgroup RootFinders One-dimensional Root-Finding algorithms 00046 Various implementation esists in MathCore and MathMore 00047 The user interacts with a proxy class ROOT::Math::RootFinder which creates behing 00048 the choosen algorithms which are implemented using the ROOT::Math::IRootFinderMethod interface 00049 00050 @ingroup NumAlgo 00051 */ 00052 00053 00054 namespace ROOT { 00055 namespace Math { 00056 00057 00058 //_____________________________________________________________________________________ 00059 /** 00060 User Class to find the Root of one dimensional functions. 00061 The GSL Methods are implemented in MathMore and they are loaded automatically 00062 via the plug-in manager 00063 00064 The possible types of Root-finding algorithms are: 00065 <ul> 00066 <li>Root Bracketing Algorithms which do not require function derivatives 00067 <ol> 00068 <li>RootFinder::kBRENT (default method implemented in MathCore) 00069 <li>RootFinder::kGSL_BISECTION 00070 <li>RootFinder::kGSL_FALSE_POS 00071 <li>RootFinder::kGSL_BRENT 00072 </ol> 00073 <li>Root Finding Algorithms using Derivatives 00074 <ol> 00075 <li>RootFinder::kGSL_NEWTON 00076 <li>RootFinder::kGSL_SECANT 00077 <li>RootFinder::kGSL_STEFFENSON 00078 </ol> 00079 </ul> 00080 00081 This class does not cupport copying 00082 00083 @ingroup RootFinders 00084 00085 */ 00086 00087 class RootFinder { 00088 00089 public: 00090 00091 enum EType { kBRENT, // Methods from MathCore 00092 kGSL_BISECTION, kGSL_FALSE_POS, kGSL_BRENT, // GSL Normal 00093 kGSL_NEWTON, kGSL_SECANT, kGSL_STEFFENSON // GSL Derivatives 00094 }; 00095 00096 /** 00097 Construct a Root-Finder algorithm 00098 */ 00099 RootFinder(RootFinder::EType type = RootFinder::kBRENT); 00100 virtual ~RootFinder(); 00101 00102 private: 00103 // usually copying is non trivial, so we make this unaccessible 00104 RootFinder(const RootFinder & ) {} 00105 RootFinder & operator = (const RootFinder & rhs) 00106 { 00107 if (this == &rhs) return *this; // time saving self-test 00108 return *this; 00109 } 00110 00111 public: 00112 00113 bool SetMethod(RootFinder::EType type = RootFinder::kBRENT); 00114 00115 /** 00116 Provide to the solver the function and the initial search interval [xlow, xup] 00117 for algorithms not using derivatives (bracketing algorithms) 00118 The templated function f must be of a type implementing the \a operator() method, 00119 <em> double operator() ( double x ) </em> 00120 Returns non zero if interval is not valid (i.e. does not contains a root) 00121 */ 00122 00123 bool SetFunction( const IGenFunction & f, double xlow, double xup) { 00124 return fSolver->SetFunction( f, xlow, xup); 00125 } 00126 00127 00128 /** 00129 Provide to the solver the function and an initial estimate of the root, 00130 for algorithms using derivatives. 00131 The templated function f must be of a type implementing the \a operator() 00132 and the \a Gradient() methods. 00133 <em> double operator() ( double x ) </em> 00134 Returns non zero if starting point is not valid 00135 */ 00136 00137 bool SetFunction( const IGradFunction & f, double xstart) { 00138 return fSolver->SetFunction( f, xstart); 00139 } 00140 00141 template<class Function, class Derivative> 00142 bool Solve(Function &f, Derivative &d, double start, 00143 int maxIter = 100, double absTol = 1E-8, double relTol = 1E-10); 00144 00145 template<class Function> 00146 bool Solve(Function &f, double min, double max, 00147 int maxIter = 100, double absTol = 1E-8, double relTol = 1E-10); 00148 00149 /** 00150 Compute the roots iterating until the estimate of the Root is within the required tolerance returning 00151 the iteration Status 00152 */ 00153 bool Solve( int maxIter = 100, double absTol = 1E-8, double relTol = 1E-10) { 00154 return fSolver->Solve( maxIter, absTol, relTol ); 00155 } 00156 00157 /** 00158 Return the number of iteration performed to find the Root. 00159 */ 00160 int Iterations() const { 00161 return fSolver->Iterations(); 00162 } 00163 00164 /** 00165 Perform a single iteration and return the Status 00166 */ 00167 int Iterate() { 00168 return fSolver->Iterate(); 00169 } 00170 00171 /** 00172 Return the current and latest estimate of the Root 00173 */ 00174 double Root() const { 00175 return fSolver->Root(); 00176 } 00177 00178 /** 00179 Return the status of the last estimate of the Root 00180 = 0 OK, not zero failure 00181 */ 00182 int Status() const { 00183 return fSolver->Status(); 00184 } 00185 00186 00187 /** 00188 Return the current and latest estimate of the lower value of the Root-finding interval (for bracketing algorithms) 00189 */ 00190 /* double XLower() const { */ 00191 /* return fSolver->XLower(); */ 00192 /* } */ 00193 00194 /** 00195 Return the current and latest estimate of the upper value of the Root-finding interval (for bracketing algorithms) 00196 */ 00197 /* double XUpper() const { */ 00198 /* return fSolver->XUpper(); */ 00199 /* } */ 00200 00201 /** 00202 Get Name of the Root-finding solver algorithm 00203 */ 00204 const char * Name() const { 00205 return fSolver->Name(); 00206 } 00207 00208 00209 protected: 00210 00211 00212 private: 00213 00214 IRootFinderMethod* fSolver; // type of algorithm to be used 00215 00216 00217 }; 00218 00219 } // namespace Math 00220 } // namespace ROOT 00221 00222 00223 #ifndef ROOT_Math_WrappedFunction 00224 #include "Math/WrappedFunction.h" 00225 #endif 00226 00227 #ifndef ROOT_Math_Functor 00228 #include "Math/Functor.h" 00229 #endif 00230 00231 template<class Function, class Derivative> 00232 bool ROOT::Math::RootFinder::Solve(Function &f, Derivative &d, double start, 00233 int maxIter, double absTol, double relTol) 00234 { 00235 if (!fSolver) return false; 00236 ROOT::Math::GradFunctor1D wf(f, d); 00237 bool ret = fSolver->SetFunction(wf, start); 00238 if (!ret) return false; 00239 return Solve(maxIter, absTol, relTol); 00240 } 00241 00242 template<class Function> 00243 bool ROOT::Math::RootFinder::Solve(Function &f, double min, double max, 00244 int maxIter, double absTol, double relTol) 00245 { 00246 if (!fSolver) return false; 00247 ROOT::Math::WrappedFunction<Function &> wf(f); 00248 bool ret = fSolver->SetFunction(wf, min, max); 00249 if (!ret) return false; 00250 return Solve(maxIter, absTol, relTol); 00251 } 00252 00253 #endif /* ROOT_Math_RootFinder */