35 extern void F2Fit(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
36 extern void F3Fit(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
43 TFitter::TFitter(Int_t maxpar)
45 fMinuit =
new TMinuit(maxpar);
49 SetName(
"MinuitFitter");
57 if (fCovar)
delete [] fCovar;
58 if (fSumLog)
delete [] fSumLog;
65 Double_t TFitter::Chisquare(Int_t , Double_t * )
const
67 Error(
"Chisquare",
"This function is deprecated - use ROOT::Fit::Chisquare class");
70 return TMath::QuietNaN();
76 void TFitter::Clear(Option_t *)
78 if (fCovar) {
delete [] fCovar; fCovar = 0;}
84 fMinuit->mnrn15(val,inseed);
92 Int_t TFitter::ExecuteCommand(
const char *command, Double_t *args, Int_t nargs)
94 if (fCovar) {
delete [] fCovar; fCovar = 0;}
96 fMinuit->mnexcm(command,args,nargs,ierr);
103 void TFitter::FixParameter(Int_t ipar)
105 if (fCovar) {
delete [] fCovar; fCovar = 0;}
106 fMinuit->FixParameter(ipar);
122 void TFitter::GetConfidenceIntervals(Int_t n, Int_t ndim,
const Double_t *x, Double_t *ci, Double_t cl)
124 TF1 *f = (TF1*)fUserFunc;
125 Int_t npar = f->GetNumberFreeParameters();
126 Int_t npar_real = f->GetNpar();
127 Double_t *grad =
new Double_t[npar_real];
128 Double_t *sum_vector =
new Double_t[npar];
131 if (npar_real != npar){
132 fixed =
new Bool_t[npar_real];
133 memset(fixed,0,npar_real*
sizeof(Bool_t));
135 for (Int_t ipar=0; ipar<npar_real; ipar++){
137 f->GetParLimits(ipar,al,bl);
138 if (al*bl != 0 && al >= bl) {
146 Double_t *matr = GetCovarianceMatrix();
149 delete [] sum_vector;
155 Double_t t = TMath::StudentQuantile(0.5 + cl/2, f->GetNDF());
156 Double_t chidf = TMath::Sqrt(f->GetChisquare()/f->GetNDF());
157 Int_t igrad, ifree=0;
158 for (Int_t ipoint=0; ipoint<n; ipoint++){
160 f->GradientPar(x+ndim*ipoint, grad);
162 for (Int_t irow=0; irow<npar; irow++){
165 for (Int_t icol=0; icol<npar; icol++){
170 while (ifree<icol+1){
171 if (fixed[igrad]==0) ifree++;
179 sum_vector[irow]+=matr[irow*npar_real+icol]*grad[igrad];
183 for (Int_t i=0; i<npar; i++){
188 if (fixed[igrad]==0) ifree++;
195 c+=grad[igrad]*sum_vector[i];
199 ci[ipoint]=c*t*chidf;
203 delete [] sum_vector;
232 void TFitter::GetConfidenceIntervals(TObject *obj, Double_t cl)
234 if (obj->InheritsFrom(TGraph::Class())) {
235 TGraph *gr = (TGraph*)obj;
237 Error(
"GetConfidenceIntervals",
"A TGraphErrors should be passed instead of a graph");
240 if (fObjectFit->InheritsFrom(TGraph2D::Class())){
241 Error(
"GetConfidenceIntervals",
"A TGraph2DErrors should be passed instead of a graph");
244 if (fObjectFit->InheritsFrom(TH1::Class())){
245 if (((TH1*)(fObjectFit))->GetDimension()>1){
246 Error(
"GetConfidenceIntervals",
"A TGraph2DErrors or a TH23 should be passed instead of a graph");
250 GetConfidenceIntervals(gr->GetN(),1,gr->GetX(), gr->GetEY(), cl);
251 for (Int_t i=0; i<gr->GetN(); i++)
252 gr->SetPoint(i, gr->GetX()[i], ((TF1*)(fUserFunc))->Eval(gr->GetX()[i]));
256 else if (obj->InheritsFrom(TGraph2D::Class())) {
257 TGraph2D *gr2 = (TGraph2D*)obj;
259 Error(
"GetConfidenceIntervals",
"A TGraph2DErrors should be passed instead of a TGraph2D");
262 if (fObjectFit->InheritsFrom(TGraph::Class())){
263 Error(
"GetConfidenceIntervals",
"A TGraphErrors should be passed instead of a TGraph2D");
266 if (fObjectFit->InheritsFrom(TH1::Class())){
267 if (((TH1*)(fObjectFit))->GetDimension()==1){
268 Error(
"GetConfidenceIntervals",
"A TGraphErrors or a TH1 should be passed instead of a graph");
272 TF2 *f=(TF2*)fUserFunc;
274 Int_t np = gr2->GetN();
275 Int_t npar = f->GetNpar();
276 Double_t *grad =
new Double_t[npar];
277 Double_t *sum_vector =
new Double_t[npar];
278 Double_t *x = gr2->GetX();
279 Double_t *y = gr2->GetY();
280 Double_t t = TMath::StudentQuantile(0.5 + cl/2, f->GetNDF());
281 Double_t chidf = TMath::Sqrt(f->GetChisquare()/f->GetNDF());
282 Double_t *matr=GetCovarianceMatrix();
284 for (Int_t ipoint=0; ipoint<np; ipoint++){
287 f->GradientPar(xy, grad);
288 for (Int_t irow=0; irow<f->GetNpar(); irow++){
290 for (Int_t icol=0; icol<npar; icol++)
291 sum_vector[irow]+=matr[irow*npar+icol]*grad[icol];
294 for (Int_t i=0; i<npar; i++)
295 c+=grad[i]*sum_vector[i];
297 gr2->SetPoint(ipoint, xy[0], xy[1], f->EvalPar(xy));
298 gr2->GetEZ()[ipoint]=c*t*chidf;
302 delete [] sum_vector;
306 else if (obj->InheritsFrom(TH1::Class())) {
307 if (fObjectFit->InheritsFrom(TGraph::Class())){
308 if (((TH1*)obj)->GetDimension()>1){
309 Error(
"GetConfidenceIntervals",
"Fitted graph and passed histogram have different number of dimensions");
313 if (fObjectFit->InheritsFrom(TGraph2D::Class())){
314 if (((TH1*)obj)->GetDimension()!=2){
315 Error(
"GetConfidenceIntervals",
"Fitted graph and passed histogram have different number of dimensions");
319 if (fObjectFit->InheritsFrom(TH1::Class())){
320 if (((TH1*)(fObjectFit))->GetDimension()!=((TH1*)(obj))->GetDimension()){
321 Error(
"GetConfidenceIntervals",
"Fitted and passed histograms have different number of dimensions");
327 TH1 *hfit = (TH1*)obj;
328 TF1 *f = (TF1*)GetUserFunc();
329 Int_t npar = f->GetNpar();
330 Double_t *grad =
new Double_t[npar];
331 Double_t *sum_vector =
new Double_t[npar];
334 Int_t hxfirst = hfit->GetXaxis()->GetFirst();
335 Int_t hxlast = hfit->GetXaxis()->GetLast();
336 Int_t hyfirst = hfit->GetYaxis()->GetFirst();
337 Int_t hylast = hfit->GetYaxis()->GetLast();
338 Int_t hzfirst = hfit->GetZaxis()->GetFirst();
339 Int_t hzlast = hfit->GetZaxis()->GetLast();
341 TAxis *xaxis = hfit->GetXaxis();
342 TAxis *yaxis = hfit->GetYaxis();
343 TAxis *zaxis = hfit->GetZaxis();
344 Double_t t = TMath::StudentQuantile(0.5 + cl/2, f->GetNDF());
345 Double_t chidf = TMath::Sqrt(f->GetChisquare()/f->GetNDF());
346 Double_t *matr=GetCovarianceMatrix();
348 for (Int_t binz=hzfirst; binz<=hzlast; binz++){
349 x[2]=zaxis->GetBinCenter(binz);
350 for (Int_t biny=hyfirst; biny<=hylast; biny++) {
351 x[1]=yaxis->GetBinCenter(biny);
352 for (Int_t binx=hxfirst; binx<=hxlast; binx++) {
353 x[0]=xaxis->GetBinCenter(binx);
354 f->GradientPar(x, grad);
355 for (Int_t irow=0; irow<npar; irow++){
357 for (Int_t icol=0; icol<npar; icol++)
358 sum_vector[irow]+=matr[irow*npar+icol]*grad[icol];
361 for (Int_t i=0; i<npar; i++)
362 c+=grad[i]*sum_vector[i];
364 hfit->SetBinContent(binx, biny, binz, f->EvalPar(x));
365 hfit->SetBinError(binx, biny, binz, c*t*chidf);
370 delete [] sum_vector;
373 Error(
"GetConfidenceIntervals",
"This object type is not supported");
382 Double_t *TFitter::GetCovarianceMatrix()
const
384 if (fCovar)
return fCovar;
385 Int_t npars = fMinuit->GetNumPars();
386 ((TFitter*)
this)->fCovar =
new Double_t[npars*npars];
387 fMinuit->mnemat(fCovar,npars);
394 Double_t TFitter::GetCovarianceMatrixElement(Int_t i, Int_t j)
const
396 GetCovarianceMatrix();
397 Int_t npars = fMinuit->GetNumPars();
398 if (i < 0 || i >= npars || j < 0 || j >= npars) {
399 Error(
"GetCovarianceMatrixElement",
"Illegal arguments i=%d, j=%d",i,j);
402 return fCovar[j+npars*i];
413 Int_t TFitter::GetErrors(Int_t ipar,Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc)
const
417 fMinuit->mnerrs(ipar, eplus,eminus,eparab,globcc);
425 Int_t TFitter::GetNumberTotalParameters()
const
427 return fMinuit->fNpar + fMinuit->fNpfix;
433 Int_t TFitter::GetNumberFreeParameters()
const
435 return fMinuit->fNpar;
442 Double_t TFitter::GetParError(Int_t ipar)
const
446 Double_t value,verr,vlow,vhigh;
448 fMinuit->mnpout(ipar, pname,value,verr,vlow,vhigh,ierr);
456 Double_t TFitter::GetParameter(Int_t ipar)
const
460 Double_t value,verr,vlow,vhigh;
462 fMinuit->mnpout(ipar, pname,value,verr,vlow,vhigh,ierr);
478 Int_t TFitter::GetParameter(Int_t ipar,
char *parname,Double_t &value,Double_t &verr,Double_t &vlow, Double_t &vhigh)
const
482 fMinuit->mnpout(ipar, pname,value,verr,vlow,vhigh,ierr);
483 strcpy(parname,pname.Data());
490 const char *TFitter::GetParName(Int_t ipar)
const
492 if (!fMinuit || ipar < 0 || ipar > fMinuit->fNu)
return "";
493 return fMinuit->fCpnam[ipar];
505 Int_t TFitter::GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx)
const
508 fMinuit->mnstat(amin,edm,errdef,nvpar,nparx,ierr);
516 Double_t TFitter::GetSumLog(Int_t n)
520 if (fSumLog)
delete [] fSumLog;
522 fSumLog =
new Double_t[fNlog+1];
524 for (Int_t j=0;j<=fNlog;j++) {
525 if (j > 1) fobs += TMath::Log(j);
529 if (fSumLog)
return fSumLog[n];
537 Bool_t TFitter::IsFixed(Int_t ipar)
const
539 if (fMinuit->fNiofex[ipar] == 0 )
return kTRUE;
547 void TFitter::PrintResults(Int_t level, Double_t amin)
const
549 fMinuit->mnprin(level,amin);
555 void TFitter::ReleaseParameter(Int_t ipar)
557 if (fCovar) {
delete [] fCovar; fCovar = 0;}
558 fMinuit->Release(ipar);
564 void TFitter::SetFCN(
void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
566 if (fCovar) {
delete [] fCovar; fCovar = 0;}
567 TVirtualFitter::SetFCN(fcn);
568 fMinuit->SetFCN(fcn);
574 void TFitter::SetFitMethod(
const char *name)
576 if (fCovar) {
delete [] fCovar; fCovar = 0;}
582 if (!strcmp(name,
"F2Minimizer")) SetFCN(F2Fit);
583 if (!strcmp(name,
"F3Minimizer")) SetFCN(F3Fit);
596 Int_t TFitter::SetParameter(Int_t ipar,
const char *parname,Double_t value,Double_t verr,Double_t vlow, Double_t vhigh)
598 if (fCovar) {
delete [] fCovar; fCovar = 0;}
600 fMinuit->mnparm(ipar,parname,value,verr,vlow,vhigh,ierr);
608 void F2Fit(Int_t &, Double_t * , Double_t &f,Double_t *u, Int_t )
610 TVirtualFitter *fitter = TVirtualFitter::GetFitter();
611 TF2 *f2 = (TF2*)fitter->GetObjectFit();
612 f2->InitArgs(u, f2->GetParameters() );
618 void F3Fit(Int_t &, Double_t * , Double_t &f,Double_t *u, Int_t )
620 TVirtualFitter *fitter = TVirtualFitter::GetFitter();
621 TF3 *f3 = (TF3*)fitter->GetObjectFit();
622 f3->InitArgs(u, f3->GetParameters() );