Home | News | Documentation | Download

Intersection of TGraph and TF1

Hello, I am trying to find the point of intersection between a TGraph and an analytic TF1. I have an example from Rene where he uses a C-style function to create a TF1 from a TGraph object, and I am trying to use this approach, but I am getting an error when trying to define the object to find a difference between the TF1 defined the normal way and the TF1 defined from the TGraph.

ROOT Version: 6.20/04

Here is a minimal example using a simple sin function:

using namespace std;

TGraph* trueStress;
double myfunc(double *x, double *){ return trueStress->Eval(x[0]);}

void minimalProblem(){

    //populate TGraph with a sin function
    Double_t x[100], y[100];
    Int_t m = 20;
    for (Int_t i=0;i<m;i++) {
	x[i] = i*0.1;
	y[i] = 10*sin(x[i]+0.2);
    }
    trueStress = new TGraph(m,x,y);
    trueStress->Draw();

    //simple TF1 of a line
    TF1* line = new TF1("line","10*x");
    gROOT->GetListOfFunctions()->Add(line);
    //verify that line and sin function intersect somewhere, want to find the point of intersection
    line->Draw("same");

    //create a TF1 from my TGraph using C style function (from Rene Brun example)
    TCanvas* c4 = new TCanvas("c4");
    TF1* f1 = new TF1("f1",myfunc,0,2);
    gROOT->GetListOfFunctions()->Add(f1);
    f1->Draw();
    
    //create new TF1 to find intersection of two other TF1s
    TF1* diff = new TF1("diff", Form("abs(%s-%s)",f1->GetName(),line->GetName()),0,0.2);
}

The errors I get are:

input_line_111:2:77: error: use of undeclared identifier 'f1'
Double_t TFormula____id5398377958029293329(Double_t *x){ return TMath::Abs({f1}-(10*x[0])) ; }
                                                                            ^
input_line_112:2:80: error: expected ')'
Double_t TFormula____id5398377958029293329(Double_t *x){ return TMath::Abs({f1}-(10*x[0])) ; }
                                                                               ^
input_line_112:2:75: note: to match this '('
Double_t TFormula____id5398377958029293329(Double_t *x){ return TMath::Abs({f1}-(10*x[0])) ; }
                                                                          ^
Error in <prepareMethod>: Can't compile function TFormula____id5398377958029293329 prototype with arguments Double_t*
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>: Formula "abs(f1-(10*x))" is invalid !

Thank you for any assistance!

The last line of your macro produces this error. It is equivalent to:

   auto diff = new TF1("diff", "abs(f1-line)",0,0.2);

Which also produces the same error. May be @moneta will know.

Hi,
The TF1 function f1 is based on a C++ function pointer myfunc.
It cannot then used to build another TF1 based on an expression.
See ROOT: TF1 Class Reference

Cheers

Lorenzo

1 Like

Ah, I was afraid that would be the answer.
Is there by chance another way to find an intersection point between a TGraph and an analytical TF1?

Thank you!

Hi,
You can use the example above but you need to use a lambda for creating the TF1 diff .
You can do as following:

auto diff = new TF1("diff",[&](double *x, double *p){ return std::abs(f1->EvalPar(x,p)-line->EvalPar(x,p)); },0,0.2, f1->GetNpar() );

Lorenzo

Lorenzo, thank you! I never would have figured that out.

This is not that important, but is there a reason ROOT crashes when I try to diff->Draw()?

 Generating stack trace...
 0x00007f88a8234d3b in <unknown function>
 0x00007f88961bb970 in TF1::EvalPar(double const*, double const*) + 0x1b0 from /home/jbouffar/root-6.20.04-install/lib/libHist.so
 0x00007f88961c46b2 in TF1::DoCreateHistogram(double, double, bool) + 0x512 from /home/jbouffar/root-6.20.04-install/lib/libHist.so
 0x00007f88961c3b98 in TF1::Paint(char const*) + 0x1e8 from /home/jbouffar/root-6.20.04-install/lib/libHist.so
 0x00007f8895a5b69b in TPad::PaintModified() + 0x23b from /home/jbouffar/root-6.20.04-install/lib/libGpad.so
 0x00007f8895a18986 in TCanvas::Update() + 0x136 from /home/jbouffar/root-6.20.04-install/lib/libGpad.so
 0x00007f88a222587c in <unknown> from /home/jbouffar/root-6.20.04-install/lib/libCling.so
 0x00007f88a222bc2a in <unknown> from /home/jbouffar/root-6.20.04-install/lib/libCling.so
 0x00007f88a222d120 in <unknown> from /home/jbouffar/root-6.20.04-install/lib/libCling.so
 0x00007f88a7de186f in TRint::Run(bool) + 0x1bf from /home/jbouffar/root-6.20.04-install/lib/libRint.so
 0x00007f88a8400a0c in <unknown> from /home/jbouffar/root-6.20.04-install/bin/root.exe
 0x00007f88a6cc1b97 in __libc_start_main + 0xe7 from /lib/x86_64-linux-gnu/libc.so.6
 0x00007f88a8400a6a in _start + 0x2a from /home/jbouffar/root-6.20.04-install/bin/root.exe
terminate called after throwing an instance of 'cling::InvalidDerefException'
  what():  Trying to access a pointer that points to an invalid memory address.

Hi,

You have to make sure that the objects referenced by the function in diff through the lambda do not disappear (are deleted) when drawing

Lorenzo

Thanks for update and quick reply, its work for me. really appreciate.

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