In the fit function you define, you can use any complex C++ programming or access the data you need. Have you checked the ROOT Math libraries to see if some tools there answer your question ? And, at the end, if no predefined tools are satisfactory for you, you can program yourself the algorithm you need. May be @moneta has some ideas.
Please help me to check my example:
My fit function is g(x), which obtained by integral f(x,y) from y = -sqrt(1-x^2) to y = sqrt(1-x^2).
And the f(x,y) = 3x^2+2y.
#include "TF2.h"
#include "TH2.h"
#include "TCutG.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TStyle.h"
Double_t f2(Double_t *x, Double_t *par) {
return par[0]*(3*x[0]*x[0]+2*x[1]);
}
Double_t gx(Double_t *x, Double_t *par) {
Double_t yrange[2] = {-TMath::Sqrt(1-x[0]*x[0]),TMath::Sqrt(1-x[0]*x[0])};
return f2->Integral(yrange[0],yrange[1]);
}
TCanvas *fit2a() {
TCanvas *c = new TCanvas();
gStyle->SetOptStat(kTRUE);
gStyle->SetPalette(57);
const Int_t npar = 1;
Double_t f2params[npar] = {2};
auto f1 = new TF1("f1",gx,-1,1, npar);
f1->SetParameters(f2params);
//Create an histogram and fill it randomly with f2
auto h1 = new TH1F("h1","From f1",40,-1,1);
Int_t nentries = 100000;
h1->FillRandom("f1",nentries);
f1->SetParameters(f2params);
h1->Fit("f1","N");
h1->Draw();
f1->Draw("same");
return c;
}
Hi,
You did not follow closely the example above. You need to create an internal TF1 object to define the f2(y) function. You can create for every call of gx(x) as in the example or , in case it is too time consuming, create as a global object or use a functor class and create in its constructor (cleaner and more efficient solution).
I attach below the case where the TF1 object is created inside g(x) as in the cited example.
#include "TF2.h"
#include "TH2.h"
#include "TCutG.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TStyle.h"
Double_t f2(Double_t *x, Double_t *par) {
return par[0]*(3*x[0]*x[0]+2*x[1]);
}
Double_t gx(Double_t *x, Double_t *par) {
Double_t yrange[2] = {-TMath::Sqrt(1-x[0]*x[0]),TMath::Sqrt(1-x[0]*x[0])};
TF1 func2("f2",f2,TMath::Infinity(),-TMath::Infinity(), 1);
func2.SetParameter(0, par[0]);
return func2.Integral(yrange[0],yrange[1]);
}
TCanvas *fit2a() {
TCanvas *c = new TCanvas();
gStyle->SetOptStat(kTRUE);
gStyle->SetPalette(57);
const Int_t npar = 1;
Double_t f2params[npar] = {2};
auto f1 = new TF1("f1",gx,-1,1, npar);
f1->SetParameters(f2params);
//Create an histogram and fill it randomly with f2
auto h1 = new TH1F("h1","From f1",40,-1,1);
Int_t nentries = 100000;
h1->FillRandom("f1",nentries);
f1->SetParameters(f2params);
h1->Fit("f1","N");
h1->Draw();
f1->Draw("same");
return c;
}
Hi,
you are right, the code above is wrong, since you want to compute an integral of f(x,y) in dy. You need in that case to define x as a parameter for ‘f2’. .Here is the corrected code:
#include "TF2.h"
#include "TH2.h"
#include "TCutG.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TStyle.h"
Double_t f2(Double_t *x, Double_t *par) {
return par[0]*(3*par[1]*par[1]+2*x[0]);
}
Double_t gx(Double_t *x, Double_t *par) {
Double_t yrange[2] = {-TMath::Sqrt(1-x[0]*x[0]),TMath::Sqrt(1-x[0]*x[0])};
TF1 func2("f2",f2,TMath::Infinity(),-TMath::Infinity(), 2);
func2.SetParameter(0, par[0]);
func2.SetParameter(1, x[0]);
return func2.Integral(yrange[0],yrange[1]);
}
TCanvas *fit2a() {
TCanvas *c = new TCanvas();
gStyle->SetOptStat(kTRUE);
gStyle->SetPalette(57);
const Int_t npar = 1;
Double_t f2params[npar] = {2.};
auto f1 = new TF1("f1",gx,-1,1, npar);
f1->SetParameters(f2params);
//Create an histogram and fill it randomly with f2
auto h1 = new TH1F("h1","From f1",40,-1,1);
Int_t nentries = 100000;
h1->FillRandom("f1",nentries);
f1->SetParameters(f2params);
ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator("Gauss");
h1->Fit("f1","N");
h1->Draw();
f1->Draw("same");
return c;
}