00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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"
00019
00020 #include <iostream>
00021 #include <cassert>
00022
00023 namespace ROOT {
00024
00025 namespace Math {
00026
00027
00028
00029
00030
00031 GSLSimAnMinimizer::GSLSimAnMinimizer( int ) :
00032 fDim(0),
00033 fOwnFunc(false),
00034 fObjFunc(0),
00035 fMinVal(0)
00036 {
00037
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
00053
00054 if (ivar > fValues.size() ) return false;
00055 if (ivar == fValues.size() ) {
00056 fValues.push_back(val);
00057 fNames.push_back(name);
00058
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
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
00102
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
00111
00112 if (ivar > fValues.size() ) return false;
00113 fValues[ivar] = val;
00114 return true;
00115 }
00116
00117 bool GSLSimAnMinimizer::SetVariableValues( const double * x) {
00118
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
00127
00128
00129 fObjFunc = &func;
00130 fDim = func.NDim();
00131 }
00132
00133 void GSLSimAnMinimizer::SetFunction(const ROOT::Math::IMultiGradFunction & func ) {
00134
00135
00136 SetFunction( static_cast<const ROOT::Math::IMultiGenFunction &>(func) );
00137 }
00138
00139
00140 bool GSLSimAnMinimizer::Minimize() {
00141
00142 int debugLevel = PrintLevel();
00143
00144 if (debugLevel >=1 ) std::cout <<"Minimize using GSLSimAnMinimizer " << std::endl;
00145
00146
00147
00148 for (unsigned int i = 0; i < fSteps.size() ; ++i)
00149 fSteps[i] *= 10;
00150
00151
00152 std::vector<double> xvar (fValues );
00153 std::vector<double> steps (fSteps);
00154
00155
00156
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
00164
00165 MinimTransformFunction * trFunc = 0;
00166 if (doTransform) {
00167
00168
00169
00170 trFunc = new MinimTransformFunction ( new MultiNumGradFunction( *fObjFunc), fVarTypes, fValues, fBounds );
00171
00172 trFunc->InvTransformation(&fValues.front(), &xvar[0]);
00173
00174
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;
00182 }
00183
00184 assert (xvar.size() == steps.size() );
00185
00186
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
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
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 }
00228
00229 }
00230