TF1 intersection

Is there any built in way to determine where two TF1’s intersect? I’ve been looking around and I can’t seem to find one. Thanks

see example below

TF1 *f1, *f2;
double finter(double *x, double*par) {
   return TMath::Abs(f1->EvalPar(x,par) - f2->EvalPar(x,par));
}
void fint() {
   f1 = new TF1("f1","1+2*x+0.2*x*x",0,10);
   f2 = new TF1("f2","6+3*x-0.3*x*x",0,10);
   f1->Draw();
   f2->Draw("same");
   TF1 *fint = new TF1("fint",finter,0,10,0);
   double xint = fint->GetMinimumX();
   fint->Draw("lsame");
   TMarker *m = new TMarker(xint,f1->Eval(xint),24);
   m->SetMarkerColor(kRed);
   m->SetMarkerSize(3);
   m->Draw();
   printf("xint=%g\n",xint);
}

Rene

thanks

Hello,
I’m new to root and I’m having a problem just about this.
I saw the posted macro just above and it works, of course, but I’m finding it difficult to use that example in a .cpp file which I must compile. To make you understand, I’m in a situation like the following:

I have my .cpp file

#include
#include “TROOT.h”
#include “TSystem.h”
#include “TF1.h”
#include "TMath.h"
using namespace std;

// Then I have a main in which I do various things, until I get to fit a graph and extract two different TF1
// functions which are the ones I want to find the intersection point of.

