GSLRootFinder.cxx

Go to the documentation of this file.
00001 // @(#)root/mathmore:$Id: GSLRootFinder.cxx 32583 2010-03-12 09:57:42Z 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 // Implementation file for class GSLRootFinder
00026 // 
00027 // Created by: moneta  at Sun Nov 14 11:27:11 2004
00028 // 
00029 // Last update: Sun Nov 14 11:27:11 2004
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    // create function wrapper
00056    fFunction = new GSLFunctionWrapper(); 
00057 }
00058 
00059 GSLRootFinder::~GSLRootFinder() 
00060 {
00061    // delete function wrapper
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    // dummy operator=
00072    if (this == &rhs) return *this;  // time saving self-test
00073    
00074    return *this;
00075 }
00076 
00077 bool GSLRootFinder::SetFunction(  GSLFuncPointer f, void * p, double xlow, double xup) { 
00078    // set from GSL function 
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    // set from IGenFunction
00095    fStatus  = -1; // invalid the status 
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    // set type of solver
00110    fS = s; 
00111 }
00112 
00113 void GSLRootFinder::FreeSolver( ) { 
00114    // free resources
00115    if (fS) delete fS; 
00116 }
00117 
00118 int GSLRootFinder::Iterate() {
00119    // iterate  
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    // update Root 
00135    fRoot = gsl_root_fsolver_root(fS->Solver() );
00136    // update interval
00137    fXlow =  gsl_root_fsolver_x_lower(fS->Solver() ); 
00138    fXup =  gsl_root_fsolver_x_upper(fS->Solver() );
00139 
00140    //std::cout << "iterate .." << fRoot << " status " << status << " interval " 
00141    //          << fXlow << "  " << fXup << std::endl;
00142 
00143    return status;
00144 }
00145 
00146 double GSLRootFinder::Root() const { 
00147    // return cached value
00148    return fRoot;
00149 }
00150 /**
00151 double GSLRootFinder::XLower() const { 
00152    return fXlow; 
00153 }
00154 
00155 double GSLRootFinder::XUpper() const { 
00156    return fXup;
00157 }
00158 */
00159 const char * GSLRootFinder::Name() const {
00160    // get GSL name 
00161    return gsl_root_fsolver_name(fS->Solver() ); 
00162 }
00163 
00164 bool GSLRootFinder::Solve (int maxIter, double absTol, double relTol) 
00165 { 
00166    // find the roots by iterating
00167    fStatus = -1;
00168    int status = 0;
00169    int iter = 0; 
00170    do { 
00171       iter++; 
00172       status = Iterate();
00173       //std::cerr << "RF: iteration " << iter << " status = " << status << std::endl;
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 } // namespace Math
00199 } // namespace ROOT

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