If status=converged break

Hello,
Is there a way to break a for loop if the fitter status=converged, and if so, how is it coded? I have some code below, where hh is a TH1 object and ball is a TF1. How would I break the loop when status=converged?

for (int i=0; i<100; i++)
    {
    hh->Fit(&ball,"SL","");
    }

ROOT Version: 6.23/01
Platform: Not Provided
Compiler: Not Provided


The question is: β€œis there a way to know if a fit converged or not ?”. I am sure @moneta knows.

Hi,

you can check the status returned in FitResult, for example:

for (int i=0; i<100; i++) {
    auto result = hh->Fit(&ball,"SL","");
    if (result == 0) break;
 }

Lorenzo

2 Likes

Thank you moneta!

In hindsight to this post, the following was more what I was looking for:

int i = 1;
while(true)
{
    cout << i << endl;
    auto fitr = hh->Fit(&ball,"SL","");
    fitr->Print();
    i++;
    if(strncmp(gMinuit->fCstatu.Data(),"CONVERGED",9)==0)
    {
        break;
    }
}

Note that the above is valid only when using TMinuit and not Minuit2.
A more general solution is to use the return valued of FitResult::Status() or better what is returned by FitResult::IsValid(). The above lines should be then:

for (int i=0; i<100; i++) {
    auto result = hh->Fit(&ball,"SL","");
    if (result->IsValid() ) break;
 }

Note that In case of TMinuit when gMinuit->fCstatu="CONVERGED" , the return status is always zero and the FitResult is flagged as valid.
If the fit failed instead the status is equal to 4 when using TMinuit.
In case of Minuit2 you have different status values depending on the reason of fit failures.
See Minuit2Minimizer::Minimize().
In this case when the return status is 0 or 1, the fit can be considered a valid fit, while for status>1 the fit is invalid.

Lorenzo

1 Like