MINUIT2 better than MINUIT?

Hello,

I am using ROOT 5.24/00 and now I am working to minimize a fuction with many parameters. To my surprise, I find that MINUIT2::Migrad method works much better than MINUIT::Migrad. Dealing with the sample data sample for 100 times of minimization, MINUIT2 finished the task within 2598.63s (CPU time), and it found the global minimum almost every time (99%). The MINUIT minimizer, on the other hand, spent 10926.39s for the same job and only succeeded in finding the global minimum for about 50 times among 100 minimization attempts.

I thought that MINUIT2 was just a C++ conversion of FORTRAN MINUIT, but my results tell it otherwise. Could someone tell me what causes such a difference? Are there any improvements that make MINUIT2 a much better fitter? Thank you!

Following is a substraction of my minimization code. I could provide more info if necessary.

//PWA is a class which contains the PDF to be used and info of the fit parameters
PWA *fptr=new PWA();

//This is the function to be minimized
Double_t LogLike(const Double_t par){
double x[1];
double lnL=0;
Int_t n=fptr->GetDataNumber();
for(int i=0;i<n;i++){
x[0]=i;
double pdf=fptr->PDF(x,par);
if(pdf > 0){
lnL += TMath::Log(pdf);
}
else {
cout<< “WARNING – pdf is negative!!!” << endl;
}
}
return (-2.0
lnL); // factor of -2 so minuit gets the errors right
}

int main(int argc, char **argv){
TStopwatch timer;

fptr->Initialize();

//Get number of parameters
const int npar = fptr->GetParaNumber();

ROOT::Math::Functor f(&LogLike,npar);

// ROOT::Math::Minimizer *min=ROOT::Math::factory::CreateMinimizer(“Minuit2”, “Migrad”);
ROOT::Math::Minimizer *min=ROOT::Math::factory::CreateMinimizer(“Minuit”, “Migrad”);

min->SetMaxFunctionCalls(1e10);
min->SetMaxIterations(1e10);
min->SetTolerance(1e-14);
min->SetFunction(f);

//Could someone gives a detailed explanation about the print level?
min->SetPrintLevel(1);

double par[npar];
double stepSize[npar];
double minVal[npar];
double maxVal[npar];
string parName[npar];

fptr->GetParameters(parName,par,stepSize,minVal,maxVal);

//Read data sample and get prepared for the fit
fptr->SetData();

timer.Start();
for(int ii=0;ii<100;ii++){

//Parameters and stepsizes are randomized before each fit
fptr->Randomize(0,par,stepSize);

for(int i=0;i<npar;i++)  min->SetLimitedVariable(i, parName[i].c_str(),par[i],stepSize[i],minVal[i],maxVal[i]);
min->Minimize();
fptr->OutputResults(ii);

}
timer.Stop();
double opttime=timer.CpuTime();
}

1 Like

Hello,
results should be comparable between the two since it is basically the same algorithm. I suspect the difference might due to the fact that you use a very small tolerance and Minuit2 contains a fix for it which is not present in Minuit.
However, to understand more, I would need the output log (obtained with
min->SetPrintLevel(3) ) for the same fit, where Minuit fails and Minuit2 converges.

Best Regards

Lorenzo

1 Like

Mr. Moneta,

Thank you for your reply. I have included detailed output logs of both fitters in the attachment as well as summaries of results, which were both get from 100 times of optimization using the same initial parameter values and step-sizes each time. Thank you for your help!

Best Regards,

Hongtao Yang

[quote=“moneta”]Hello,
results should be comparable between the two since it is basically the same algorithm. I suspect the difference might due to the fact that you use a very small tolerance and Minuit2 contains a fix for it which is not present in Minuit.
However, to understand more, I would need the output log (obtained with
min->SetPrintLevel(3) ) for the same fit, where Minuit fails and Minuit2 converges.

Best Regards

Lorenzo[/quote]
output.rar (329 KB)

Hello,
Thank you very much for your logs, they are useful.
The reason of the failure is due to the fact that Minuit seems to force more often than Minuit2 the call of Hesse
(full second derivative) calculation at the end of the minimization.
The reason for this is not fully clear to me.
The calculation of the Hessian then fails due to a second derivative = 0 for the parameter (26) and this explains all the failures you observe when running TMinuit.
Probably the dependency on this parameter is too weak and it could be fixed during the minimization.

However, if you are interested in error calculations you should compute the Hessian (call Hesse) at the end of th eminimization. In that case you should have then the same behavior (i.e. same failures) between Minuit and Minuit2.

Best Regards

Lorenzo