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]