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.0lnL); // 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::CreateMinimizer(“Minuit2”, “Migrad”);
ROOT::Math::Minimizer *min=ROOT::Math::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();
}