int main()
{

graph->Fit(“pol1”,"","",start_point1,end_point1) ;
TF1 *fit1=gr->GetFunction(“pol1”) ;

graph->Fit(“pol1”,"","",start_point2,end_pont2);
TF1 *fit2= gr->GetFunction(“pol1”);

//and until this point it’s ok because I can draw my functions (writing them in a .root file) and all is working.

The problem is that I tried in many ways to use the same method of the example above but couldn’t find any way to make it suit my case correctly and I’ve always got errors from the compiler or, if it compiled, then it crashed when executing it.

To be more precise, what I tried is :

#include
#include “TROOT.h”
#include “TSystem.h”
#include “TF1.h”
#include "TMath.h"
using namespace std;

TF1 *f1, *f2 ;
double finter (double *x,double *par) {
return TMath::Abs(f1->EvalPar(x,par) - f2->EvalPar(x,par)) ; }

// Then the main, as I’ve already explained
int main()
{

//until i got the two functions *fit1 and *fit2, then

TF1 *fint=new TF1(“fint”,finter,start,end,0)
//note: start and end are chosen so that the two TF1s intersecate themselves within

double xint = fit->GetMinimumX() ;
cout << xint << endl;
return 0;
}

In this way it compiles but when launching it I get the error:
Break segmentation violation
Segmentation fault (core dumped)

I also tried changing it a bit but couldn’t manage to find a code that works.

Hope you can help me,
Thank you very much.

Lorenzo

Could you post the shortest possible running script reproducing the problem?
When posting code please use the code mode

Rene

I found where was the problem cause now it works. Here it is:

#include <iostream>
#include "TROOT.h"
#include "TSystem.h"
#include "TMath.h"
#include "TF1.h"
using namespace std; 

TF1 *f1, *f2;
double finter(double *x, double *par) 
{
    return TMath::Abs(f1->EvalPar(x,par) - f2->EvalPar(x,par));
}

double fint(double start,double end) {                                
       TF1 *fint = new TF1("fint",finter,start,end,0);
       double xint = fint->GetMinimumX();
       return xint; 
}

int main ()
{
	f1=new TF1("f1","x^2 + 4",0,10);
	f2=new TF1("f2","x + 3",0,10);
	cout << "x_int = " << fint(0,8) << endl; 
}

I would be grateful for any suggestion and improvement.

Thanks,
Lorenzo

Your functions f1 and f2 do not intersect. The minimum of fint corresponds to the minimum distance between f1 and f2 at x=0.5

Rene

I hadn’t checked it because it was just an example, what I needed was a working code to use in another situation, but thank you.

Lorenzo

Note that the code that I posted and that you use is working correctly.
For intersecting functions it will report the intersecting point.
For non intersecting functions it will return the point of closest approach between the 2 functions.

Rene

hi i’m a new to root and the programming itself…

and i also need the intersection point of two functions

in my case the functions intersect twice with each other…

the solution from mr. brun hepled already a little bit but it only gives me the last intersection point
if i draw the function in the range of the first intersection piont it gives me this one out too…

is there a way in which i can store both intersection points and call them later ?

i tried already but i did not get ir to work my way

any suggestion would be helpful

best regards Sebastian

could you post a short running script showing what you try to achieve (or would like to achieve) ?

Rene

ok so here is my problem

TF1 *fitebl, *fitsens;


double finter(double *x, double*par) {
  return TMath::Abs(fitsens->EvalPar(x,par) - fitebl->EvalPar(x,par));
}


void new_file(){
  
 TF1 *fint1[2];        
 double xint1[2];    
 TMarker *m[2];

 TCanvas *c = new TCanvas("c"," 2nd FERMICAT dec >-32 & Redshift  0.028 - 0.2756",200,10,1200,800);
 c->SetFillColor(0);
 c->SetGrid(1,1);
 

 
 fitebl = new TF1("EBL_fit","pol6",1.9,3.6);
 fitebl->SetParameters(-2.5413 ,41.9401 , -49.1368  , 29.758 , -9.81396  , 1.66925  , -0.114667);
 

 fitsens = new TF1("SENS_fit","pol6",1.9,3.6);
 fitsens->SetParameters(12.9507,-13.9686,-15.4212,19.9494 , -8.59093 , 1.66669 ,-0.123174);

 fitebl->Draw("AL");
 fitsens->Draw("LSame");

 for (int j=0;i<=1;i++)
   {
     fint1[j] = new TF1("fint1",finter,1.9,3.6,0);
     xint1[j]=fint1[j]->GetMinimumX();
     fint1[j]->Draw("lsame");
     
     m[j] = new TMarker(xint1[j],fitebl->Eval(xint1[j]),24);
     m[j]->SetMarkerColor(kRed);
     m[j]->SetMarkerSize(3);
     m[j]->Draw();
     cout<<" xint "<<xint1[j]<<endl;
   }
 return;
}

your functions do not intersect at all (execute your modified and corrected (for C++ errors) macro below).

Rene

[code]TF1 *fitebl, *fitsens;

double finter(double x, doublepar) {
return TMath::Abs(fitsens->EvalPar(x,par) - fitebl->EvalPar(x,par));
}

void new_file(){

TF1 *fint1[2];
double xint1[2];
TMarker *m[2];

TCanvas *c = new TCanvas(“c”," 2nd FERMICAT dec >-32 & Redshift 0.028 - 0.2756",200,10,1200,800);
//c->SetFillColor(0);
c->SetGrid(1,1);

fitebl = new TF1(“fitebl”,“pol6”,1.9,3.6);
fitebl->SetParameters(-2.5413 ,41.9401 , -49.1368 , 29.758 , -9.81396 , 1.66925 , -0.114667);
fitebl->SetMaximum(12);
fitebl->SetMinimum(-12);

fitsens = new TF1(“fitsens”,“pol6”,1.9,3.6);
fitsens->SetParameters(12.9507,-13.9686,-15.4212,19.9494 , -8.59093 , 1.66669 ,-0.123174);

fitebl->Draw(“L”);
fitsens->Draw(“LSame”);

for (int j=0;j<=1;j++)
{
fint1[j] = new TF1(“fint1”,finter,1.9,3.6,0);
xint1[j]=fint1[j]->GetMinimumX();
fint1[j]->Draw(“lsame”);

  m[j] = new TMarker(xint1[j],fitebl->Eval(xint1[j]),24);
  m[j]->SetMarkerColor(kRed);
  m[j]->SetMarkerSize(3);
  m[j]->Draw();
  cout<<" xint "<<xint1[j]<<endl;

}
return;
}

[/code]

hi, i"m sorry about the previous code… truth is my original code is quite long and the data is taken from other files and obviously my short runnig script did not work…

but the general problem is this

[code]TF1 *fitebl, *fitsens;

double finter(double x, doublepar) {
return TMath::Abs(fitsens->EvalPar(x,par) - fitebl->EvalPar(x,par));
}

void new_file(){

TF1 *fint1[2];
double xint1[2];
TMarker *m[2];

TCanvas *c = new TCanvas(“c”," 2nd FERMICAT dec >-32 & Redshift 0.028 - 0.2756",200,10,1200,800);
c->SetFillColor(0);
c->SetGrid(1,1);

fitebl = new TF1(“EBL_fit”,“x*x”,-2,2);
fitsens = new TF1(“SENS_fit”,"(-x[0]*x[0])+2",-2,2);

fitsens->Draw();
fitebl->Draw(“Same”);
for (int j=0;j<=1;j++)
{
fint1[j] = new TF1(“fint1”,finter,-2,2,0);
xint1[j]=fint1[j]->GetMinimumX();
// fint1[j]->Draw(“lsame”);

 m[j] = new TMarker(xint1[j],fitebl->Eval(xint1[j]),24);
 m[j]->SetMarkerColor(kRed);
 m[j]->SetMarkerSize(3);
 m[j]->Draw();
 cout<<" xint "<<xint1[j]<<endl;

}
return;
}
[/code]

here an example withw two square functions

how do i also get the first intersection point?

simply change the range of the domain where you search the crossing point. see your code modified below

Rene

[code]TF1 *fitebl, *fitsens;

double finter(double x, doublepar) {
return TMath::Abs(fitsens->EvalPar(x,par) - fitebl->EvalPar(x,par));
}

void new_file(){

TF1 *fint1[2];
double xint1[2];
TMarker *m[2];

TCanvas *c = new TCanvas(“c”," 2nd FERMICAT dec >-32 & Redshift 0.028 - 0.2756",200,10,1200,800);
c->SetFillColor(0);
c->SetGrid(1,1);

Double_t xmin = -2, xmax = 2;
fitebl = new TF1(“EBL_fit”,“x*x”,xmin,xmax);
fitsens = new TF1(“SENS_fit”,"(-x[0]*x[0])+2",xmin,xmax);

fitsens->Draw();
fitebl->Draw(“Same”);
for (int j=0;j<=1;j++)
{
fint1[j] = new TF1(“fint1”,finter,-2,2,0);
xint1[j]=fint1[j]->GetMinimumX(xmin,xmax);
xmax = xint1[j]-0.01;
// fint1[j]->Draw(“lsame”);

  m[j] = new TMarker(xint1[j],fitebl->Eval(xint1[j]),24);
  m[j]->SetMarkerColor(kRed);
  m[j]->SetMarkerSize(3);
  m[j]->Draw();
  cout<<" xint "<<xint1[j]<<endl;

}
return;
}
[/code]