Minuit in ROOT 6.32.04

Good afternoon!

I have upgraded Root up to version 6.32.04, and realized, that behavior of Minuit has changed. An addressing gMinuit leads to the error

Error in <HandleInterpreterException>: Trying to dereference null pointer or trying to call routine taking non-null arguments
Execution of your code was aborted.
In file included from input_line_8:1:
/home/natalia/Examples/TestMinuit/TestMinuit-1/testMinuit_1.C:27:5: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
    gMinuit->mnemat(matrix0.GetMatrixArray(), 2);

After searching in Internet I understood, that now there is no global variable gMinuit, and it has to be initialized manually.

This is an example of code, which for the version 6.28 returns covariance matrix.
In the branch #if RVERSION == 632 a TMinuit variable is defined, there is no errors anymore, but the returned matrix is zero.

#define RVERSION 628 // ROOT Version: 6.28/04
//#define RVERSION 632 //ROOT Version: 6.32.04

void testMinuit_1(){
    int i;
    
    double x[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0};
    int n = (int)(sizeof(x) / sizeof(double));
    for (i = 0; i < n; i++)
        x[i] /= 3.0;
    
    double y[] = {86.25, 85.2, 73.4, 75.3, 71.4, 68.4, 73.35, 64.4, 83.15, 68.4, 50.65};
    
    double dy[] = {95.33, 94.35, 81.95, 83.77, 79.76, 76.63, 81.98, 72.54, 92.33, 76.69, 57.55};
    for (i = 0; i < n; i++)
        dy[i] -= y[i];
    
    TGraphErrors *gr = new TGraphErrors(n, x, y, NULL, dy);
    
    TF1 *f = new TF1("f", "[0] + [1]*x");
         f->SetRange(0.33, 3.5);
    
    TFitResultPtr fr = gr->Fit("f", "RS");
    
    TMatrixD matrix0(2, 2);
#if RVERSION == 628
    gMinuit->mnemat(matrix0.GetMatrixArray(), 2);
    matrix0.Print();
#endif
    
#if RVERSION == 632
    TMinuit *gM = new TMinuit();
    gM->mnemat(matrix0.GetMatrixArray(), 2);
    matrix0.Print();
#endif
    
#if RVERSION == 632
    delete gM;
#endif
    
    delete gr;
}

The question is, how to relate TMinuit variable to the needed fit?

Best regards,
Natalia

My system:

> lsb_release -d && uname -r
No LSB modules are available.
Description:    Debian GNU/Linux 12 (bookworm)
6.3.0-2-amd64

> g++ --version | head -n 1
g++ (Debian 12.2.0-14) 12.2.0

> root --version
ROOT Version: 6.32.04
Built for linuxx8664gcc on Aug 26 2024, 10:55:24
From heads/master@tags/v6-32-04

> root --version
ROOT Version: 6.28/04
Built for linuxx8664gcc on May 08 2023, 02:44:07
From tags/v6-28-04@v6-28-04
1 Like

Hi Natalia,

Let me add in the loop @jonas , our expert of statistics and minimisation.

Cheers,
D

The problem still exists…

There is a global variable gMinuit, but it is not initialized by default on ROOT 6.32

So what you should do is instead:

#if RVERSION == 632
    gMinuit = new TMinuit(2);
#endif
    gMinuit->mnemat(matrix0.GetMatrixArray(), 2);

In some cases, gMinuit is auto-initialized when calling TH1::Fit
If you look at Blaming root/tutorials/fit/fitcont.C at master · root-project/root · GitHub
and you add cout << gMinuit << endl;
you will see that it is 0 if you put that line before ->Fit, and nonzero otherwise.

Whether this was an intended change of behavior between versions, I don’t know. Couldn’t find it in the release notes.

Good afternoon!

Adding gMinuit = new TMinuit(2); hasn’t help.

After looking here, I have added

#include <TMinuit.h>
#include <TVirtualFitter.h>

void testMinuit_1(){
. . .

TVirtualFitter::SetDefaultFitter("Minuit");
TFitResultPtr fr = gr->Fit("f", "RS");

. . .
}

and it works.

Thank you!

Best regards,
Natalia