TF1::IsValid returns false for valid function

Hello,

I was trying to find a good way to determine if a TF1 is properly defined and thought I found what I need with TF1::IsValid.

Unfortunately either it is bugged, or I don’t understand the purpose of this method. It seems to returns false when using lambda functions even though TF1:SetParameter(s) or TF1:Draw returns perfectly valid results.

A simple example

   TF1* myf = TF1("myf", [](double* x, double* p){return p[0]*x[0]+p[1];}, -10, 10, 2);

   myf->SetParameters(1, 2);
   myf->Draw();                                <= This displays the expected result

   cout << myf->IsValid() << endl;   <= returns false ???

I am using ROOT 6.11/03

Thanks,
Alex

Did someone mistakenly write kFALSE in place of kTRUE for the functor case? The comment above it seems to imply that.

Bool_t TF1::IsValid() const
{
    if (fFormula) return fFormula->IsValid();
    if (fMethodCall) return fMethodCall->IsValid();
    // function built on compiled functors are always valid by definition
    // (checked at compiled time)
    if (fFunctor && fSave.empty()) return kFALSE;
    return kTRUE;
}

The following script indicates that TF1::IsValid returns false because fSave is empty. The question is what is the purpose of checking fSave.

{
   TF1* myf = new TF1("myf", [](double* x, double* p){return p[0]*x[0]+p[1];}, -10, 10, 2);

   myf->SetParameters(1, 2);
   myf->Draw();

   myf->Print();
   double *save;
   myf->GetSave(save);
   cout << "Save: " << save << endl;
   cout << "IsValid: " << (myf->IsValid() ? "True" : "False") << endl;
}

Output:

$ root test.C 
root [0] 
Processing test.C...
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
Compiled based function: myf  based on a functor object.  Ndim = 1, Npar = 2
Save: 0x0
IsValid: False
root [1]

Trying to force a save with the following led to a segmentation violation:

   myf->Save(-10, 10, 0, 1, 0, 1);

@moneta may have some thoughts…

Hi,

Yes, this is a bug, it should be

if (!fFunctor && fSave.empty()) return kFALSE;

because in this case the functor pointer is null and there is not a saved array for evaluating the function

I’ll fix this tomorrow. Thank you for finding this bug

Best Regards

Lorenzo

1 Like

Thanks!

Any idea why trying to use TF1::Save led to a segmentation violation?

No idea. I will look at it

Hi,

I cannot reproduce the crash. Which ROOT version are you using ?

Lorenzo

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