GSLSimAnMinimizer.cxx

Go to the documentation of this file.
00001 // @(#)root/mathmore:$Id: GSLSimAnMinimizer.cxx 31763 2009-12-10 10:40:21Z moneta $
00002 // Author: L. Moneta Wed Dec 20 17:16:32 2006
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Implementation file for class GSLSimAnMinimizer
00012 
00013 #include "Math/GSLSimAnMinimizer.h"
00014 #include "Math/WrappedParamFunction.h"
00015 #include "Math/Error.h"
00016 
00017 #include "Math/MinimTransformFunction.h"
00018 #include "Math/MultiNumGradFunction.h"   // needed to use transformation function
00019 
00020 #include <iostream> 
00021 #include <cassert>
00022 
00023 namespace ROOT { 
00024 
00025    namespace Math { 
00026 
00027 
00028 
00029 // GSLSimAnMinimizer implementation
00030 
00031 GSLSimAnMinimizer::GSLSimAnMinimizer( int /* ROOT::Math::EGSLSimAnMinimizerType type */ ) : 
00032    fDim(0), 
00033    fOwnFunc(false),
00034    fObjFunc(0), 
00035    fMinVal(0)
00036 {
00037    // Constructor implementation : create GSLMultiFit wrapper object
00038 
00039    fValues.reserve(10); 
00040    fNames.reserve(10); 
00041    fSteps.reserve(10); 
00042 
00043    SetMaxIterations(100);
00044    SetPrintLevel(0);
00045 }
00046 
00047 GSLSimAnMinimizer::~GSLSimAnMinimizer () { 
00048    if ( fOwnFunc   && fObjFunc) delete fObjFunc;
00049 }
00050 
00051 bool GSLSimAnMinimizer::SetVariable(unsigned int ivar, const std::string & name, double val, double step) { 
00052    // set variable in minimizer - support only free variables 
00053    // no transformation implemented - so far
00054    if (ivar > fValues.size() ) return false; 
00055    if (ivar == fValues.size() ) { 
00056       fValues.push_back(val); 
00057       fNames.push_back(name);
00058       // step is the simmulated annealing scale
00059       fSteps.push_back( step ); 
00060       fVarTypes.push_back(kDefault); 
00061    }
00062    else { 
00063       fValues[ivar] = val; 
00064       fNames[ivar] = name;
00065       fSteps[ivar] = step; 
00066       fVarTypes[ivar] = kDefault; 
00067 
00068       // remove bounds if needed
00069       std::map<unsigned  int, std::pair<double, double> >::iterator iter = fBounds.find(ivar); 
00070       if ( iter !=  fBounds.end() ) fBounds.erase (iter); 
00071    }
00072    return true; 
00073 
00074 }
00075 
00076 bool GSLSimAnMinimizer::SetLowerLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower ) { 
00077    bool ret =  SetVariable(ivar, name, val, step); 
00078    if (!ret) return false; 
00079    fBounds[ivar] = std::make_pair( lower, lower);
00080    fVarTypes[ivar] = kLowBound; 
00081    return true;  
00082 }
00083 bool GSLSimAnMinimizer::SetUpperLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double upper) { 
00084    bool ret = SetVariable(ivar, name, val, step); 
00085    if (!ret) return false; 
00086    fBounds[ivar] = std::make_pair( upper, upper);
00087    fVarTypes[ivar] = kUpBound; 
00088    return true;  
00089 }
00090 bool GSLSimAnMinimizer::SetLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower, double upper ) { 
00091    bool ret = SetVariable(ivar, name, val, step); 
00092    if (!ret) return false; 
00093    fBounds[ivar] = std::make_pair( lower, upper);
00094    fVarTypes[ivar] = kBounds; 
00095    return true;  
00096 }
00097 
00098 
00099 
00100 bool GSLSimAnMinimizer::SetFixedVariable(unsigned int ivar, const std::string & name, double val) { 
00101    /// set fixed variable (override if minimizer supports them )
00102    // use zero step size 
00103    bool ret = SetVariable(ivar, name, val, 0.); 
00104    if (!ret) return false; 
00105    fVarTypes[ivar] = kFix; 
00106    return true;  
00107 }
00108 
00109 bool GSLSimAnMinimizer::SetVariableValue(unsigned int ivar, double val) { 
00110    // set variable value in minimizer 
00111    // no transformation implemented - so far
00112    if (ivar > fValues.size() ) return false; 
00113    fValues[ivar] = val; 
00114    return true; 
00115 }
00116 
00117 bool GSLSimAnMinimizer::SetVariableValues( const double * x) { 
00118    // set all variable values in minimizer 
00119    if (x == 0) return false; 
00120    std::copy(x,x+fValues.size(), fValues.begin() );
00121    return true; 
00122 }
00123 
00124       
00125 void GSLSimAnMinimizer::SetFunction(const ROOT::Math::IMultiGenFunction & func) { 
00126    // set the function to minimize
00127    
00128    // keep pointers to the chi2 function
00129    fObjFunc = &func; 
00130    fDim = func.NDim();
00131 }
00132 
00133 void GSLSimAnMinimizer::SetFunction(const ROOT::Math::IMultiGradFunction & func ) { 
00134    // set the function to minimize
00135    // use the other methods
00136    SetFunction( static_cast<const ROOT::Math::IMultiGenFunction &>(func) ); 
00137 }
00138 
00139 
00140 bool GSLSimAnMinimizer::Minimize() { 
00141    // set initial parameters of the minimizer
00142    int debugLevel = PrintLevel(); 
00143 
00144    if (debugLevel >=1 ) std::cout <<"Minimize using GSLSimAnMinimizer " << std::endl; 
00145 
00146 
00147    // adapt  the steps (use largers) 
00148    for (unsigned int i = 0; i < fSteps.size() ; ++i) 
00149       fSteps[i] *= 10; 
00150 
00151    // vector of internal values (copied by default) 
00152    std::vector<double> xvar (fValues );
00153    std::vector<double> steps (fSteps);
00154 
00155 
00156    // check if a transformation is needed 
00157    bool doTransform = (fBounds.size() > 0); 
00158    unsigned int ivar = 0; 
00159    while (!doTransform && ivar < fVarTypes.size() ) {
00160       doTransform = (fVarTypes[ivar++] != kDefault );
00161    }
00162 
00163    // if needed do transformation and wrap objective function in a new transformation function
00164    // and transform from external variables (and steps)   to internals one 
00165    MinimTransformFunction * trFunc  = 0; 
00166    if (doTransform)   {   
00167       // since objective function is gradient build a gradient function for the transformation
00168       // although gradient is not needed
00169 
00170       trFunc =  new MinimTransformFunction ( new MultiNumGradFunction( *fObjFunc), fVarTypes, fValues, fBounds ); 
00171 
00172       trFunc->InvTransformation(&fValues.front(), &xvar[0]); 
00173 
00174       // need to transform also  the steps 
00175       trFunc->InvStepTransformation(&fValues.front(), &fSteps.front(), &steps[0]); 
00176 
00177       xvar.resize( trFunc->NDim() );
00178       steps.resize( trFunc->NDim() ); 
00179 
00180       fObjFunc = trFunc; 
00181       fOwnFunc = true; // flag to indicate we need to delete the function
00182    }
00183 
00184    assert (xvar.size() == steps.size() );         
00185 
00186    // output vector 
00187    std::vector<double> xmin(xvar.size() ); 
00188   
00189    int iret = fSolver.Solve(*fObjFunc, &xvar.front(), &steps.front(), &xmin[0], (debugLevel > 1) );
00190 
00191    fMinVal = (*fObjFunc)(&xmin.front() );
00192 
00193    // get the result (transform if needed) 
00194    if (trFunc != 0) { 
00195       const double * xtrans = trFunc->Transformation(&xmin.front());  
00196       assert(fValues.size() == trFunc->NTot() ); 
00197       assert( trFunc->NTot() == NDim() );
00198       std::copy(xtrans, xtrans + trFunc->NTot(),  fValues.begin() ); 
00199    }
00200    else { 
00201       // case of no transformation applied 
00202       assert( fValues.size() == xmin.size() ); 
00203       std::copy(xmin.begin(), xmin.end(),  fValues.begin() ); 
00204    }
00205 
00206 
00207 
00208    if (debugLevel >=1 ) { 
00209       if (iret == 0)  
00210          std::cout << "GSLSimAnMinimizer: Minimum Found" << std::endl;  
00211       else 
00212          std::cout << "GSLSimAnMinimizer: Error in solving" << std::endl;  
00213 
00214       int pr = std::cout.precision(18);
00215       std::cout << "FVAL         = " << fMinVal << std::endl;
00216       std::cout.precision(pr);
00217       for (unsigned int i = 0; i < fDim; ++i) 
00218          std::cout << fNames[i] << "\t  = " << fValues[i] << std::endl; 
00219    }
00220 
00221 
00222    return ( iret == 0) ? true : false; 
00223 }
00224 
00225 
00226 
00227    } // end namespace Math
00228 
00229 } // end namespace ROOT
00230 

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