I have two function TF1 (f1 and f2) and I would like to create a new TF1 function (ftot) in order to use it in my fit.
Ftot = f1( f2(x) )
(I can’t modify neither f1 nor f2.)
How can I do this?
I have two function TF1 (f1 and f2) and I would like to create a new TF1 function (ftot) in order to use it in my fit.
Ftot = f1( f2(x) )
(I can’t modify neither f1 nor f2.)
How can I do this?
Did you try
new TF1("f3","f2(f1(x)");
?
Yes, it doesn’t work …
How did it fail? Did you correct the (unfortunately obvious type I had (missing the 1 at the end of TF1)? Did you replace f1 and f2 with the “name” (1st argument of the constructor) of the two functions? See also https://root.cern.ch/doc/master/classTF1.html for more details.
TF1 *ftot = new TF1("ftot","f(fsh(x)))");
----------------------------
The error is:
input_line_51:1:70: error: called object type 'TF1 *' is not a function or function pointer
Double_t TFormula____id5336273493103678123(Double_t *x){ return f(fsh(x[0]))) ; }
~~~^
Error in <TFormula::Eval>: Can't find TFormula____id5336273493103678123 function prototype with arguments Double_t*
Error in <TFormula::ProcessFormula>: Could not find f function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Could not find fsh function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Formula "f(fsh(x)))" is invalid !
Try with
TFormula *ftot = new TFormula("ftot","f(fsh(x)))");
TFormula *ftot = new TFormula(“ftot”,“f(fsh(x)))”);
doesn’t work
Here is a minimal not working example to clear up some confusion. It has always puzzled me as well, why this doesn’t work:
root [0] auto f1 = new TF1("f1", "2*x");
root [1] auto f2 = new TF1("f2", "x*x");
root [2] auto f = new TF1("f", "f1(f2(x))");
input_line_23:1:71: error: called object type 'TF1 *' is not a function or function pointer
Double_t TFormula____id12629671998992482178(Double_t *x){ return f1(f2(x[0])) ; }
~~^
Error in <TFormula::Eval>: Can't find TFormula____id12629671998992482178 function prototype with arguments Double_t*
Error in <TFormula::ProcessFormula>: Could not find f1 function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Could not find f2 function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Formula "f1(f2(x))" is invalid !
It is also not restricted to nesting, a simple addition already fails:
root [7] auto f4 = new TF1("f4", "f1(x) + f2(x)");
input_line_28:1:68: error: called object type 'TF1 *' is not a function or function pointer
Double_t TFormula____id10490377465922475681(Double_t *x){ return f1(x[0])+f2(x[0]) ; }
~~^
input_line_28:1:77: error: called object type 'TF1 *' is not a function or function pointer
Double_t TFormula____id10490377465922475681(Double_t *x){ return f1(x[0])+f2(x[0]) ; }
~~^
Error in <TFormula::Eval>: Can't find TFormula____id10490377465922475681 function prototype with arguments Double_t*
Error in <TFormula::ProcessFormula>: Could not find f1 function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Could not find f2 function with 1 argument(s)
Error in <TFormula::ProcessFormula>: Formula "f1(x)+f2(x)" is invalid !
In other words, why are TF1
objects not callable? I would have expected to be able to do e.g. f1(3.5)
. What does work is (*f1)(3.5)
, because we are using pointers.
So, a solution is not to use pointers:
root [15] auto g1 = TF1("g1", "2*x")
(TF1 &) Name: g1 Title: 2*x
root [16] auto g2 = TF1("g1", "x*x")
(TF1 &) Name: g1 Title: x*x
root [17] auto g = TF1("g", "g1(g2(x))")
(TF1 &) Name: g Title: g1(g2(x))
The real solution would be to get TF1 *
to be recognized as a function pointer, though.
Hi,
The formula of TF1 understands C++ syntax, so if you have previously defined a pointer to TF1 as f1 you then need to use (*f1)(x).
However the formula understands also other TF1 names, by replacing the formula name with its expression. This works partially for compositions. For example this works:
auto g_1 = new TF1("g1", "x*x");
auto g_2 = new TF1("g2", "2*g1")
auto g_3 = new TF1("g3","g1+g2")
but as you find out “g2(g1)” does not work.
In principle we should be able to implement this case in TFormula
Lorenzo
Double_t funTheoSchifted(Double_t *x, Double_t *par){
Double_t *fshPar;
Double_t *fPar;
fshPar = par;
fPar = &par[2];
Double_t y = fsh->EvalPar(x,fshPar);
Double_t sr = f->EvalPar(&y,fPar);
return sr;
}
[…]
TF1 *ftot = new TF1(“ftot”,funTheoSchifted,100,600,6);
in this way it works!
Yes, it would be a really nice new feature. Could you add it in your todo list for a next ROOT release?
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.