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/Error.h"
00034 #include "Math/GSLRootFinderDeriv.h"
00035 #include "Math/GSLRootHelper.h"
00036 #include "GSLRootFdFSolver.h"
00037 #include "GSLFunctionWrapper.h"
00038
00039 #include "gsl/gsl_roots.h"
00040 #include "gsl/gsl_errno.h"
00041
00042 #include <iostream>
00043 #include <cmath>
00044
00045 namespace ROOT {
00046 namespace Math {
00047
00048
00049 GSLRootFinderDeriv::GSLRootFinderDeriv() :
00050 fFunction(0), fS(0),
00051 fRoot(0), fPrevRoot(0),
00052 fIter(0), fStatus(-1),
00053 fValidPoint(false)
00054 {
00055
00056 fFunction = new GSLFunctionDerivWrapper();
00057 }
00058
00059 GSLRootFinderDeriv::~GSLRootFinderDeriv()
00060 {
00061
00062 if (fFunction) delete fFunction;
00063 }
00064
00065 GSLRootFinderDeriv::GSLRootFinderDeriv(const GSLRootFinderDeriv &) : IRootFinderMethod()
00066 {
00067 }
00068
00069 GSLRootFinderDeriv & GSLRootFinderDeriv::operator = (const GSLRootFinderDeriv &rhs)
00070 {
00071
00072 if (this == &rhs) return *this;
00073
00074 return *this;
00075 }
00076
00077
00078
00079
00080 bool GSLRootFinderDeriv::SetFunction( GSLFuncPointer f, GSLFuncPointer df, GSLFdFPointer Fdf, void * p, double xstart) {
00081 fStatus = -1;
00082
00083 fRoot = xstart;
00084 fFunction->SetFuncPointer( f );
00085 fFunction->SetDerivPointer( df );
00086 fFunction->SetFdfPointer( Fdf );
00087 fFunction->SetParams( p );
00088 int status = gsl_root_fdfsolver_set( fS->Solver(), fFunction->GetFunc(), fRoot);
00089 if (status == GSL_SUCCESS)
00090 fValidPoint = true;
00091 else
00092 fValidPoint = false;
00093
00094 return fValidPoint;
00095
00096 }
00097
00098 void GSLRootFinderDeriv::SetSolver(GSLRootFdFSolver * s ) {
00099
00100 fS = s;
00101 }
00102
00103 void GSLRootFinderDeriv::FreeSolver( ) {
00104
00105 if (fS) delete fS;
00106 }
00107
00108 int GSLRootFinderDeriv::Iterate() {
00109
00110
00111 if (!fFunction->IsValid() ) {
00112 MATH_ERROR_MSG("GSLRootFinderDeriv::Iterate"," Function is not valid");
00113 return -1;
00114 }
00115 if (!fValidPoint ) {
00116 MATH_ERROR_MSG("GSLRootFinderDeriv::Iterate"," Estimated point is not valid");
00117 return -2;
00118 }
00119
00120
00121 int status = gsl_root_fdfsolver_iterate(fS->Solver());
00122
00123 fPrevRoot = fRoot;
00124 fRoot = gsl_root_fdfsolver_root(fS->Solver() );
00125 return status;
00126 }
00127
00128 double GSLRootFinderDeriv::Root() const {
00129
00130 return fRoot;
00131 }
00132
00133 const char * GSLRootFinderDeriv::Name() const {
00134
00135 return gsl_root_fdfsolver_name(fS->Solver() );
00136 }
00137
00138 bool GSLRootFinderDeriv::Solve (int maxIter, double absTol, double relTol)
00139 {
00140
00141 fStatus = -1;
00142 int iter = 0;
00143 int status = 0;
00144 do {
00145 iter++;
00146
00147 status = Iterate();
00148 if (status != GSL_SUCCESS) {
00149 MATH_ERROR_MSG("GSLRootFinderDeriv::Solve","error returned when performing an iteration");
00150 fStatus = status;
00151 return false;
00152 }
00153 status = GSLRootHelper::TestDelta(fRoot, fPrevRoot, absTol, relTol);
00154 if (status == GSL_SUCCESS) {
00155 fIter = iter;
00156 fStatus = status;
00157 return true;
00158 }
00159
00160
00161
00162 }
00163 while (status == GSL_CONTINUE && iter < maxIter);
00164
00165 if (status == GSL_CONTINUE) {
00166 double tol = std::abs(fRoot-fPrevRoot);
00167 MATH_INFO_MSGVAL("GSLRootFinderDeriv::Solve","exceeded max iterations, reached tolerance is not sufficient",tol);
00168 }
00169
00170 fStatus = status;
00171 return false;
00172 }
00173
00174
00175 }
00176 }