00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Math/IFunction.h"
00033 #include "Math/GSLRootFinder.h"
00034 #include "Math/GSLRootHelper.h"
00035 #include "Math/Error.h"
00036
00037 #include "GSLRootFSolver.h"
00038 #include "GSLFunctionWrapper.h"
00039
00040 #include "gsl/gsl_roots.h"
00041 #include "gsl/gsl_errno.h"
00042 #include <cmath>
00043
00044
00045 namespace ROOT {
00046 namespace Math {
00047
00048
00049 GSLRootFinder::GSLRootFinder() :
00050 fFunction(0), fS(0),
00051 fRoot(0), fXlow(0), fXup(0),
00052 fIter(0), fStatus(-1),
00053 fValidInterval(false)
00054 {
00055
00056 fFunction = new GSLFunctionWrapper();
00057 }
00058
00059 GSLRootFinder::~GSLRootFinder()
00060 {
00061
00062 if (fFunction) delete fFunction;
00063 }
00064
00065 GSLRootFinder::GSLRootFinder(const GSLRootFinder &): IRootFinderMethod()
00066 {
00067 }
00068
00069 GSLRootFinder & GSLRootFinder::operator = (const GSLRootFinder &rhs)
00070 {
00071
00072 if (this == &rhs) return *this;
00073
00074 return *this;
00075 }
00076
00077 bool GSLRootFinder::SetFunction( GSLFuncPointer f, void * p, double xlow, double xup) {
00078
00079 fXlow = xlow;
00080 fXup = xup;
00081 fFunction->SetFuncPointer( f );
00082 fFunction->SetParams( p );
00083
00084 int status = gsl_root_fsolver_set( fS->Solver(), fFunction->GetFunc(), xlow, xup);
00085 if (status == GSL_SUCCESS)
00086 fValidInterval = true;
00087 else
00088 fValidInterval = false;
00089
00090 return fValidInterval;
00091 }
00092
00093 bool GSLRootFinder::SetFunction( const IGenFunction & f, double xlow, double xup) {
00094
00095 fStatus = -1;
00096 fXlow = xlow;
00097 fXup = xup;
00098 fFunction->SetFunction( f );
00099 int status = gsl_root_fsolver_set( fS->Solver(), fFunction->GetFunc(), xlow, xup);
00100 if (status == GSL_SUCCESS)
00101 fValidInterval = true;
00102 else
00103 fValidInterval = false;
00104
00105 return fValidInterval;
00106 }
00107
00108 void GSLRootFinder::SetSolver(GSLRootFSolver * s ) {
00109
00110 fS = s;
00111 }
00112
00113 void GSLRootFinder::FreeSolver( ) {
00114
00115 if (fS) delete fS;
00116 }
00117
00118 int GSLRootFinder::Iterate() {
00119
00120 int status = 0;
00121 if (!fFunction->IsValid() ) {
00122 MATH_ERROR_MSG("GSLRootFinder::Iterate"," Function is not valid");
00123 status = -1;
00124 return status;
00125 }
00126 if (!fValidInterval ) {
00127 MATH_ERROR_MSG("GSLRootFinder::Iterate"," Interval is not valid");
00128 status = -2;
00129 return status;
00130 }
00131
00132 status = gsl_root_fsolver_iterate(fS->Solver());
00133
00134
00135 fRoot = gsl_root_fsolver_root(fS->Solver() );
00136
00137 fXlow = gsl_root_fsolver_x_lower(fS->Solver() );
00138 fXup = gsl_root_fsolver_x_upper(fS->Solver() );
00139
00140
00141
00142
00143 return status;
00144 }
00145
00146 double GSLRootFinder::Root() const {
00147
00148 return fRoot;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 const char * GSLRootFinder::Name() const {
00160
00161 return gsl_root_fsolver_name(fS->Solver() );
00162 }
00163
00164 bool GSLRootFinder::Solve (int maxIter, double absTol, double relTol)
00165 {
00166
00167 fStatus = -1;
00168 int status = 0;
00169 int iter = 0;
00170 do {
00171 iter++;
00172 status = Iterate();
00173
00174 if (status != GSL_SUCCESS) {
00175 MATH_ERROR_MSG("GSLRootFinder::Solve","error returned when performing an iteration");
00176 fStatus = status;
00177 return false;
00178 }
00179 status = GSLRootHelper::TestInterval(fXlow, fXup, absTol, relTol);
00180 if (status == GSL_SUCCESS) {
00181 fIter = iter;
00182 fStatus = status;
00183 return true;
00184 }
00185 }
00186 while (status == GSL_CONTINUE && iter < maxIter);
00187 if (status == GSL_CONTINUE) {
00188 double tol = std::abs(fXup-fXlow);
00189 MATH_INFO_MSGVAL("GSLRootFinder::Solve","exceeded max iterations, reached tolerance is not sufficient",tol);
00190 }
00191 fStatus = status;
00192 return false;
00193 }
00194
00195
00196
00197
00198 }
00199 }