# NumericalMinimization.C

Hello!

I am a student trying to understand the wonderful tutorial macro NumericalMinimization.C: I have a few questions, which I put in bold below (I have tried to research these online but haven’t found explanation beyond the macro itself…)

// Example on how to use the new Minimizer class in ROOT
// Show usage with all the possible minimizers.
// Minimize the Rosenbrock function (a 2D -function)
// This example is described also in
// root.cern.ch/drupal/content/nume … idim_minim
// input : minimizer name + algorithm name
// randomSeed: = <0 : fixed value: 0 random with seed 0; >0 random with given seed What does this parameter do?
//
//Author: L. Moneta Dec 2010

#include “Math/Minimizer.h”
#include “Math/Factory.h”
#include “Math/Functor.h”
#include “TRandom2.h”
#include “TError.h”
#include

double RosenBrock(const double xx )
{
const Double_t x = xx;
const Double_t y = xx;
const Double_t tmp1 = y-x
x;
const Double_t tmp2 = 1-x;
return 100tmp1tmp1+tmp2*tmp2;
}

int NumericalMinimization(const char * minName = “Minuit2”,
const char algoName = “” ,
int randomSeed = -1)
{
// create minimizer giving a name and a name (optionally) for the specific
// algorithm
// possible choices are:
// minName algoName
// Minuit2 Fumili2
// Fumili
// GSLMultiMin ConjugateFR, ConjugatePR, BFGS,
// BFGS2, SteepestDescent
// GSLMultiFit
// GSLSimAn
// Genetic
ROOT::Math::Minimizer
min =
ROOT::Math: :CreateMinimizer(minName, algoName);

// set tolerance , etc…
min->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2
min->SetMaxIterations(10000); // for GSL
min->SetTolerance(0.001);
min->SetPrintLevel(1);

// create funciton wrapper for minmizer
// a IMultiGenFunction type
ROOT::Math::Functor f(&RosenBrock,2);
double step = {0.01,0.01}; How was this double determined, and what does it do?
// starting point

double variable = { -1.,1.2}; How was this double determined, and what does it do?
if (randomSeed >= 0) {
TRandom2 r(randomSeed);
variable = r.Uniform(-20,20);
variable = r.Uniform(-20,20);
}

min->SetFunction(f);

// Set the free variables to be minimized!
min->SetVariable(0,“x”,variable, step);
min->SetVariable(1,“y”,variable, step);

// do the minimization
min->Minimize();

const double *xs = min->X();
std::cout << “Minimum: f(” << xs << “,” << xs << "): "
<< min->MinValue() << std::endl;

// expected minimum is 0
if ( min->MinValue() < 1.E-4 && f(xs) < 1.E-4)
std::cout << “Minimizer " << minName << " - " << algoName
<< " converged to the right minimum” << std::endl;
else {
std::cout << “Minimizer " << minName << " - " << algoName
<< " failed to converge !!!” << std::endl;
Error(“NumericalMinimization”,“fail to converge”);
}

return 0;
}

I have asked the author of the macro to complete the help. Note that this macro is on the web doc also:
root.cern.ch/doc/master/Numeric … on_8C.html

Wow, thank you very much!

Ain’t it obvious?

In this example macro, the minimizer uses two “free variables”, defined as:
// variable number 0, named “x”, initial value set to variable, initial step set to step
min->SetVariable(0,“x”,variable, step);
// variable number 1, named “y”, initial value set to variable, initial step set to step
min->SetVariable(1,“y”,variable, step);

How does one set “initial values” and “initial steps”?
It’s up to the user … the closer the “initial values” are to the real values in the minimum, the better for the minimizer and the “initial steps” should be small enough to make sense (e.g. they should be related to the expected errors of your “free variables”).
In general, if the “initial values” are far away from the real minimum, then the minimizer may fail to find the minimum and the “initial steps” are not that important at all (the minimizer will anyhow recalculate them when it runs, using derivatives of the minimized function).

So, in this particular case, the “user” decided to set:
double variable = { -1.,1.2};
double step = {0.01,0.01};

In some cases, the “initial values” are not that important (i.e. the minimizer will find the minimum regardless of the “starting point”). In this example macro, you can play with setting random values for the “starting point” (note: in this case, the previously set “fixed values” { -1.,1.2} are changed, of course), and see what happens (i.e. if it finds the minimum or not):
if (randomSeed >= 0) {
TRandom2 r(randomSeed);
variable = r.Uniform(-20,20);
variable = r.Uniform(-20,20);
}

See: ROOT::Math::Minimizer
See: TRandom2

So when the randomSeed parameter is greater than zero, the variables become randomized?

Also, the function I am hoping to minimize takes in two defined vectors along with the const double *xx:

double minfunc(const double *xx, const std::vector xpos, const std::vector zpos) { …}

I get the error message that:
In instantiation of ‘double ROOT::Math::FunctorHandler<ParentFunctor, Func>::DoEval(const double*) const [with ParentFunctor = ROOT::Math::Functor; Func = double ()(const double, std::vector, std::vector)]’:
VMM2.C:260:1: required from here
home/root/include/Math/Functor.h:116:21: error: too few arguments to function
return fFunc(x);

Is there any way that I can fix/adapt this header so I can put in these vectors, too?

For some explanations of “seed”, see the TRandom2::SetSeed (and the TRandom3::SetSeed and the TRandom::SetSeed) method descriptions.

In this example macro, if you use “randomSeed = 0” then the “initial values” of both “free variables” are “randomized” (well, hopefully, the minimizer will find the same minimum in any case).

The other question needs Lorenzo, I guess.

Thank you so much Pepe Le Pew. I appreciate so much you taking the time to explain to us students.

I have solved the parameter problem myself. Thank you!

1.Is there a way that I can put bounds on what my parameter values can be without randomizing them?
For example, in the macro how could I set the fit on x to only go from -5 to 5?

1. Once, I test my program and before the minimum is displayed this message is printed:
Minuit2Minimizer : Invalid Minimum - status = 2
FVAL = 1.76505e-08
Edm = 3.60266e-09
Nfcn = 42

What do these parameters FVAL Edm and Nfcn mean?

As this one is marked as “solved” it is better to open a new question

Okay, I did, thank you!