51 GSLMinimizer::GSLMinimizer( ROOT::Math::EGSLMinimizerType type) :
57 fGSLMultiMin =
new GSLMultiMinimizer((ROOT::Math::EGSLMinimizerType) type);
60 int niter = ROOT::Math::MinimizerOptions::DefaultMaxIterations();
61 if (niter <=0 ) niter = 1000;
62 SetMaxIterations(niter);
63 SetPrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel());
66 GSLMinimizer::GSLMinimizer(
const char * type) : BasicMinimizer()
69 std::string algoname(type);
70 std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int(*)(int)) tolower );
72 ROOT::Math::EGSLMinimizerType algo = kVectorBFGS2;
74 if (algoname ==
"conjugatefr") algo = kConjugateFR;
75 if (algoname ==
"conjugatepr") algo = kConjugatePR;
76 if (algoname ==
"bfgs") algo = kVectorBFGS;
77 if (algoname ==
"bfgs2") algo = kVectorBFGS2;
78 if (algoname ==
"steepestdescent") algo = kSteepestDescent;
83 fGSLMultiMin =
new GSLMultiMinimizer(algo);
86 int niter = ROOT::Math::MinimizerOptions::DefaultMaxIterations();
87 if (niter <=0 ) niter = 1000;
88 SetMaxIterations(niter);
89 SetPrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel());
93 GSLMinimizer::~GSLMinimizer () {
94 assert(fGSLMultiMin != 0);
100 void GSLMinimizer::SetFunction(
const ROOT::Math::IMultiGenFunction & func) {
104 ROOT::Math::MultiNumGradFunction gradFunc(func);
108 BasicMinimizer::SetFunction(gradFunc);
112 unsigned int GSLMinimizer::NCalls()
const {
115 const ROOT::Math::MultiNumGradFunction * fnumgrad =
dynamic_cast<const ROOT::Math::MultiNumGradFunction *
>(ObjFunction());
116 if (fnumgrad)
return fnumgrad->NCalls();
117 const ROOT::Math::FitMethodGradFunction * ffitmethod =
dynamic_cast<const ROOT::Math::FitMethodGradFunction *
>(ObjFunction());
118 if (ffitmethod)
return ffitmethod->NCalls();
123 bool GSLMinimizer::Minimize() {
126 if (fGSLMultiMin == 0)
return false;
127 const ROOT::Math::IMultiGradFunction *
function = GradObjFunction();
129 MATH_ERROR_MSG(
"GSLMinimizer::Minimize",
"Function has not been set");
133 unsigned int npar = NPar();
134 unsigned int ndim = NDim();
135 if (npar == 0 || npar < NDim() ) {
136 MATH_ERROR_MSGVAL(
"GSLMinimizer::Minimize",
"Wrong number of parameters",npar);
140 MATH_WARN_MSGVAL(
"GSLMinimizer::Minimize",
"number of parameters larger than function dimension - ignore extra parameters",npar);
143 const double eps = std::numeric_limits<double>::epsilon();
145 std::vector<double> startValues;
146 std::vector<double> steps(StepSizes(), StepSizes()+npar);
148 MinimTransformFunction * trFunc = CreateTransformation(startValues);
152 trFunc->InvStepTransformation(X(), StepSizes(), &steps[0]);
153 steps.resize(trFunc->NDim());
158 MATH_INFO_MSG(
"GSLMinimizer::Minimize",
"There are no free parameter - just compute the function value");
159 double fval = (*function)((
double*)0);
160 SetFinalValues(&startValues[0]);
168 for (
unsigned int i = 0; i < steps.size(); ++i)
169 stepSize += steps[i]*steps[i];
170 stepSize = std::sqrt(stepSize);
171 if (stepSize < eps) {
172 MATH_ERROR_MSGVAL(
"GSLMinimizer::Minimize",
"Step size is too small",stepSize);
178 fGSLMultiMin->Set(*
function, &startValues.front(), stepSize, fLSTolerance );
181 int debugLevel = PrintLevel();
183 if (debugLevel >=1 ) std::cout <<
"Minimize using GSLMinimizer " << fGSLMultiMin->Name() << std::endl;
190 unsigned int iter = 0;
192 bool minFound =
false;
193 bool iterFailed =
false;
195 status = fGSLMultiMin->Iterate();
201 status = fGSLMultiMin->TestGradient( Tolerance() );
202 if (status == GSL_SUCCESS) {
206 if (debugLevel >=2) {
207 std::cout <<
"----------> Iteration " << std::setw(4) << iter;
208 int pr = std::cout.precision(18);
209 std::cout <<
" FVAL = " << fGSLMultiMin->Minimum() << std::endl;
210 std::cout.precision(pr);
211 if (debugLevel >=3) {
212 std::cout <<
" Parameter Values : ";
213 const double * xtmp = fGSLMultiMin->X();
214 std::cout << std::endl;
216 xtmp = trFunc->Transformation(xtmp);
218 for (
unsigned int i = 0; i < NDim(); ++i) {
219 std::cout <<
" " << VariableName(i) <<
" = " << xtmp[i];
223 std::cout << std::endl;
232 while (status == GSL_CONTINUE && iter < MaxIterations() );
236 double * x = fGSLMultiMin->X();
237 if (x == 0)
return false;
240 double minVal = fGSLMultiMin->Minimum();
247 if (debugLevel >=1 ) {
248 std::cout <<
"GSLMinimizer: Minimum Found" << std::endl;
249 int pr = std::cout.precision(18);
250 std::cout <<
"FVAL = " << MinValue() << std::endl;
251 std::cout.precision(pr);
253 std::cout <<
"Niterations = " << iter << std::endl;
254 unsigned int ncalls = NCalls();
255 if (ncalls) std::cout <<
"NCalls = " << ncalls << std::endl;
256 for (
unsigned int i = 0; i < NDim(); ++i)
257 std::cout << VariableName(i) <<
"\t = " << X()[i] << std::endl;
262 if (debugLevel >= -1 ) {
263 std::cout <<
"GSLMinimizer: Minimization did not converge" << std::endl;
265 if (status == GSL_ENOPROG)
266 std::cout <<
"\t Iteration is not making progress towards solution" << std::endl;
268 std::cout <<
"\t Iteration failed with status " << status << std::endl;
270 if (debugLevel >= 1) {
271 double * g = fGSLMultiMin->Gradient();
273 for (
unsigned int i = 0; i < NDim(); ++i) dg2 += g[i] * g[1];
274 std::cout <<
"Grad module is " << std::sqrt(dg2) << std::endl;
275 for (
unsigned int i = 0; i < NDim(); ++i)
276 std::cout << VariableName(i) <<
"\t = " << X()[i] << std::endl;
277 std::cout <<
"FVAL = " << MinValue() << std::endl;
279 std::cout <<
"Niterations = " << iter << std::endl;
288 const double * GSLMinimizer::MinGradient()
const {
290 return fGSLMultiMin->Gradient();