Cannot call by names the probability density functions obtained with TKDE

Dear ROOT experts,
I want to divide two probability density functions obtained with TKDE but I cannot call the functions by name. Here I post some C++ code but I have the same problem with pyROOT.
Consider the following snippet:

    TKDE *kde1 = new TKDE(n, &data1[0], xmin, xmax);
    TKDE *kde2 = new TKDE(n, &data2[0], xmin, xmax);
    TF1 *fKde1 = kde1->GetFunction(100, xmin, xmax);
    TF1 *fKde2 = kde2->GetFunction(100, xmin, xmax);

    fKde1->SetName("f1");
    fKde2->SetName("f2");

    TF1 *f1f2 = new TF1("f1f2", "f1/f2", xmin, xmax);
    f1f2->Draw();

This gives the error

input_line_10:2:56: error: use of undeclared identifier 'f1'
Double_t TFormula____id13717184231236088683(){ return {f1}/{f2} ; }
                                                       ^
input_line_11:2:56: error: use of undeclared identifier 'f1'
Double_t TFormula____id13717184231236088683(){ return {f1}/{f2} ; }
                                                       ^
Error in <prepareMethod>: Can't compile function TFormula____id13717184231236088683 prototype with arguments 
Error in <TFormula::InputFormulaIntoCling>: Error compiling formula expression in Cling
Error in <TFormula::ProcessFormula>: "f1" has not been matched in the formula expression
Error in <TFormula::ProcessFormula>: "f2" has not been matched in the formula expression
Error in <TFormula::ProcessFormula>: Formula "f1/f2" is invalid !

However,

    TF1 *g1 = new TF1("g1", "x*x+1", 0, 10);
    TF1 *g2 = new TF1("g2", "x*x+2", 0, 10);

    TF1 *g1g2 = new TF1("g1g2", "g1/g2", 0, 10);
    g1g2->Draw();

works as expected.

I noticed that in the TF1 returned by the TKDE class there is no TFormula (f1->GetFormula() is 0), is this related to my problem?

Thanks in advance,
Daniel

ROOT Version: 6.24/06
Platform: ubuntu 20.04
Compiler: gcc 10.2.0


@moneta could you have a look at this, please?

Hi,

Calling a TF1 by name to include in another formula as above is supported only for TF1 object based on Formula, not for generic TF1 object based on some C++ code. So, what you are seeing is expected.
The workaround solution is to combine the two TF1 using C++ code, for example using a lambda function as following:

TKDE *kde1 = new TKDE(n, &data1[0], xmin, xmax);
TKDE *kde2 = new TKDE(n, &data2[0], xmin, xmax);
TF1 *fKde1 = kde1->GetFunction(100, xmin, xmax);
TF1 *fKde2 = kde2->GetFunction(100, xmin, xmax);

TF1 *f1f2 = new TF1("f1f2", [&](double *x, double *){ return fKde1->EvalPar(x,nullptr)/fKde2->EvalPar(x,nullptr); }, xmin, xmax,0);

Lorenzo

Hi Lorenzo,
thank you for the clear explanation, your workaround solves my problem.

Daniel

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