ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided
Hello! I tried running a combined unbinned extended maximum likelihood fit using the file combinedFit.C as a basis. I found that the fit, when successful, produces correct parameter values, but incorrect, inflated errors for these parameters. The simplest working code demonstrating the problem is provided below. Obviously, the error for the first parameter (Par_0) in this example should be estimated at 10, but the output is 14. What did I do wrong? Please help me figure this out.
int iPar[2] = {1,2};
double logFactorial(int n){
double result = 0;
for(int i=0;i<n;i++) result+=TMath::Log(i+1);
return result;
}
struct GlobalLikelihood{
GlobalLikelihood(ROOT::Math::IMultiGenFunction &func):fLikelihood(&func){}
int nEvents0;
double operator()(const double *par) const{
double p[2];
for(int i=0;i<2;i++) p[i] = par[iPar[i]];
return (*fLikelihood)(p)-nEvents0*TMath::Log(par[0])+par[0]+logFactorial(nEvents0);
}
const ROOT::Math::IMultiGenFunction *fLikelihood;
};
void UnBinFit()
{
int nEvents = 100;
TH1D *hist = new TH1D("hist","hist",100,0,100);
TF1 *f = new TF1("f","TMath::Gaus(x,[0],[1])/(sqrt(2*TMath::Pi())*[1])",0,100);
f->SetParameters(30,10);
ROOT::Fit::DataOptions opt;
ROOT::Fit::DataRange range;
range.SetRange(10,70);
ROOT::Fit::UnBinData data(opt,range,nEvents);
for(int i=0;i<nEvents;i++){
double value = f->GetRandom();
hist->Fill(value);
data.Add(value);
}
ROOT::Math::WrappedMultiTF1 wf(*f,f->GetNdim());
ROOT::Fit::LogLikelihoodFunction llf(data,wf);
GlobalLikelihood globalLikelihood(llf);
globalLikelihood.nEvents0 = nEvents;
ROOT::Fit::Fitter fitter;
const int Npar = 3;
double par0[Npar] = {10,25,11};
fitter.Config().SetParamsSettings(Npar,par0);
fitter.Config().SetMinimizer("Minuit2","Migrad");
fitter.FitFCN(Npar,globalLikelihood,nullptr,data.Size(),false);
ROOT::Fit::FitResult result = fitter.Result();
result.Print(std::cout);
std::cout << "Unbinned fit minimal FCN = " << result.MinFcnValue() << std::endl;
TCanvas *c1 = new TCanvas("Simfit","Unbinned fit example",10,10,700,700);
TF1 *ff = new TF1("ff","[0]*TMath::Gaus(x,[1],[2])/(sqrt(2*TMath::Pi())*[2])",0,100);
gStyle->SetOptFit(1111);
int ipar[Npar] = {0,1,2};
ff->SetFitResult(result,ipar);
ff->SetRange(0,100);
ff->SetLineColor(kBlue);
hist->GetListOfFunctions()->Add(ff);
hist->Draw();
}
The output is:
Minimizer is Minuit2 / Migrad
MinFCN = 364.105
NDf = 97
Edm = 5.15292e-06
NCalls = 119
Par_0 = 99.9983 +/- 14.1419
Par_1 = 28.4495 +/- 1.26369
Par_2 = 8.93566 +/- 0.893786
Unbinned fit minimal FCN = 364.105