113 extern void H1FitChisquareFumili(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
114 extern void H1FitLikelihoodFumili(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
115 extern void GraphFitChisquareFumili(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
123 static const Double_t gMAXDOUBLE=1e300;
124 static const Double_t gMINDOUBLE=-1e300;
128 TFumili::TFumili(Int_t maxpar)
132 fMaxParam = TMath::Max(maxpar,25);
133 if (fMaxParam>200) fMaxParam=200;
136 fNumericDerivatives =
true;
146 fNED12 = fNED1+fNED2;
161 for (
int i = 0; i<5; ++i) fINDFLG[i] = 0;
165 gROOT->GetListOfSpecials()->Add(gFumili);
173 void TFumili::BuildArrays(){
174 fCmPar =
new Double_t[fMaxParam];
175 fA =
new Double_t[fMaxParam];
176 fPL0 =
new Double_t[fMaxParam];
177 fPL =
new Double_t[fMaxParam];
178 fParamError =
new Double_t[fMaxParam];
179 fDA =
new Double_t[fMaxParam];
180 fAMX =
new Double_t[fMaxParam];
181 fAMN =
new Double_t[fMaxParam];
182 fR =
new Double_t[fMaxParam];
183 fDF =
new Double_t[fMaxParam];
184 fGr =
new Double_t[fMaxParam];
185 fANames =
new TString[fMaxParam];
189 Int_t zSize = fMaxParam*(fMaxParam+1)/2;
190 fZ0 =
new Double_t[zSize];
191 fZ =
new Double_t[zSize];
193 for (Int_t i=0;i<fMaxParam;i++) {
201 fANames[i]=Form(
"%d",i);
208 TFumili::~TFumili() {
210 if (gROOT && !gROOT->TestBit(TObject::kInvalidObject))
211 gROOT->GetListOfSpecials()->Remove(
this);
212 if (gFumili ==
this) gFumili = 0;
218 Double_t TFumili::Chisquare(Int_t npar, Double_t *params)
const
221 H1FitChisquareFumili(npar,params,amin,params,1);
233 void TFumili::Clear(Option_t *)
237 for (Int_t i=0;i<fNpar;i++) {
242 fAMN[i] = gMINDOUBLE;
243 fAMX[i] = gMAXDOUBLE;
245 fANames[i]=Form(
"%d",i);
252 void TFumili::DeleteArrays(){
266 delete[] fParamError;
282 void TFumili::Derivatives(Double_t *df,Double_t *fX){
283 Double_t ff,ai,hi,y,pi;
285 for (Int_t i=0;i<fNpar;i++) {
290 pi = fRP*TMath::Abs(ai);
300 if (fAMN[i]-ai+hi<0) {
341 Int_t TFumili::Eval(Int_t& npar, Double_t *grad, Double_t &fval, Double_t *par, Int_t flag)
343 if (fFCN) (*fFCN)(npar,grad,fval,par,flag);
353 Double_t TFumili::EvalTFN(Double_t * , Double_t *X)
360 TF1 *f1 = (TF1*)fUserFunc;
361 return f1->EvalPar(X,fA);
382 Int_t TFumili::ExecuteCommand(
const char *command, Double_t *args, Int_t nargs){
383 TString comand = command;
384 static TString clower =
"abcdefghijklmnopqrstuvwxyz";
385 static TString cupper =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
386 const Int_t nntot = 40;
387 const char *cname[nntot] = {
432 if (nargs<=0) fCmPar[0] = 0;
434 for(i=0;i<fMaxParam;i++) {
435 if(i<nargs) fCmPar[i] = args[i];
445 TString ctemp = fCword(0,3);
447 for (ind = 0; ind < nntot; ++ind) {
448 if (strncmp(ctemp.Data(),cname[ind],3) == 0)
break;
450 if (ind==nntot)
return -3;
451 if (fCword(0,4) ==
"MINO") ind=3;
453 case 0:
case 3:
case 2:
case 28:
457 fNmaxIter=TMath::Max(Int_t(fCmPar[0]),fNmaxIter);
469 return ExecuteSetCommand(nargs);
475 if (nargs<1)
return -1;
476 for (i=0;i<nargs;i++) {
477 Int_t parnum = Int_t(fCmPar[i])-1;
478 FixParameter(parnum);
482 if (nargs<1)
return 0;
484 for (i=0;i<fNpar;i++)
488 ReleaseParameter(fLastFixed);
489 std::cout <<fLastFixed<<std::endl;
493 if (nargs<1)
return -1;
494 for (i=0;i<nargs;i++) {
495 Int_t parnum = Int_t(fCmPar[i])-1;
496 ReleaseParameter(parnum);
507 Printf(
"SAVe command is obsolete");
512 {
if(nargs<1)
return -1;
513 Int_t flag = Int_t(fCmPar[0]);
515 Eval(fNpar,fGr,fval,fA,flag);
523 Eval(fNpar,fGr,fval,fA,flag);
533 case 26:
case 27:
case 29:
case 30:
case 31:
case 32:
535 case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
537 Printf(
"Obsolete command. Use corresponding SET command instead");
549 Int_t TFumili::ExecuteSetCommand(Int_t nargs){
550 static Int_t nntot = 30;
551 static const char *cname[30] = {
583 TString cfname, cmode, ckind, cwarn, copt, ctemp, ctemp2;
585 Bool_t setCommand=kFALSE;
586 for (ind = 0; ind < nntot; ++ind) {
589 ctemp2 = fCword(4,6);
590 if (strstr(ctemp2.Data(),ckind.Data()))
break;
592 ctemp2 = fCword(0,3);
593 if(ctemp2.Contains(
"SET")) setCommand=
true;
594 if(ctemp2.Contains(
"HEL") || ctemp2.Contains(
"SHO")) setCommand=
false;
596 if (ind>=nntot)
return -3;
600 if(!setCommand) Printf(
"FCN=%f",fS);
604 if (nargs<2 && setCommand)
return -1;
608 parnum = Int_t(fCmPar[0])-1;
610 if(parnum<0 || parnum>=fNpar)
return -2;
614 parnum = Int_t(fCmPar[0])-1;
615 if(parnum<0 || parnum>=fNpar)
return -2;
616 Printf(
"Parameter %s = %E",fANames[parnum].Data(),fA[parnum]);
618 for (i=0;i<fNpar;i++)
619 Printf(
"Parameter %s = %E",fANames[i].Data(),fA[i]);
627 Double_t lolim,uplim;
631 fAMN[i] = gMINDOUBLE;
632 fAMX[i] = gMAXDOUBLE;
634 Printf(
"Limits for param %s: Low=%E, High=%E",
635 fANames[i].Data(),fAMN[i],fAMX[i]);
637 parnum = Int_t(fCmPar[0])-1;
638 if(parnum<0 || parnum>=fNpar)
return -1;
643 if(uplim==lolim)
return -1;
645 Double_t tmp = lolim;
653 fAMN[parnum] = lolim;
654 fAMX[parnum] = uplim;
656 Printf(
"Limits for param %s Low=%E, High=%E",
657 fANames[parnum].Data(),fAMN[parnum],fAMX[parnum]);
663 if(setCommand)
return 0;
664 Printf(
"\nCovariant matrix ");
665 Int_t l = 0,nn=0,nnn=0;
666 for (i=0;i<fNpar;i++) if(fPL0[i]>0.) nn++;
668 for(;fPL0[nnn]<=0.;nnn++) { }
669 printf(
"%5s: ",fANames[nnn++].Data());
670 for (Int_t j=0;j<=i;j++)
671 printf(
"%11.2E",fZ[l++]);
672 std::cout<<std::endl;
674 std::cout<<std::endl;
678 if(setCommand)
return 0;
679 Printf(
"\nGlobal correlation factors (maximum correlation of the parameter\n with arbitrary linear combination of other parameters)");
680 for(i=0;i<fNpar;i++) {
681 printf(
"%5s: ",fANames[i].Data());
682 printf(
"%11.3E\n",TMath::Sqrt(1-1/((fR[i]!=0.)?fR[i]:1.)) );
684 std::cout<<std::endl;
689 if(!setCommand)
return 0;
693 if(!setCommand)
return 0;
705 if(!setCommand)
return 0;
709 if(!setCommand)
return 0;
726 Printf(
"Relative floating point precision RP=%E",fRP);
729 Double_t pres=fCmPar[0];
730 if (pres<1e-5 && pres>1e-34) fRP=pres;
740 if(setCommand)
return 0;
741 Printf(
"FUMILI-ROOT version 0.1");
746 if(!setCommand)
return 0;
750 if(!setCommand)
return 0;
765 void TFumili::FixParameter(Int_t ipar) {
766 if(ipar>=0 && ipar<fNpar && fPL0[ipar]>0.) {
767 fPL0[ipar] = -fPL0[ipar];
775 Double_t *TFumili::GetCovarianceMatrix()
const
784 Double_t TFumili::GetCovarianceMatrixElement(Int_t i, Int_t j)
const
787 if (i < 0 || i >= fNpar || j < 0 || j >= fNpar) {
788 Error(
"GetCovarianceMatrixElement",
"Illegal arguments i=%d, j=%d",i,j);
791 return fZ[j+fNpar*i];
797 Int_t TFumili::GetNumberTotalParameters()
const
805 Int_t TFumili::GetNumberFreeParameters()
const
808 for (Int_t i=0;i<fNpar;i++) {
809 if (IsFixed(i)) nfree--;
817 Double_t TFumili::GetParError(Int_t ipar)
const
819 if (ipar<0 || ipar>=fNpar)
return 0;
820 else return fParamError[ipar];
826 Double_t TFumili::GetParameter(Int_t ipar)
const
828 if (ipar<0 || ipar>=fNpar)
return 0;
829 else return fA[ipar];
843 Int_t TFumili::GetParameter(Int_t ipar,
char *cname,Double_t &value,Double_t &verr,Double_t &vlow, Double_t &vhigh)
const
845 if (ipar<0 || ipar>=fNpar) {
852 strcpy(cname,fANames[ipar].Data());
854 verr = fParamError[ipar];
863 const char *TFumili::GetParName(Int_t ipar)
const
865 if (ipar < 0 || ipar > fNpar)
return "";
866 return fANames[ipar].Data();
873 Int_t TFumili::GetErrors(Int_t ipar,Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc)
const
877 if (ipar<0 || ipar>=fNpar) {
882 eplus=fParamError[ipar];
895 Int_t TFumili::GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx)
const
902 for(Int_t ii=0; ii<fNpar; ii++) {
903 if(fPL0[ii]>0.) nvpar++;
912 Double_t TFumili::GetSumLog(Int_t n)
916 if (fSumLog)
delete [] fSumLog;
918 fSumLog =
new Double_t[fNlog+1];
920 for (Int_t j=0;j<=fNlog;j++) {
921 if (j > 1) fobs += TMath::Log(j);
925 if (fSumLog)
return fSumLog[n];
936 void TFumili::InvertZ(Int_t n)
938 static Double_t am = 3.4e138;
939 static Double_t rp = 5.0e-14;
940 Double_t ap, aps, c, d;
944 Int_t i, k, l, ii, ki, li, kk, ni, ll, nk, nl, ir, lk;
953 ap = 1.0e0 / (aps * aps);
955 for (i = 1; i <= n; ++i) {
958 if (pl_1[ir] <= 0.0e0)
goto L1;
961 ni = i * (i - 1) / 2;
964 if (z_1[ii] <= rp * TMath::Abs(r_1[ir]) || z_1[ii] <= ap) {
967 z_1[ii] = 1.0e0 / sqrt(z_1[ii]);
970 if (nl - ni <= 0)
goto L5;
974 if (TMath::Abs(z_1[nl]) >= aps) {
980 if (i - n >= 0)
goto L12;
984 nk = k * (k - 1) / 2;
987 d = z_1[kk] * z_1[ii];
993 z_1[ll] -= z_1[li] * c;
996 if (l - i <= 0)
goto L9;
1001 z_1[ll] -= z_1[li] * d;
1004 if (l <= 0)
goto L10;
1008 if (k - i - 1 <= 0)
goto L11;
1014 for (i = 1; i <= n; ++i) {
1015 for (k = i; k <= n; ++k) {
1016 nl = k * (k - 1) / 2;
1019 for (l = k; l <= n; ++l) {
1022 d += z_1[li] * z_1[lk];
1025 ki = k * (k - 1) / 2 + i;
1034 for (i = 1; i <= k; ++i) {
1037 if (pl_1[ir] <= 0.0e0) {
1044 fINDFLG[0] = ir - 1;
1051 Bool_t TFumili::IsFixed(Int_t ipar)
const
1053 if(ipar < 0 || ipar >= fNpar) {
1054 Warning(
"IsFixed",
"Illegal parameter number :%d",ipar);
1057 if (fPL0[ipar] < 0)
return kTRUE;
1076 Int_t TFumili::Minimize()
1087 Eval(parn,fGr,fS,fA,9); fNfcn++;
1089 for( i = 0; i < fNpar; i++) {
1090 if(fA[i] > fAMX[i]) fA[i] = fAMX[i];
1091 if(fA[i] < fAMN[i]) fA[i] = fAMN[i];
1094 Int_t nn2, n, fixFLG, ifix1, fi, nn3, nn1, n0;
1096 Double_t sp, t, olds=0;
1097 Double_t bi, aiMAX=0, amb;
1098 Double_t afix, sigi, akap;
1099 Double_t alambd, al, bm, abi, abm;
1118 for( i=0; i < n; i++) {
1120 if ( fEPS > 0.) fParamError[i] = 0.;
1135 for( i = 0; i < n; i++) {
1140 if (fPL[i] > .0) fPL0[i]=fPL[i];
1148 for( i=0; i < nn0; i++) fZ[i]=0.;
1156 Eval(parn,fGr,fS,fA,2);
1160 if(!ijkl)
return 10;
1161 if (ijkl == -1) fINDFLG[0]=1;
1164 sp=fRP*TMath::Abs(fS);
1167 for( i=0; i < nn0; i++) fZ0[i] = fZ[i];
1169 if (nn1 <= fNstepDec) {
1171 if (fINDFLG[0] == 0) {
1172 if (TMath::Abs(fS-olds) <= sp && -fGT <= sp)
goto L19;
1173 if( 0.59*t < -fGT)
goto L19;
1175 if (t < 0.25 ) t = 0.25;
1181 for( i = 0; i < n; i++) {
1196 if(fINDFLG[0] != 0) {
1198 printf(
"trying to execute an illegal jump at L85\n");
1203 Int_t k1, k2, i1, j, l;
1209 for( i = 0; i < n; i++) {
1212 if (fPL[i] == 0.) fPL[i]=fPL0[i];
1216 if ((fA[i] >= fAMX[i] && fGr[i] < 0.) ||
1217 (fA[i] <= fAMN[i] && fGr[i] > 0.)) {
1223 for( j=0; j <= i; j++) {
1228 fZ[k2 -1] = fZ0[k1 -1];
1244 for( i = 0; i < n; i++) {
1256 if (fINDFLG[0] != 0) {
1260 fixFLG = fixFLG + 1;
1267 for( i = 0; i < n; i++) {
1271 for( l = 0; l < n; l++) {
1275 if (i1 <= l1 ) k=l1*(l1-1)/2+i1;
1276 else k=i1*(i1-1)/2+l1;
1278 fDA[i]=fDA[i]-fGr[l]*fZ[k - 1];
1291 for( i = 0; i < n; i++)
1293 sigi = TMath::Sqrt(TMath::Abs(fZ[l - 1]));
1294 fR[i] = fR[i]*fZ[l - 1];
1295 if (fEPS > .0) fParamError[i]=sigi;
1296 if ((fA[i] >= fAMX[i] && fDA[i] > 0.) || (fA[i] <= fAMN[i]
1300 akap = TMath::Abs(fDA[i]/sigi);
1315 fixFLG = fixFLG + 1;
1329 for( i = 0; i < n; i++) {
1331 bm = fAMX[i] - fA[i];
1332 abi = fA[i] + fPL[i];
1335 bm = fA[i] - fAMN[i];
1336 abi = fA[i] - fPL[i];
1347 if ( TMath::Abs(fDA[i]) > bi) {
1349 al = TMath::Abs(bi/fDA[i]);
1357 akap = TMath::Abs(fDA[i]/fParamError[i]);
1358 if (akap > fAKAPPA) fAKAPPA=akap;
1365 if (alambd > .0) amb = 0.25/alambd;
1366 for( i = 0; i < n; i++) {
1368 if (nn2 > fNlimMul ) {
1369 if (TMath::Abs(fDA[i]/fPL[i]) > amb ) {
1375 fDA[i] = fDA[i]*alambd;
1377 fGT = fGT + fDA[i]*fGr[i];
1384 if (-fGT <= sp && t1 < 1. && alambd < 1.)fENDFLG = -1;
1387 if (fAKAPPA < TMath::Abs(fEPS)) {
1397 for( i = 0; i < fNpar; i++) fPL[i] = fPL0[i];
1415 for( i = 0; i < fNpar; i++) fPL[i] = fPL0[i];
1431 if(fENDFLG == 0 && nn3 >= fNmaxIter) fENDFLG=-3;
1434 if(fENDFLG > 0 && fINDFLG[1] > 0) fENDFLG=-2;
1438 for ( i = 0; i < n; i++) fA[i] = fA[i] + fDA[i];
1439 if (imax >= 0) fA[imax] = aiMAX;
1448 for( Int_t ip = 0; ip < fNpar; ip++) {
1449 if( fPL0[ip] > .0) {
1450 for( Int_t jp = 0; jp <= ip; jp++) {
1474 void TFumili::PrintResults(Int_t ikode,Double_t p)
const
1476 TString exitStatus=
"";
1478 TString colhdu[3],colhdl[3],cx2,cx3;
1481 exitStatus=
"CONVERGED";
1484 exitStatus=
"CONST FCN";
1485 xsexpl=
"****\n* FUNCTION IS NOT DECREASING OR BAD DERIVATIVES\n****";
1488 exitStatus=
"ERRORS INF";
1489 xsexpl=
"****\n* ESTIMATED ERRORS ARE INfiNITE\n****";
1492 exitStatus=
"MAX ITER.";
1493 xsexpl=
"****\n* MAXIMUM NUMBER OF ITERATIONS IS EXCEEDED\n****";
1496 exitStatus=
"ZERO PROBAB";
1497 xsexpl=
"****\n* PROBABILITY OF LIKLIHOOD FUNCTION IS NEGATIVE OR ZERO\n****";
1500 exitStatus=
"UNDEfiNED";
1501 xsexpl=
"****\n* fiT IS IN PROGRESS\n****";
1506 colhdl[0] =
" ERROR ";
1507 colhdu[1] =
" PHYSICAL";
1508 colhdu[2] =
" LIMITS ";
1509 colhdl[1] =
" NEGATIVE ";
1510 colhdl[2] =
" POSITIVE ";
1514 colhdl[0] =
" ERROR ";
1515 colhdu[1] =
" INTERNAL ";
1516 colhdl[1] =
" STEP SIZE ";
1517 colhdu[2] =
" INTERNAL ";
1518 colhdl[2] =
" VALUE ";
1522 colhdl[0] =
" ERROR ";
1523 colhdu[1] =
" STEP ";
1524 colhdl[1] =
" SIZE ";
1525 colhdu[2] =
" fiRST ";
1526 colhdl[2] =
" DERIVATIVE";
1529 colhdu[0] =
" PARABOLIC ";
1530 colhdl[0] =
" ERROR ";
1531 colhdu[1] =
" MINOS ";
1532 colhdu[2] =
"ERRORS ";
1533 colhdl[1] =
" NEGATIVE ";
1534 colhdl[2] =
" POSITIVE ";
1536 if(fENDFLG<1)Printf(
"%s", xsexpl.Data());
1537 Printf(
" FCN=%g FROM FUMILI STATUS=%-10s %9d CALLS OF FCN",
1538 p,exitStatus.Data(),fNfcn);
1539 Printf(
" EDM=%g ",-fGT);
1540 Printf(
" EXT PARAMETER %-14s%-14s%-14s",
1541 (
const char*)colhdu[0].Data()
1542 ,(
const char*)colhdu[1].Data()
1543 ,(
const char*)colhdu[2].Data());
1544 Printf(
" NO. NAME VALUE %-14s%-14s%-14s",
1545 (
const char*)colhdl[0].Data()
1546 ,(
const char*)colhdl[1].Data()
1547 ,(
const char*)colhdl[2].Data());
1549 for (Int_t i=0;i<fNpar;i++) {
1551 cx2 = Form(
"%14.5e",fDA[i]);
1552 cx3 = Form(
"%14.5e",fGr[i]);
1556 cx2 = Form(
"%14.5e",fAMN[i]);
1557 cx3 = Form(
"%14.5e",fAMX[i]);
1560 cx2 = Form(
"%14.5e",fDA[i]);
1561 cx3 = Form(
"%14.5e",fA[i]);
1564 cx2 =
" *undefined* ";
1565 cx3 =
" *undefined* ";
1567 if(fPL0[i]<=0.) { cx2=
" *fixed* ";cx3=
""; }
1568 Printf(
"%4d %-11s%14.5e%14.5e%-14s%-14s",i+1
1569 ,fANames[i].Data(),fA[i],fParamError[i]
1570 ,cx2.Data(),cx3.Data());
1577 void TFumili::ReleaseParameter(Int_t ipar) {
1578 if(ipar>=0 && ipar<fNpar && fPL0[ipar]<=0.) {
1579 fPL0[ipar] = -fPL0[ipar];
1580 if (fPL0[ipar] == 0. || fPL0[ipar]>=1.) fPL0[ipar]=.1;
1607 void TFumili::SetData(Double_t *exdata,Int_t numpoints,Int_t vecsize){
1619 void TFumili::SetFitMethod(
const char *name)
1621 if (!strcmp(name,
"H1FitChisquare")) SetFCN(H1FitChisquareFumili);
1622 if (!strcmp(name,
"H1FitLikelihood")) SetFCN(H1FitLikelihoodFumili);
1623 if (!strcmp(name,
"GraphFitChisquare")) SetFCN(GraphFitChisquareFumili);
1632 Int_t TFumili::SetParameter(Int_t ipar,
const char *parname,Double_t value,Double_t verr,Double_t vlow, Double_t vhigh) {
1633 if (ipar<0 || ipar>=fNpar)
return -1;
1634 fANames[ipar] = parname;
1636 fParamError[ipar] = verr;
1647 ReleaseParameter(ipar);
1648 fAMN[ipar] = gMINDOUBLE;
1649 fAMX[ipar] = gMAXDOUBLE;
1651 if(vlow!=0) FixParameter(ipar);
1661 Int_t TFumili::SGZ()
1664 Int_t i,j,l,k2=1,k1,ki=0;
1665 Double_t *x =
new Double_t[fNED2];
1666 Double_t *df =
new Double_t[fNpar];
1668 for (l=0;l<fNED1;l++) {
1671 fNumericDerivatives = kTRUE;
1681 Double_t y = EvalTFN(df,x);
1682 if(fNumericDerivatives) Derivatives(df,x);
1697 y = y - fEXDA[k1-1];
1698 fS = fS + (y*y/(sig*sig))*.5;
1701 for (i=0;i<fNpar;i++) {
1704 fGr[i] += df[n]*(y/sig);
1711 fZ[l++] += df[i]*df[j];
1729 void TFumili::FitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
1731 Foption_t fitOption = GetFitOption();
1732 if (fitOption.Integral) {
1733 FitChisquareI(npar,gin,f,u,flag);
1736 Double_t cu,eu,fu,fsum;
1741 TH1 *hfit = (TH1*)GetObjectFit();
1742 TF1 *f1 = (TF1*)GetUserFunc();
1743 Int_t nd = hfit->GetDimension();
1746 npar = f1->GetNpar();
1748 if(flag == 9)
return;
1752 Double_t *df =
new Double_t[npar];
1757 Double_t *cache = fCache;
1758 for (Int_t i=0;i<fNpoints;i++) {
1759 if (nd > 2) x[2] = cache[4];
1760 if (nd > 1) x[1] = cache[3];
1763 TF1::RejectPoint(kFALSE);
1764 fu = f1->EvalPar(x,u);
1765 if (TF1::RejectedPoint()) {cache += fPointSize;
continue;}
1771 for (j=0;j<npar;j++) {
1775 gin[j] += df[n]*fsum;
1781 for (Int_t k=0;k<=j;k++)
1782 zik[l++] += df[j]*df[k];
1786 cache += fPointSize;
1788 f1->SetNumberFitPoints(npfit);
1800 void TFumili::FitChisquareI(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
1802 Double_t cu,eu,fu,fsum;
1807 TH1 *hfit = (TH1*)GetObjectFit();
1808 TF1 *f1 = (TF1*)GetUserFunc();
1809 Int_t nd = hfit->GetDimension();
1813 npar = f1->GetNpar();
1815 if(flag == 9)
return;
1819 Double_t *df=
new Double_t[npar];
1823 Double_t *cache = fCache;
1824 for (Int_t i=0;i<fNpoints;i++) {
1826 TF1::RejectPoint(kFALSE);
1827 f1->SetParameters(u);
1829 fu = f1->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3])/cache[3];
1830 }
else if (nd < 3) {
1831 fu = ((TF2*)f1)->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3],cache[4] - 0.5*cache[5],cache[4] + 0.5*cache[5])/(cache[3]*cache[5]);
1833 fu = ((TF3*)f1)->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3],cache[4] - 0.5*cache[5],cache[4] + 0.5*cache[5],cache[6] - 0.5*cache[7],cache[6] + 0.5*cache[7])/(cache[3]*cache[5]*cache[7]);
1835 if (TF1::RejectedPoint()) {cache += fPointSize;
continue;}
1841 for (j=0;j<npar;j++) {
1845 gin[j] += df[n]*fsum;
1851 for (Int_t k=0;k<=j;k++)
1852 zik[l++] += df[j]*df[k];
1856 cache += fPointSize;
1858 f1->SetNumberFitPoints(npfit);
1875 void TFumili::FitLikelihood(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
1877 Foption_t fitOption = GetFitOption();
1878 if (fitOption.Integral) {
1879 FitLikelihoodI(npar,gin,f,u,flag);
1882 Double_t cu,fu,fobs,fsub;
1883 Double_t dersum[100];
1887 TH1 *hfit = (TH1*)GetObjectFit();
1888 TF1 *f1 = (TF1*)GetUserFunc();
1889 Int_t nd = hfit->GetDimension();
1891 Double_t *zik = GetZ();
1892 Double_t *pl0 = GetPL0();
1894 npar = f1->GetNpar();
1896 if(flag == 9)
return;
1897 Double_t *df=
new Double_t[npar];
1898 if (flag == 2)
for (j=0;j<npar;j++) dersum[j] = gin[j] = 0;
1903 Double_t *cache = fCache;
1904 for (Int_t i=0;i<fNpoints;i++) {
1905 if (nd > 2) x[2] = cache[4];
1906 if (nd > 1) x[1] = cache[3];
1909 TF1::RejectPoint(kFALSE);
1910 fu = f1->EvalPar(x,u);
1911 if (TF1::RejectedPoint()) {cache += fPointSize;
continue;}
1913 for (j=0;j<npar;j++) {
1918 if (fu < 1.e-9) fu = 1.e-9;
1920 fsub = -fu +icu*TMath::Log(fu);
1921 fobs = GetSumLog(icu);
1927 for (j=0;j<npar;j++) {
1929 df[n] = df[j]*(icu/fu-1);
1938 for (Int_t k=0;k<=j;k++)
1939 zik[l++] += df[j]*df[k];
1943 cache += fPointSize;
1946 f1->SetNumberFitPoints(npfit);
1963 void TFumili::FitLikelihoodI(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
1965 Double_t cu,fu,fobs,fsub;
1966 Double_t dersum[100];
1970 TH1 *hfit = (TH1*)GetObjectFit();
1971 TF1 *f1 = (TF1*)GetUserFunc();
1972 Int_t nd = hfit->GetDimension();
1974 Double_t *zik = GetZ();
1975 Double_t *pl0 = GetPL0();
1977 Double_t *df=
new Double_t[npar];
1979 npar = f1->GetNpar();
1981 if(flag == 9) {
delete [] df;
return;}
1982 if (flag == 2)
for (j=0;j<npar;j++) dersum[j] = gin[j] = 0;
1987 Double_t *cache = fCache;
1988 for (Int_t i=0;i<fNpoints;i++) {
1989 if (nd > 2) x[2] = cache[4];
1990 if (nd > 1) x[1] = cache[3];
1993 TF1::RejectPoint(kFALSE);
1995 fu = f1->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3])/cache[3];
1996 }
else if (nd < 3) {
1997 fu = ((TF2*)f1)->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3],cache[4] - 0.5*cache[5],cache[4] + 0.5*cache[5])/(cache[3]*cache[5]);
1999 fu = ((TF3*)f1)->Integral(cache[2] - 0.5*cache[3],cache[2] + 0.5*cache[3],cache[4] - 0.5*cache[5],cache[4] + 0.5*cache[5],cache[6] - 0.5*cache[7],cache[6] + 0.5*cache[7])/(cache[3]*cache[5]*cache[7]);
2001 if (TF1::RejectedPoint()) {cache += fPointSize;
continue;}
2003 for (j=0;j<npar;j++) {
2008 if (fu < 1.e-9) fu = 1.e-9;
2010 fsub = -fu +icu*TMath::Log(fu);
2011 fobs = GetSumLog(icu);
2017 for (j=0;j<npar;j++) {
2019 df[n] = df[j]*(icu/fu-1);
2028 for (Int_t k=0;k<=j;k++)
2029 zik[l++] += df[j]*df[k];
2033 cache += fPointSize;
2036 f1->SetNumberFitPoints(npfit);
2049 void H1FitChisquareFumili(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
2051 TFumili *hFitter = (TFumili*)TVirtualFitter::GetFitter();
2052 hFitter->FitChisquare(npar, gin, f, u, flag);
2067 void H1FitLikelihoodFumili(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
2070 TFumili *hFitter = (TFumili*)TVirtualFitter::GetFitter();
2071 hFitter->FitLikelihood(npar, gin, f, u, flag);
2103 void GraphFitChisquareFumili(Int_t &npar, Double_t * gin, Double_t &f,
2104 Double_t *u, Int_t flag)
2106 Double_t cu,eu,exl,exh,ey,eux,fu,fsum;
2108 Int_t i, bin, npfits=0;
2110 TFumili *grFitter = (TFumili*)TVirtualFitter::GetFitter();
2111 TGraph *gr = (TGraph*)grFitter->GetObjectFit();
2112 TF1 *f1 = (TF1*)grFitter->GetUserFunc();
2113 Foption_t fitOption = grFitter->GetFitOption();
2115 Int_t n = gr->GetN();
2116 Double_t *gx = gr->GetX();
2117 Double_t *gy = gr->GetY();
2118 npar = f1->GetNpar();
2120 grFitter->SetParNumber(npar);
2122 if(flag == 9)
return;
2123 Double_t *zik = grFitter->GetZ();
2124 Double_t *pl0 = grFitter->GetPL0();
2125 Double_t *df =
new Double_t[npar];
2130 for (bin=0;bin<n;bin++) {
2132 if (!f1->IsInside(x))
continue;
2134 TF1::RejectPoint(kFALSE);
2135 fu = f1->EvalPar(x,u);
2136 if (TF1::RejectedPoint())
continue;
2142 exh = gr->GetErrorXhigh(bin);
2143 exl = gr->GetErrorXlow(bin);
2144 ey = gr->GetErrorY(bin);
2145 if (exl < 0) exl = 0;
2146 if (exh < 0) exh = 0;
2148 if (exh > 0 && exl > 0) {
2150 eux = 0.5*(exl + exh)*f1->Derivative(x[0], u);
2154 if (eu <= 0) eu = 1;
2155 eusq = TMath::Sqrt(eu);
2157 grFitter->Derivatives(df,x);
2159 fsum = (fu-cu)/eusq;
2160 for (i=0;i<npar;i++) {
2164 gin[i] += df[n]*fsum;
2170 for (Int_t j=0;j<=i;j++)
2171 zik[l++] += df[i]*df[j];
2176 f1->SetNumberFitPoints(npfits);