Problem retrieving Minuit2 correlation matrix

Hello,

I am using Minuit2 to minimize a custom chi2 function, but I can’t recover the correlation between parameters after the fit has converged.

My minimizer goes something like this:

int npars = 10;
double parStart[10] = { 0., ...., 0.}
auto chi2Function = [&](const Double_t *par) {
         ------------------------
         ------------------------
         ------------------------
         return chi2;
}

ROOT::Math::Functor fcn(chi2Function,npars);

ROOT::Fit::Fitter  fitter;

ROOT::Fit::FitConfig& fitConfig = fitter.Config();
fitter.SetFCN(fcn, parStart);

ROOT::Math::MinimizerOptions minOpt;
minOpt.SetMinimizerType("Minuit2");
minOpt.SetMinimizerAlgorithm("MIGRAD");
fitConfig.SetMinimizerOptions(minOpt);

bool  ok = fitter.FitFCN();

const ROOT::Fit::FitResult & result = fitter.Result();

TMatrixD correlationM(npars,npars);
result.GetCorrelationMatrix( correlationM );

This gives a correlation matrix of the correct size (npars x npars), but it contains only zeros (even if I use MINOS to estimate the errors).

  • Am I looking for the matrix in the wrong place?
  • Or do I need to tell Minuit2 something so that the matrix is computed/stored?

Thanks in advance for any help

1 Like

I guess @moneta can help you.

The code is not correct. I don’t think it compiles. It should be:

const ROOT::Fit::FitResult & result = fitter.Result();

TFitResult t_result(result); 
TMatrixDSym correlationM =  t_result.GetCorrelationMatrix();

Lorenzo

Thanks a lot! This did the trick.

Oddly enough the code I had before was not giving any error/warning.

Just one last thing.

If I do 2 minimizations consecutively, e.g.

fit with MIGRAD
if (coverged){
    fit with MINOS (to compute asymmetric errors)
}

or

fit with MIGRAD
if (coverged){
    fit with MIGRAD (changing e.g. the tolerance of the fit or some other parameter)
}

the correlation matrix is again only zeros. For some reason this information gets lost when fitting a second time. Is this behavior expected?

Hi,
This looks strange. Maybe the fit did not work correctly. Can you please post your code and possibly also the output log.
Thank you
Lorenzo

Certainly. I am attaching a code based on one of the ROOT fit tutorials (with minor additions). The output is shown bellow.

If you run the code just like it is, it fits only once using MIGRAD. This will correctly retrieve and show the correlation matrix. :

Processing fitCircle.C...

****************************************
Minimizer is Minuit2 / MIGRAD
MinFCN                    =      903.174
NDf                       =            0
Edm                       =  8.44652e-07
NCalls                    =           65
x0                        =   0.00667903   +/-   0.0141774
y0                        =   0.00535479   +/-   0.0141954
R                         =        3.995   +/-   0.0100048

3x3 matrix is as follows

     |      0    |      1    |      2    |
--------------------------------------------
   0 |          1    0.003836   -0.006109
   1 |   0.003836           1    -0.03041
   2 |  -0.006109    -0.03041           1

But if you uncomment lines 69,70,71, (which just re-fits using the very same function and conditions) the correlations are lost:

Processing fitCircle.C...

****************************************
Minimizer is Minuit2 / MIGRAD
MinFCN                    =      903.174
NDf                       =            0
Edm                       =  7.72164e-10
NCalls                    =           30
x0                        =   0.00667763   +/-   0.0141774
y0                        =    0.0053648   +/-   0.0141954
R                         =        3.995   +/-   0.0100048

3x3 matrix is as follows

     |      0    |      1    |      2    |
--------------------------------------------
   0 |          0           0           0
   1 |          0           0           0
   2 |          0           0           0

fitCircle.C (2.3 KB)

Hi,
Thank you for your code and log. It is clear, this is a bug when doing additional fits and I will fix it. As a work around, you can either print the matrix by calling FitResult::Print(std::cout, "V") or retrieve the
matrix index by index code using for example this code:

    int npar = result.NPar(); 
   TMatrixDSym correlationM(npar);
   for (int i = 0; i < npar; ++i) { 
      for (int j = 0; j < npar; ++j) {
         correlationM(i,j) = result.Correlation(i,j);
      }
   }
   correlationM.Print();

Sorry for this and thank you for reporting this problem

Lorenzo

1 Like

No problem, and thanks again for the suggestions!

Cheers,
Juan

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.