348 static const char charal[29] =
" .ABCDEFGHIJKLMNOPQRSTUVWXYZ";
356 TMinuit::TMinuit(): TNamed(
"MINUIT",
"The Minimization package")
358 if (TMinuit::Class()->IsCallingNew() != TClass::kRealNew) {
437 fGraphicsMode = kTRUE;
455 fGraphicsMode = kTRUE;
462 R__LOCKGUARD(gROOTMutex);
463 gROOT->GetListOfSpecials()->Add(
this);
473 TMinuit::TMinuit(Int_t maxpar): TNamed(
"MINUIT",
"The Minimization package")
484 fGraphicsMode = kTRUE;
489 R__LOCKGUARD(gROOTMutex);
490 gROOT->GetListOfSpecials()->Add(
this);
498 TMinuit::TMinuit(
const TMinuit &minuit) : TNamed(minuit)
500 Error(
"TMinuit",
"can not copy construct TMinuit");
512 R__LOCKGUARD(gROOTMutex);
513 if (gROOT != 0 && gROOT->GetListOfSpecials() != 0) gROOT->GetListOfSpecials()->Remove(
this);
515 if (gMinuit ==
this) gMinuit =
nullptr;
521 void TMinuit::BuildArrays(Int_t maxpar)
524 if (maxpar >= fMaxpar) fMaxpar = maxpar+1;
525 fMaxpar1= fMaxpar*(fMaxpar+1);
527 fMaxpar5= fMaxpar1/2;
529 fCpnam =
new TString[fMaxpar2];
530 fU =
new Double_t[fMaxpar2];
531 fAlim =
new Double_t[fMaxpar2];
532 fBlim =
new Double_t[fMaxpar2];
533 fPstar =
new Double_t[fMaxpar2];
534 fGin =
new Double_t[fMaxpar2];
535 fNvarl =
new Int_t[fMaxpar2];
536 fNiofex =
new Int_t[fMaxpar2];
538 fNexofi =
new Int_t[fMaxpar];
539 fIpfix =
new Int_t[fMaxpar];
540 fErp =
new Double_t[fMaxpar];
541 fErn =
new Double_t[fMaxpar];
542 fWerr =
new Double_t[fMaxpar];
543 fGlobcc =
new Double_t[fMaxpar];
544 fX =
new Double_t[fMaxpar];
545 fXt =
new Double_t[fMaxpar];
546 fDirin =
new Double_t[fMaxpar];
547 fXs =
new Double_t[fMaxpar];
548 fXts =
new Double_t[fMaxpar];
549 fDirins =
new Double_t[fMaxpar];
550 fGrd =
new Double_t[fMaxpar];
551 fG2 =
new Double_t[fMaxpar];
552 fGstep =
new Double_t[fMaxpar];
553 fDgrd =
new Double_t[fMaxpar];
554 fGrds =
new Double_t[fMaxpar];
555 fG2s =
new Double_t[fMaxpar];
556 fGsteps =
new Double_t[fMaxpar];
557 fPstst =
new Double_t[fMaxpar];
558 fPbar =
new Double_t[fMaxpar];
559 fPrho =
new Double_t[fMaxpar];
560 fWord7 =
new Double_t[fMaxpar];
561 fVhmat =
new Double_t[fMaxpar5];
562 fVthmat =
new Double_t[fMaxpar5];
563 fP =
new Double_t[fMaxpar1];
564 fXpt =
new Double_t[fMaxcpt];
565 fYpt =
new Double_t[fMaxcpt];
566 fChpt =
new char[fMaxcpt+1];
569 fCONTgcc =
new Double_t[fMaxpar];
570 fCONTw =
new Double_t[fMaxpar];
571 fFIXPyy =
new Double_t[fMaxpar];
572 fGRADgf =
new Double_t[fMaxpar];
573 fHESSyy =
new Double_t[fMaxpar];
574 fIMPRdsav =
new Double_t[fMaxpar];
575 fIMPRy =
new Double_t[fMaxpar];
576 fMATUvline =
new Double_t[fMaxpar];
577 fMIGRflnu =
new Double_t[fMaxpar];
578 fMIGRstep =
new Double_t[fMaxpar];
579 fMIGRgs =
new Double_t[fMaxpar];
580 fMIGRvg =
new Double_t[fMaxpar];
581 fMIGRxxs =
new Double_t[fMaxpar];
582 fMNOTxdev =
new Double_t[fMaxpar];
583 fMNOTw =
new Double_t[fMaxpar];
584 fMNOTgcc =
new Double_t[fMaxpar];
585 fPSDFs =
new Double_t[fMaxpar];
586 fSEEKxmid =
new Double_t[fMaxpar];
587 fSEEKxbest =
new Double_t[fMaxpar];
588 fSIMPy =
new Double_t[fMaxpar];
589 fVERTq =
new Double_t[fMaxpar];
590 fVERTs =
new Double_t[fMaxpar];
591 fVERTpp =
new Double_t[fMaxpar];
592 fCOMDplist =
new Double_t[fMaxpar];
593 fPARSplist =
new Double_t[fMaxpar];
595 for (
int i = 0; i < fMaxpar; i++) {
605 TObject *TMinuit::Clone(
const char *newname)
const
607 TMinuit *named = (TMinuit*)TNamed::Clone(newname);
635 Int_t TMinuit::Command(
const char *command)
638 mncomd(command,status);
662 TObject *TMinuit::Contour(Int_t npoints, Int_t pa1, Int_t pa2)
670 Double_t *xcoor =
new Double_t[npoints+1];
671 Double_t *ycoor =
new Double_t[npoints+1];
672 mncont(pa1,pa2,npoints,xcoor,ycoor,npfound);
675 Warning(
"Contour",
"Cannot find more than 4 points, no TGraph returned");
676 fStatus= (npfound==0 ? 1 : npfound);
681 if (npfound!=npoints) {
683 Warning(
"Contour",
"Returning a TGraph with %d points only",npfound);
688 xcoor[npoints] = xcoor[0];
689 ycoor[npoints] = ycoor[0];
692 if ((h = gROOT->GetPluginManager()->FindHandler(
"TMinuitGraph"))) {
693 if (h->LoadPlugin() != -1)
694 gr = (TObject*)h->ExecPlugin(3,npoints+1,xcoor,ycoor);
704 Int_t TMinuit::DefineParameter( Int_t parNo,
const char *name, Double_t initVal, Double_t initErr, Double_t lowerLimit, Double_t upperLimit )
708 TString sname = name;
709 mnparm( parNo, sname, initVal, initErr, lowerLimit, upperLimit, err);
717 void TMinuit::DeleteArrays()
765 delete [] fMATUvline;
776 delete [] fSEEKxbest;
781 delete [] fCOMDplist;
782 delete [] fPARSplist;
809 Int_t TMinuit::Eval(Int_t npar, Double_t *grad, Double_t &fval, Double_t *par, Int_t flag)
829 if (fFCN) (*fFCN)(npar,grad,fval,par,flag);
836 Int_t TMinuit::FixParameter( Int_t parNo)
842 mnexcm(
"FIX", tmp, 1, err );
850 Int_t TMinuit::GetParameter( Int_t parNo, Double_t ¤tValue, Double_t ¤tError )
const
856 mnpout( parNo, name, currentValue, currentError, bnd1, bnd2, err );
864 Int_t TMinuit::GetNumFixedPars()
const
872 Int_t TMinuit::GetNumFreePars()
const
881 Int_t TMinuit::GetNumPars()
const
883 return fNpar + fNpfix;
889 Int_t TMinuit::Migrad()
895 mnexcm(
"MIGRAD", tmp, 0, err );
903 Int_t TMinuit::Release( Int_t parNo)
909 mnexcm(
"RELEASE", tmp, 1, err );
917 Int_t TMinuit::SetErrorDef( Double_t up )
921 mnexcm(
"SET ERRDEF", &up, 1, err );
929 void TMinuit::SetFCN(
void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
937 void InteractiveFCNm(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
939 TMethodCall *m = gMinuit->GetMethodCall();
943 args[0] = (Long_t)∦
944 args[1] = (Long_t)gin;
945 args[2] = (Long_t)&f;
947 args[4] = (Long_t)flag;
948 m->SetParamPtrs(args);
961 Int_t TMinuit::SetPrintLevel( Int_t printLevel )
967 mnexcm(
"SET PRINT", tmp, 1, err );
969 if (printLevel <=-1) mnexcm(
"SET NOWarnings",tmp,0,err);
981 void TMinuit::mnamin()
989 Printf(
" FIRST CALL TO USER FUNCTION AT NEW START POINT, WITH IFLAG=4.");
992 Eval(nparx, fGin, fnew, fU, 4); ++fNfcn;
1006 void TMinuit::mnbins(Double_t a1, Double_t a2, Int_t naa, Double_t &bl, Double_t &bh, Int_t &nb, Double_t &bwid)
1009 Double_t awid,ah, al, sigfig, sigrnd, alb;
1010 Int_t kwid, lwid, na=0, log_;
1012 al = TMath::Min(a1,a2);
1013 ah = TMath::Max(a1,a2);
1014 if (al == ah) ah = al + 1;
1017 if (naa == -1)
goto L150;
1024 awid = (ah-al) / Double_t(na);
1025 log_ = Int_t(TMath::Log10(awid));
1026 if (awid <= 1) --log_;
1027 sigfig = awid*TMath::Power(10, -log_);
1029 if (sigfig > 2)
goto L40;
1033 if (sigfig > 2.5)
goto L50;
1037 if (sigfig > 5)
goto L60;
1044 bwid = sigrnd*TMath::Power(10, log_);
1048 if (bwid <= 0)
goto L10;
1052 if (alb < 0) --lwid;
1053 bl = bwid*Double_t(lwid);
1054 alb = ah / bwid + 1;
1056 if (alb < 0) --kwid;
1057 bh = bwid*Double_t(kwid);
1059 if (naa > 5)
goto L240;
1060 if (naa == -1)
return;
1062 if (naa > 1 || nb == 1)
return;
1067 if (nb << 1 != naa)
return;
1079 void TMinuit::mncalf(Double_t *pvec, Double_t &ycalf)
1082 Int_t ndex, i, j, m, n, nparx;
1087 Eval(nparx, fGin, f, fU, 4); ++fNfcn;
1088 for (i = 1; i <= fNpar; ++i) {
1090 for (j = 1; j <= fNpar; ++j) {
1091 m = TMath::Max(i,j);
1092 n = TMath::Min(i,j);
1093 ndex = m*(m-1) / 2 + n;
1094 fGrd[i-1] += fVthmat[ndex-1]*(fXt[j-1] - pvec[j-1]);
1098 for (i = 1; i <= fNpar; ++i) {denom += fGrd[i-1]*(fXt[i-1] - pvec[i-1]); }
1104 ycalf = (f - fApsi) / denom;
1112 void TMinuit::mncler()
1122 for (i = 1; i <= fMaxext; ++i) {
1124 fCpnam[i-1] = fCundef;
1131 fCstatu =
"UNDEFINED ";
1141 void TMinuit::mncntr(Int_t ike1, Int_t ike2, Int_t &ierrf)
1143 static const char *
const clabel =
"0123456789ABCDEFGHIJ";
1146 Double_t d__1, d__2;
1147 Double_t fcna[115], fcnb[115], contur[20];
1148 Double_t ylabel, fmn, fmx, xlo, ylo, xup, yup;
1149 Double_t devs, xsav, ysav, bwidx, bwidy, unext, ff, xb4;
1150 Int_t i, ngrid, ixmid, nparx, ix, nx, ny, ki1, ki2, ixzero, iy, ics;
1151 TString chmid, chln, chzero;
1155 if (ke1 <= 0 || ke2 <= 0)
goto L1350;
1156 if (ke1 > fNu || ke2 > fNu)
goto L1350;
1157 ki1 = fNiofex[ke1-1];
1158 ki2 = fNiofex[ke2-1];
1159 if (ki1 <= 0 || ki2 <= 0)
goto L1350;
1160 if (ki1 == ki2)
goto L1350;
1170 if (devs <= 0) devs = 2;
1171 xlo = fU[ke1-1] - devs*fWerr[ki1-1];
1172 xup = fU[ke1-1] + devs*fWerr[ki1-1];
1173 ylo = fU[ke2-1] - devs*fWerr[ki2-1];
1174 yup = fU[ke2-1] + devs*fWerr[ki2-1];
1175 ngrid = Int_t(fWord7[3]);
1179 nx = TMath::Min(fNpagwd - 15,ngrid);
1181 ny = TMath::Min(fNpagln - 7,ngrid);
1186 if (nx < 11) nx = 11;
1187 if (ny < 11) ny = 11;
1188 if (nx >= 115) nx = 114;
1191 if (fNvarl[ke1-1] > 1) {
1192 if (xlo < fAlim[ke1-1]) xlo = fAlim[ke1-1];
1193 if (xup > fBlim[ke1-1]) xup = fBlim[ke1-1];
1195 if (fNvarl[ke2-1] > 1) {
1196 if (ylo < fAlim[ke2-1]) ylo = fAlim[ke2-1];
1197 if (yup > fBlim[ke2-1]) yup = fBlim[ke2-1];
1199 bwidx = (xup - xlo) / Double_t(nx);
1200 bwidy = (yup - ylo) / Double_t(ny);
1201 ixmid = Int_t(((xsav - xlo)*Double_t(nx) / (xup - xlo)) + 1);
1202 if (ixmid < 1) ixmid = 1;
1203 if (fAmin == fUndefi) mnamin();
1205 for (i = 1; i <= 20; ++i) { contur[i-1] = fAmin + fUp*(i-1)*(i-1); }
1206 contur[0] += fUp*.01;
1213 chzero.Resize(nx+1);
1215 for (ix = 1; ix <= nx + 1; ++ix) {
1216 fU[ke1-1] = xlo + Double_t(ix-1)*bwidx;
1217 Eval(nparx, fGin, ff, fU, 4);
1219 if (xb4 < 0 && fU[ke1-1] > 0) ixzero = ix - 1;
1224 Printf(
" Y-AXIS: PARAMETER %3d: %s",ke2,(
const char*)fCpnam[ke2-1]);
1226 chzero[ixzero-1] =
'+';
1231 for (iy = 1; iy <= ny; ++iy) {
1232 unext = fU[ke2-1] - bwidy;
1237 chln[ixmid-1] =
'*';
1238 if (ixzero != 0) chln[ixzero-1] =
':';
1239 if (fU[ke2-1] > ysav && unext < ysav) chln = chmid;
1240 if (fU[ke2-1] > 0 && unext < 0) chln = chzero;
1242 ylabel = fU[ke2-1] + bwidy*.5;
1244 for (ix = 1; ix <= nx + 1; ++ix) {
1245 fcna[ix-1] = fcnb[ix-1];
1246 fU[ke1-1] = xlo + Double_t(ix-1)*bwidx;
1247 Eval(nparx, fGin, ff, fU, 4);
1251 for (ix = 1; ix <= nx; ++ix) {
1252 d__1 = TMath::Max(fcna[ix-1],fcnb[ix-1]),
1253 d__2 = TMath::Max(fcna[ix],fcnb[ix]);
1254 fmx = TMath::Max(d__1,d__2);
1255 d__1 = TMath::Min(fcna[ix-1],fcnb[ix-1]),
1256 d__2 = TMath::Min(fcna[ix],fcnb[ix]);
1257 fmn = TMath::Min(d__1,d__2);
1258 for (ics = 1; ics <= 20; ++ics) {
1259 if (contur[ics-1] > fmn)
goto L240;
1263 if (contur[ics-1] < fmx) chln[ix-1] = clabel[ics-1];
1266 Printf(
" %12.4g %s",ylabel,(
const char*)chln);
1271 chln(ixmid-1,1) =
'I';
1273 Printf(
" %s",(
const char*)chln);
1278 Printf(
" %12.4g%s%12.4g",xlo,(
const char*)chln,xup);
1279 Printf(
" %s%12.4g",(
const char*)chln,xsav);
1281 Printf(
" %12.4g%s%12.4g%s%12.4g",xlo,(
const char*)chln,xsav,(
const char*)chln,xup);
1283 Printf(
" X-AXIS: PARAMETER %3d %s ONE COLUMN=%12.4g"
1284 ,ke1,(
const char*)fCpnam[ke1-1],bwidx);
1285 Printf(
" FUNCTION VALUES: F(I)=%12.4g +%12.4g *I**2",fAmin,fUp);
1292 Printf(
" INVALID PARAMETER NUMBER(S) REQUESTED. IGNORED.");
1319 void TMinuit::mncomd(
const char *crdbin, Int_t &icondn)
1322 Int_t ierr, ipos, i, llist, lenbuf, lnc;
1324 TString comand, crdbuf, ctemp;
1328 lenbuf = crdbuf.Length();
1333 for (i = 1; i <= TMath::Min(20,lenbuf); ++i) {
1334 if (crdbuf[i-1] ==
'\'')
break;
1335 if (crdbuf[i-1] ==
' ') {
1343 if (ipos > lenbuf) {
1344 Printf(
" BLANK COMMAND IGNORED.");
1350 if (crdbuf(ipos-1,3) ==
"PAR") {
1356 if (crdbuf(ipos-1,3) ==
"SET INP") {
1362 if (crdbuf(ipos-1,7) ==
"SET TIT") {
1368 if (crdbuf(ipos-1,7) ==
"SET COV") {
1374 ctemp = crdbuf(ipos-1,lenbuf-ipos+1);
1375 mncrck(ctemp, 20, comand, lnc, fMaxpar, fCOMDplist, llist, ierr, fIsyswr);
1377 Printf(
" COMMAND CANNOT BE INTERPRETED");
1382 mnexcm(comand.Data(), fCOMDplist, llist, ierr);
1404 void TMinuit::mncont(Int_t ike1, Int_t ike2, Int_t nptu, Double_t *xptu, Double_t *yptu, Int_t &ierrf)
1410 Double_t d__1, d__2;
1411 Double_t dist, xdir, ydir, aopt, u1min, u2min;
1412 Double_t abest, scalx, scaly;
1413 Double_t a1, a2, val2mi, val2pl, dc, sclfac, bigdis, sigsav;
1414 Int_t nall, iold, line, mpar, ierr, inew, move, next, i, j, nfcol, iercr;
1415 Int_t idist=0, npcol, kints, i2, i1, lr, nfcnco=0, ki1, ki2, ki3, ke3;
1416 Int_t nowpts, istrav, nfmxin, isw2, isw4;
1422 ldebug = fIdbg[6] >= 1;
1423 if (ke1 <= 0 || ke2 <= 0)
goto L1350;
1424 if (ke1 > fNu || ke2 > fNu)
goto L1350;
1425 ki1 = fNiofex[ke1-1];
1426 ki2 = fNiofex[ke2-1];
1427 if (ki1 <= 0 || ki2 <= 0)
goto L1350;
1428 if (ki1 == ki2)
goto L1350;
1429 if (nptu < 4)
goto L1400;
1432 fNfcnmx = (nptu + 5)*100*(fNpar + 1);
1438 fCfrom =
"MNContour ";
1441 Printf(
" START MNCONTOUR CALCULATION OF %4d POINTS ON CONTOUR.",nptu);
1444 ki3 = 6 - ki1 - ki2;
1445 ke3 = fNexofi[ki3-1];
1446 Printf(
" EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER %3d %s",ke3,(
const char*)fCpnam[ke3-1]);
1448 Printf(
" EACH POINT IS A MINIMUM WITH RESPECT TO THE OTHER %3d VARIABLE PARAMETERS.",fNpar - 2);
1455 mnmnot(ke1, ke2, val2pl, val2mi);
1456 if (fErn[ki1-1] == fUndefi) {
1457 xptu[0] = fAlim[ke1-1];
1458 mnwarn(
"W",
"MNContour ",
"Contour squeezed by parameter limits.");
1460 if (fErn[ki1-1] >= 0)
goto L1500;
1461 xptu[0] = u1min + fErn[ki1-1];
1465 if (fErp[ki1-1] == fUndefi) {
1466 xptu[2] = fBlim[ke1-1];
1467 mnwarn(
"W",
"MNContour ",
"Contour squeezed by parameter limits.");
1469 if (fErp[ki1-1] <= 0)
goto L1500;
1470 xptu[2] = u1min + fErp[ki1-1];
1473 scalx = 1 / (xptu[2] - xptu[0]);
1475 mnmnot(ke2, ke1, val2pl, val2mi);
1476 if (fErn[ki2-1] == fUndefi) {
1477 yptu[1] = fAlim[ke2-1];
1478 mnwarn(
"W",
"MNContour ",
"Contour squeezed by parameter limits.");
1480 if (fErn[ki2-1] >= 0)
goto L1500;
1481 yptu[1] = u2min + fErn[ki2-1];
1484 if (fErp[ki2-1] == fUndefi) {
1485 yptu[3] = fBlim[ke2-1];
1486 mnwarn(
"W",
"MNContour ",
"Contour squeezed by parameter limits.");
1488 if (fErp[ki2-1] <= 0)
goto L1500;
1489 yptu[3] = u2min + fErp[ki2-1];
1492 scaly = 1 / (yptu[3] - yptu[1]);
1496 Printf(
" Plot of four points found by MINOS");
1501 nall = TMath::Min(nowpts + 1,101);
1502 for (i = 2; i <= nall; ++i) {
1503 fXpt[i-1] = xptu[i-2];
1504 fYpt[i-1] = yptu[i-2];
1506 sprintf(fChpt,
"%s",
" ABCD");
1507 mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1520 for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
1521 i__1 = mpar*(mpar + 1) / 2;
1522 for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
1523 for (i = 1; i <= mpar; ++i) {
1524 fCONTgcc[i-1] = fGlobcc[i-1];
1525 fCONTw[i-1] = fWerr[i-1];
1528 kints = fNiofex[ke1-1];
1529 mnfixp(kints-1, ierr);
1530 kints = fNiofex[ke2-1];
1531 mnfixp(kints-1, ierr);
1533 for (inew = next; inew <= nptu; ++inew) {
1536 for (iold = 1; iold <= inew - 1; ++iold) {
1538 if (i2 == inew) i2 = 1;
1539 d__1 = scalx*(xptu[iold-1] - xptu[i2-1]);
1540 d__2 = scaly*(yptu[iold-1] - yptu[i2-1]);
1541 dist = d__1*d__1 + d__2*d__2;
1542 if (dist > bigdis) {
1549 if (i2 == inew) i2 = 1;
1554 fXmidcr = a1*xptu[i1-1] + a2*xptu[i2-1];
1555 fYmidcr = a1*yptu[i1-1] + a2*yptu[i2-1];
1556 xdir = yptu[i2-1] - yptu[i1-1];
1557 ydir = xptu[i1-1] - xptu[i2-1];
1558 sclfac = TMath::Max(TMath::Abs(xdir*scalx),TMath::Abs(ydir*scaly));
1559 fXdircr = xdir / sclfac;
1560 fYdircr = ydir / sclfac;
1565 mncros(aopt, iercr);
1570 Printf(
" MNCONT CANNOT FIND NEXT POINT ON CONTOUR. ONLY %3d POINTS FOUND.",nowpts);
1574 mnwarn(
"W",
"MNContour ",
"Cannot find midpoint, try closer.");
1580 for (move = nowpts; move >= i1 + 1; --move) {
1581 xptu[move] = xptu[move-1];
1582 yptu[move] = yptu[move-1];
1585 xptu[i1] = fXmidcr + fXdircr*aopt;
1586 yptu[i1] = fYmidcr + fYdircr*aopt;
1591 fCstatu =
"SUCCESSFUL";
1592 if (nowpts < nptu) fCstatu =
"INCOMPLETE";
1599 nall = TMath::Min(nowpts + 1,101);
1600 for (i = 2; i <= nall; ++i) {
1601 fXpt[i-1] = xptu[i-2];
1602 fYpt[i-1] = yptu[i-2];
1606 Printf(
" Y-AXIS: PARAMETER %3d %s",ke2,(
const char*)fCpnam[ke2-1]);
1608 mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1610 Printf(
" X-AXIS: PARAMETER %3d %s",ke1,(
const char*)fCpnam[ke1-1]);
1614 npcol = (nowpts + 1) / 2;
1616 Printf(
"%5d POINTS ON CONTOUR. FMIN=%13.5e ERRDEF=%11.3g",nowpts,abest,fUp);
1617 Printf(
" %s%s%s%s",(
const char*)fCpnam[ke1-1],
1618 (
const char*)fCpnam[ke2-1],
1619 (
const char*)fCpnam[ke1-1],
1620 (
const char*)fCpnam[ke2-1]);
1621 for (line = 1; line <= nfcol; ++line) {
1623 Printf(
" %5d%13.5e%13.5e %5d%13.5e%13.5e",line,xptu[line-1],yptu[line-1],lr,xptu[lr-1],yptu[lr-1]);
1625 if (nfcol < npcol) {
1626 Printf(
" %5d%13.5e%13.5e",npcol,xptu[npcol-1],yptu[npcol-1]);
1633 i__1 = mpar*(mpar + 1) / 2;
1634 for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
1635 for (i = 1; i <= mpar; ++i) {
1636 fGlobcc[i-1] = fCONTgcc[i-1];
1637 fWerr[i-1] = fCONTw[i-1];
1654 Printf(
" INVALID PARAMETER NUMBERS.");
1657 Printf(
" LESS THAN FOUR POINTS REQUESTED.");
1660 fCstatu =
"USER ERROR";
1663 Printf(
" MNCONT UNABLE TO FIND FOUR POINTS.");
1669 fCfrom =
"MNContour ";
1686 void TMinuit::mncrck(TString cardbuf, Int_t maxcwd, TString &comand, Int_t &lnc,
1687 Int_t mxp, Double_t *plist, Int_t &llist, Int_t &ierr, Int_t)
1692 const char *cnumer =
"123456789-.0+";
1695 Int_t ifld, iend, lend, left, nreq, ipos, kcmnd, nextb, ic, ibegin, ltoadd;
1696 Int_t ielmnt, lelmnt[25], nelmnt;
1702 char *crdbuf = (
char*)cardbuf.Data();
1703 lend = cardbuf.Length();
1709 for (ipos = nextb; ipos <= lend; ++ipos) {
1711 if (crdbuf[ipos-1] ==
' ')
continue;
1712 if (crdbuf[ipos-1] ==
',')
goto L250;
1718 for (ipos = ibegin + 1; ipos <= lend; ++ipos) {
1719 if (crdbuf[ipos-1] ==
' ')
goto L250;
1720 if (crdbuf[ipos-1] ==
',')
goto L250;
1726 if (iend >= ibegin) celmnt[ielmnt-1] = &crdbuf[ibegin-1];
1727 else celmnt[ielmnt-1] = cnull;
1728 lelmnt[ielmnt-1] = iend - ibegin + 1;
1729 if (lelmnt[ielmnt-1] > 19) {
1730 Printf(
" MINUIT WARNING: INPUT DATA WORD TOO LONG.");
1731 ctemp = cardbuf(ibegin-1,iend-ibegin+1);
1732 Printf(
" ORIGINAL:%s",ctemp.Data());
1733 Printf(
" TRUNCATED TO:%s",celmnt[ielmnt-1]);
1734 lelmnt[ielmnt-1] = 19;
1736 if (ipos >= lend)
goto L300;
1737 if (ielmnt >= 25)
goto L300;
1739 for (ipos = iend + 1; ipos <= lend; ++ipos) {
1740 if (crdbuf[ipos-1] ==
' ')
continue;
1742 if (crdbuf[ipos-1] ==
',') nextb = ipos + 1;
1749 command[0] =
' '; command[1] = 0;
1753 if (ielmnt == 0)
goto L900;
1755 for (ielmnt = 1; ielmnt <= nelmnt; ++ielmnt) {
1756 if ( celmnt[ielmnt-1] == cnull)
goto L450;
1757 for (ic = 1; ic <= 13; ++ic) {
1758 if (*celmnt[ielmnt-1] == cnumer[ic-1])
goto L450;
1760 if (kcmnd >= maxcwd)
continue;
1761 left = maxcwd - kcmnd;
1762 ltoadd = lelmnt[ielmnt-1];
1763 if (ltoadd > left) ltoadd = left;
1764 strncpy(&command[kcmnd],celmnt[ielmnt-1],ltoadd);
1766 if (kcmnd == maxcwd)
continue;
1767 command[kcmnd] =
' ';
1777 for (ifld = ielmnt; ifld <= nelmnt; ++ifld) {
1780 nreq = nelmnt - ielmnt + 1;
1781 Printf(
" MINUIT WARNING IN MNCRCK: ");
1782 Printf(
" COMMAND HAS INPUT %5d NUMERIC FIELDS, BUT MINUIT CAN ACCEPT ONLY%3d",nreq,mxp);
1785 if (celmnt[ifld-1] == cnull) plist[llist-1] = 0;
1787 sscanf(celmnt[ifld-1],
"%lf",&plist[llist-1]);
1792 if (lnc <= 0) lnc = 1;
1807 void TMinuit::mncros(Double_t &aopt, Int_t &iercr)
1810 Double_t alsb[3], flsb[3], bmin, bmax, zmid, sdev, zdir, zlim;
1811 Double_t coeff[3], aleft, aulim, fdist, adist, aminsv;
1812 Double_t anext, fnext, slope, s1, s2, x1, x2, ecarmn, ecarmx;
1813 Double_t determ, rt, smalla, aright, aim, tla, tlf, dfda,ecart;
1814 Int_t iout=0, i, ileft, ierev, maxlk, ibest, ik, it;
1815 Int_t noless, iworst=0, iright, itoohi, kex, ipt;
1820 ldebug = fIdbg[6] >= 1;
1839 for (ik = 1; ik <= 2; ++ik) {
1845 if (fKe2cr == 0)
continue;
1850 if (fNvarl[kex-1] <= 1)
continue;
1851 if (zdir == 0)
continue;
1852 zlim = fAlim[kex-1];
1853 if (zdir > 0) zlim = fBlim[kex-1];
1854 aulim = TMath::Min(aulim,(zlim - zmid) / zdir);
1861 if (aulim < aopt + tla) fLimset = kTRUE;
1862 mneval(anext, fnext, ierev);
1865 Printf(
" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1867 if (ierev > 0)
goto L900;
1868 if (fLimset && fnext <= aim)
goto L930;
1870 fXpt[ipt-1] = anext;
1871 fYpt[ipt-1] = fnext;
1872 fChpt[ipt-1] = charal[ipt-1];
1875 fnext = TMath::Max(fnext,aminsv + fUp*.1);
1876 aopt = TMath::Sqrt(fUp / (fnext - aminsv)) - 1;
1877 if (TMath::Abs(fnext - aim) < tlf)
goto L800;
1879 if (aopt < -.5)aopt = -.5;
1880 if (aopt > 1) aopt = 1;
1886 mneval(aopt, fnext, ierev);
1889 Printf(
" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1891 if (ierev > 0)
goto L900;
1892 if (fLimset && fnext <= aim)
goto L930;
1895 fXpt[ipt-1] = alsb[1];
1896 fYpt[ipt-1] = fnext;
1897 fChpt[ipt-1] = charal[ipt-1];
1899 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1901 if (dfda > 0)
goto L460;
1903 mnwarn(
"D",
"MNCROS ",
"Looking for slope of the right sign");
1905 for (it = 1; it <= maxlk; ++it) {
1908 aopt = alsb[0] + Double_t(it)*.2;
1914 mneval(aopt, fnext, ierev);
1917 Printf(
" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1919 if (ierev > 0)
goto L900;
1920 if (fLimset && fnext <= aim)
goto L930;
1923 fXpt[ipt-1] = alsb[1];
1924 fYpt[ipt-1] = fnext;
1925 fChpt[ipt-1] = charal[ipt-1];
1927 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1928 if (dfda > 0)
goto L450;
1930 mnwarn(
"W",
"MNCROS ",
"Cannot find slope of the right sign");
1935 aopt = alsb[1] + (aim - flsb[1]) / dfda;
1936 fdist = TMath::Min(TMath::Abs(aim - flsb[0]),TMath::Abs(aim - flsb[1]));
1937 adist = TMath::Min(TMath::Abs(aopt - alsb[0]),TMath::Abs(aopt - alsb[1]));
1939 if (TMath::Abs(aopt) > 1) tla = TMath::Abs(aopt)*.01;
1940 if (adist < tla && fdist < tlf)
goto L800;
1941 if (ipt >= 15)
goto L950;
1942 bmin = TMath::Min(alsb[0],alsb[1]) - 1;
1943 if (aopt < bmin) aopt = bmin;
1944 bmax = TMath::Max(alsb[0],alsb[1]) + 1;
1945 if (aopt > bmax) aopt = bmax;
1952 mneval(aopt, fnext, ierev);
1955 Printf(
" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1957 if (ierev > 0)
goto L900;
1958 if (fLimset && fnext <= aim)
goto L930;
1961 fXpt[ipt-1] = alsb[2];
1962 fYpt[ipt-1] = fnext;
1963 fChpt[ipt-1] = charal[ipt-1];
1966 ecarmn = TMath::Abs(fnext-aim);
1970 for (i = 1; i <= 3; ++i) {
1971 ecart = TMath::Abs(flsb[i-1] - aim);
1972 if (ecart > ecarmx) { ecarmx = ecart; iworst = i; }
1973 if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
1974 if (flsb[i-1] < aim) ++noless;
1977 if (noless == 1 || noless == 2)
goto L500;
1979 if (noless == 0 && ibest != 3)
goto L950;
1982 if (noless == 3 && ibest != 3) {
1988 alsb[iworst-1] = alsb[2];
1989 flsb[iworst-1] = flsb[2];
1990 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1994 mnpfit(alsb, flsb, 3, coeff, sdev);
1995 if (coeff[2] <= 0) {
1996 mnwarn(
"D",
"MNCROS ",
"Curvature is negative near contour line.");
1998 determ = coeff[1]*coeff[1] - coeff[2]*4*(coeff[0] - aim);
2000 mnwarn(
"D",
"MNCROS ",
"Problem 2, impossible determinant");
2004 rt = TMath::Sqrt(determ);
2005 x1 = (-coeff[1] + rt) / (coeff[2]*2);
2006 x2 = (-coeff[1] - rt) / (coeff[2]*2);
2007 s1 = coeff[1] + x1*2*coeff[2];
2008 s2 = coeff[1] + x2*2*coeff[2];
2010 Printf(
" MNCONTour problem 1");
2020 if (TMath::Abs(aopt) > 1) tla = TMath::Abs(aopt)*.01;
2021 if (TMath::Abs(aopt - alsb[ibest-1]) < tla && TMath::Abs(flsb[ibest-1] - aim) < tlf) {
2024 if (ipt >= 15)
goto L950;
2032 ecarmn = TMath::Abs(aim - flsb[0]);
2033 for (i = 1; i <= 3; ++i) {
2034 ecart = TMath::Abs(flsb[i-1] - aim);
2035 if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
2036 if (ecart > ecarmx) { ecarmx = ecart; }
2037 if (flsb[i-1] > aim) {
2038 if (iright == 0) iright = i;
2039 else if (flsb[i-1] > flsb[iright-1]) iout = i;
2040 else { iout = iright; iright = i; }
2042 else if (ileft == 0) ileft = i;
2043 else if (flsb[i-1] < flsb[ileft-1]) iout = i;
2044 else { iout = ileft; ileft = i; }
2047 if (ecarmx > TMath::Abs(flsb[iout-1] - aim)*10) {
2048 aopt = aopt*.5 + (alsb[iright-1] + alsb[ileft-1])*.25;
2052 if (slope*smalla > tlf) smalla = tlf / slope;
2053 aleft = alsb[ileft-1] + smalla;
2054 aright = alsb[iright-1] - smalla;
2056 if (aopt < aleft) aopt = aleft;
2057 if (aopt > aright) aopt = aright;
2058 if (aleft > aright) aopt = (aleft + aright)*.5;
2067 mneval(aopt, fnext, ierev);
2070 Printf(
" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
2072 if (ierev > 0)
goto L900;
2073 if (fLimset && fnext <= aim)
goto L930;
2076 fYpt[ipt-1] = fnext;
2077 fChpt[ipt-1] = charal[ipt-1];
2079 alsb[iout-1] = aopt;
2080 flsb[iout-1] = fnext;
2092 if (ierev == 1)
goto L940;
2109 for (i = 1; i <= ipt; ++i) {
2110 if (fYpt[i-1] > aim + fUp) {
2111 fYpt[i-1] = aim + fUp;
2118 if (fXdircr < 0) chsign =
"NEGA";
2120 Printf(
" %sTIVE MINOS ERROR, PARAMETER %3d",chsign,fKe1cr);
2123 Printf(
"POINTS LABELLED '+' WERE TOO HIGH TO PLOT.");
2126 Printf(
"RIGHTMOST POINT IS UP AGAINST LIMIT.");
2128 mnplot(fXpt, fYpt, fChpt, ipt, fNpagwd, fNpagln);
2139 void TMinuit::mncuve()
2142 Double_t dxdi, wint;
2143 Int_t ndex, iext, i, j;
2146 Printf(
" FUNCTION MUST BE MINIMIZED BEFORE CALLING %s",(
const char*)fCfrom);
2153 mnwarn(
"W", fCfrom,
"NO ERROR MATRIX. WILL IMPROVISE.");
2154 for (i = 1; i <= fNpar; ++i) {
2156 for (j = 1; j <= i-1; ++j) {
2161 if (fG2[i-1] <= 0) {
2163 iext = fNexofi[i-1];
2164 if (fNvarl[iext-1] > 1) {
2165 mndxdi(fX[i-1], i-1, dxdi);
2166 if (TMath::Abs(dxdi) < .001) wint = .01;
2167 else wint /= TMath::Abs(dxdi);
2169 fG2[i-1] = fUp / (wint*wint);
2171 fVhmat[ndex-1] = 2 / fG2[i-1];
2187 void TMinuit::mnderi()
2190 Double_t step, dfmin, stepb4, dd, df, fs1;
2191 Double_t tlrstp, tlrgrd, epspri, optstp, stpmax, stpmin, fs2, grbfor=0, d1d2, xtf;
2192 Int_t icyc, ncyc, iint, iext, i, nparx;
2196 ldebug = fIdbg[2] >= 1;
2197 if (fAmin == fUndefi) mnamin();
2198 if (fISW[2] == 1)
goto L100;
2204 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
2207 mnwarn(
"D",
"MNDERI", TString::Format(
"function value differs from AMIN by %12.3g",df));
2210 Printf(
" FIRST DERIVATIVE DEBUG PRINTOUT. MNDERI");
2211 Printf(
" PAR DERIV STEP MINSTEP OPTSTEP D1-D2 2ND DRV");
2213 dfmin = fEpsma2*8*(TMath::Abs(fAmin) + fUp);
2218 }
else if (fIstrat == 1) {
2228 for (i = 1; i <= fNpar; ++i) {
2229 epspri = fEpsma2 + TMath::Abs(fGrd[i-1]*fEpsma2);
2235 for (icyc = 1; icyc <= ncyc; ++icyc) {
2237 optstp = TMath::Sqrt(dfmin / (TMath::Abs(fG2[i-1]) + epspri));
2239 step = TMath::Max(optstp,TMath::Abs(fGstep[i-1]*.1));
2241 if (fGstep[i-1] < 0 && step > .5) step = .5;
2243 stpmax = TMath::Abs(fGstep[i-1])*10;
2244 if (step > stpmax) step = stpmax;
2246 stpmin = TMath::Abs(fEpsma2*fX[i-1])*8;
2247 if (step < stpmin) step = stpmin;
2249 if (TMath::Abs((step - stepb4) / step) < tlrstp)
goto L50;
2252 if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(step);
2253 else fGstep[i-1] = -TMath::Abs(step);
2255 fX[i-1] = xtf + step;
2257 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
2259 fX[i-1] = xtf - step;
2261 Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
2263 fGrd[i-1] = (fs1 - fs2) / (step*2);
2264 fG2[i-1] = (fs1 + fs2 - fAmin*2) / (step*step);
2267 d1d2 = (fs1 + fs2 - fAmin*2) / step;
2268 Printf(
"%4d%11.3g%11.3g%10.2g%10.2g%10.2g%10.2g",i,fGrd[i-1],step,stpmin,optstp,d1d2,fG2[i-1]);
2271 if (TMath::Abs(grbfor - fGrd[i-1]) / (TMath::Abs(fGrd[i-1]) + dfmin/step) < tlrgrd)
2275 if (ncyc == 1)
goto L50;
2276 mnwarn(
"D",
"MNDERI", TString::Format(
"First derivative not converged. %g%g",fGrd[i-1],grbfor));
2284 for (iint = 1; iint <= fNpar; ++iint) {
2285 iext = fNexofi[iint-1];
2286 if (fNvarl[iext-1] <= 1) {
2287 fGrd[iint-1] = fGin[iext-1];
2289 dd = (fBlim[iext-1] - fAlim[iext-1])*.5*TMath::Cos(fX[iint-1]);
2290 fGrd[iint-1] = fGin[iext-1]*dd;
2302 void TMinuit::mndxdi(Double_t pint, Int_t ipar, Double_t &dxdi)
2304 Int_t i = fNexofi[ipar];
2306 if (fNvarl[i-1] > 1) {
2307 dxdi = TMath::Abs((fBlim[i-1] - fAlim[i-1])*TMath::Cos(pint))*.5;
2314 void TMinuit::mneig(Double_t *a, Int_t ndima, Int_t n, Int_t mits, Double_t *work, Double_t precis, Int_t &ifault)
2321 Double_t b, c, f, h, r, s, hh, gl, pr, pt;
2322 Int_t i, j, k, l, m=0, i0, i1, j1, m1, n1;
2326 a_offset = ndima + 1;
2334 for (i1 = 2; i1 <= n; ++i1) {
2336 f = a[i + (i-1)*ndima];
2339 if (l < 1)
goto L25;
2341 for (k = 1; k <= l; ++k) {
2342 d__1 = a[i + k*ndima];
2348 if (gl > 1e-35)
goto L30;
2355 gl = TMath::Sqrt(h);
2356 if (f >= 0) gl = -gl;
2359 a[i + (i-1)*ndima] = f - gl;
2361 for (j = 1; j <= l; ++j) {
2362 a[j + i*ndima] = a[i + j*ndima] / h;
2364 for (k = 1; k <= j; ++k) { gl += a[j + k*ndima]*a[i + k*ndima]; }
2365 if (j >= l)
goto L47;
2367 for (k = j1; k <= l; ++k) { gl += a[k + j*ndima]*a[i + k*ndima]; }
2369 work[n + j] = gl / h;
2370 f += gl*a[j + i*ndima];
2373 for (j = 1; j <= l; ++j) {
2375 gl = work[n + j] - hh*f;
2377 for (k = 1; k <= j; ++k) {
2378 a[j + k*ndima] = a[j + k*ndima] - f*work[n + k] - gl*a[i + k*ndima];
2387 for (i = 1; i <= n; ++i) {
2389 if (work[i] == 0 || l == 0)
goto L100;
2391 for (j = 1; j <= l; ++j) {
2393 for (k = 1; k <= l; ++k) { gl += a[i + k*ndima]*a[k + j*ndima]; }
2394 for (k = 1; k <= l; ++k) { a[k + j*ndima] -= gl*a[k + i*ndima]; }
2397 work[i] = a[i + i*ndima];
2399 if (l == 0)
continue;
2401 for (j = 1; j <= l; ++j) {
2408 for (i = 2; i <= n; ++i) {
2410 work[i0] = work[i0 + 1];
2415 for (l = 1; l <= n; ++l) {
2417 h = precis*(TMath::Abs(work[l]) + TMath::Abs(work[n + l]));
2419 for (m1 = l; m1 <= n; ++m1) {
2421 if (TMath::Abs(work[n + m]) <= b)
goto L150;
2425 if (m == l)
goto L205;
2428 if (j == mits)
return;
2430 pt = (work[l + 1] - work[l]) / (work[n + l]*2);
2431 r = TMath::Sqrt(pt*pt + 1);
2433 if (pt < 0) pr = pt - r;
2435 h = work[l] - work[n + l] / pr;
2436 for (i = l; i <= n; ++i) { work[i] -= h; }
2443 for (i1 = l; i1 <= m1; ++i1) {
2448 if (TMath::Abs(pt) >= TMath::Abs(work[n + i]))
goto L180;
2450 c = pt / work[n + i];
2451 r = TMath::Sqrt(c*c + 1);
2452 work[n + j] = s*work[n + i]*r;
2457 c = work[n + i] / pt;
2458 r = TMath::Sqrt(c*c + 1);
2459 work[n + j] = s*pt*r;
2463 pt = c*work[i] - s*gl;
2464 work[j] = h + s*(c*gl + s*work[i]);
2465 for (k = 1; k <= n; ++k) {
2467 a[k + j*ndima] = s*a[k + i*ndima] + c*h;
2468 a[k + i*ndima] = c*a[k + i*ndima] - s*h;
2474 if (TMath::Abs(work[n + l]) > b)
goto L160;
2479 for (i = 1; i <= n1; ++i) {
2483 for (j = i1; j <= n; ++j) {
2484 if (work[j] >= pt)
continue;
2489 if (k == i)
continue;
2493 for (j = 1; j <= n; ++j) {
2494 pt = a[j + i*ndima];
2495 a[j + i*ndima] = a[j + k*ndima];
2496 a[j + k*ndima] = pt;
2510 void TMinuit::mnemat(Double_t *emat, Int_t ndim)
2513 Int_t emat_dim1, emat_offset;
2516 Double_t dxdi, dxdj;
2517 Int_t i, j, k, npard, k2, kk, iz, nperln, kga, kgb;
2522 emat_offset = emat_dim1 + 1;
2523 emat -= emat_offset;
2526 if (fISW[1] < 1)
return;
2528 Printf(
" EXTERNAL ERROR MATRIX. NDIM=%4d NPAR=%3d ERR DEF=%g",ndim,fNpar,fUp);
2535 Printf(
" USER-DIMENSIONED ARRAY EMAT NOT BIG ENOUGH. REDUCED MATRIX CALCULATED.");
2540 nperln = (fNpagwd - 5) / 10;
2541 nperln = TMath::Min(nperln,13);
2542 if (fISW[4] >= 1 && npard > nperln) {
2543 Printf(
" ELEMENTS ABOVE DIAGONAL ARE NOT PRINTED.");
2546 for (i = 1; i <= npard; ++i) {
2547 mndxdi(fX[i-1], i-1, dxdi);
2549 for (j = 1; j <= i; ++j) {
2550 mndxdi(fX[j-1], j-1, dxdj);
2552 emat[i + j*emat_dim1] = dxdi*fVhmat[kgb-1]*dxdj*fUp;
2553 emat[j + i*emat_dim1] = emat[i + j*emat_dim1];
2558 for (i = 1; i <= npard; ++i) {
2560 if (npard >= nperln) iz = i;
2562 for (k = 1; nperln < 0 ? k >= iz : k <= iz; k += nperln) {
2563 k2 = k + nperln - 1;
2564 if (k2 > iz) k2 = iz;
2565 for (kk = k; kk <= k2; ++kk) {
2566 ctemp += TString::Format(
"%10.3e ",emat[i + kk*emat_dim1]);
2568 Printf(
"%s",(
const char*)ctemp);
2587 void TMinuit::mnerrs(Int_t number, Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &gcc)
2590 Int_t ndiag, iin, iex;
2594 if (iex > fNu || iex <= 0)
goto L900;
2595 iin = fNiofex[iex-1];
2596 if (iin <= 0)
goto L900;
2599 eplus = fErp[iin-1];
2600 if (eplus == fUndefi) eplus = 0;
2601 eminus = fErn[iin-1];
2602 if (eminus == fUndefi) eminus = 0;
2603 mndxdi(fX[iin-1], iin-1, dxdi);
2604 ndiag = iin*(iin + 1) / 2;
2605 eparab = TMath::Abs(dxdi*TMath::Sqrt(TMath::Abs(fUp*fVhmat[ndiag- 1])));
2608 if (fISW[1] < 2)
return;
2609 gcc = fGlobcc[iin-1];
2629 void TMinuit::mneval(Double_t anext, Double_t &fnext, Int_t &ierev)
2633 fU[fKe1cr-1] = fXmidcr + anext*fXdircr;
2634 if (fKe2cr != 0) fU[fKe2cr-1] = fYmidcr + anext*fYdircr;
2637 Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
2646 if (fISW[0] >= 1) ierev = 1;
2647 if (fISW[3] < 1) ierev = 2;
2673 void TMinuit::mnexcm(
const char *command, Double_t *plist, Int_t llist, Int_t &ierflg)
2677 TString comand = command;
2678 static const char *
const cname[40] = {
2723 Double_t step, xptu[101], yptu[101], f, rno;
2724 Int_t icol, kcol, ierr, iint, iext, lnow, nptu, i, iflag, ierrf;
2725 Int_t ilist, nparx, izero, nf, lk, it, iw, inonde, nsuper;
2726 Int_t it2, ke1, ke2, nowprt, kll, krl;
2727 TString chwhy, c26, cvblnk, cneway, comd;
2729 Bool_t lfreed, ltofix, lfixed;
2735 lk = comand.Length();
2736 if (lk > 20) lk = 20;
2741 for (iw = 1; iw <= fMaxpar; ++iw) {
2743 if (iw <= llist) fWord7[iw-1] = plist[iw-1];
2747 if (fCword(0,7) !=
"SET PRI" || fWord7[0] >= 0) {
2750 if (lnow > 4) lnow = 4;
2751 Printf(
" **********");
2752 ctemp.Form(
" **%5d **%s",fIcomnd,(
const char*)fCword);
2753 for (i = 1; i <= lnow; ++i) {
2754 ctemp += TString::Format(
"%12.4g",plist[i-1]);
2756 Printf(
"%s",(
const char*)ctemp);
2760 if (llist > fMaxpar) {
2764 Printf(
" ***********");
2765 for (i = lnow + 1; i <= kll; ++i) {
2766 Printf(
"%12.4g",plist[i-1]);
2769 Printf(
" **********");
2771 Printf(
" ERROR: ABOVE CALL TO MNEXCM TRIED TO PASS MORE THAN %d PARAMETERS.", fMaxpar);
2775 fNfcnmx = Int_t(fWord7[0]);
2777 fNfcnmx = fNpar*100 + 200 + fNpar*fNpar*5;
2788 ctemp = fCword(0,3);
2789 for (i = 1; i <= nntot; ++i) {
2790 if (strncmp(ctemp.Data(),cname[i-1],3) == 0)
goto L90;
2792 Printf(
"UNKNOWN COMMAND IGNORED:%s", comand.Data());
2797 if (fCword(0,4) ==
"MINO") i = 5;
2798 if (i != 6 && i != 7 && i != 8 && i != 23) {
2799 fCfrom = cname[i-1];
2813 case 10:
goto L1000;
2814 case 11:
goto L1100;
2815 case 12:
goto L1200;
2816 case 13:
goto L1300;
2817 case 14:
goto L1400;
2818 case 15:
goto L1500;
2819 case 16:
goto L1600;
2820 case 17:
goto L1700;
2821 case 18:
goto L1800;
2822 case 19:
goto L1900;
2823 case 20:
goto L1900;
2824 case 21:
goto L1900;
2825 case 22:
goto L2200;
2826 case 23:
goto L2300;
2827 case 24:
goto L2400;
2828 case 25:
goto L1900;
2829 case 26:
goto L2600;
2830 case 27:
goto L3300;
2831 case 28:
goto L3300;
2832 case 29:
goto L3300;
2833 case 30:
goto L3300;
2834 case 31:
goto L3300;
2835 case 32:
goto L3300;
2836 case 33:
goto L3300;
2837 case 34:
goto L3400;
2838 case 35:
goto L3500;
2839 case 36:
goto L3600;
2840 case 37:
goto L3700;
2841 case 38:
goto L3800;
2842 case 39:
goto L3900;
2843 case 40:
goto L4000;
2852 if (fISW[3] < 1) ierflg = 4;
2860 if (fISW[3] >= 1)
return;
2862 if (fISW[0] == 1)
return;
2863 if (fCword(0,3) ==
"MIG")
return;
2865 fNfcnmx = fNfcnmx + nf - fNfcn;
2868 if (fISW[0] == 1)
return;
2869 fNfcnmx = fNfcnmx + nf - fNfcn;
2871 if (fISW[3] >= 1) ierflg = 0;
2876 nsuper = fNfcn + ((fNpar + 1) << 1)*fNfcnmx;
2880 fCfrom = cname[i-1];
2883 if (! fLnewmn)
return;
2887 if (fNfcn < nsuper)
goto L510;
2888 Printf(
" TOO MANY FUNCTION CALLS. MINOS GIVES UP");
2908 Printf(
"%s: NO PARAMETERS REQUESTED ",(
const char*)fCword);
2911 for (ilist = 1; ilist <= llist; ++ilist) {
2912 iext = Int_t(plist[ilist-1]);
2913 chwhy =
" IS UNDEFINED.";
2914 if (iext <= 0)
goto L930;
2915 if (iext > fNu)
goto L930;
2916 if (fNvarl[iext-1] < 0)
goto L930;
2917 chwhy =
" IS CONSTANT. ";
2918 if (fNvarl[iext-1] == 0)
goto L930;
2919 iint = fNiofex[iext-1];
2921 chwhy =
" ALREADY FIXED.";
2922 if (iint == 0)
goto L930;
2923 mnfixp(iint-1, ierr);
2924 if (ierr == 0) lfixed = kTRUE;
2927 chwhy =
" ALREADY VARIABLE.";
2928 if (iint > 0)
goto L930;
2935 if (fISW[4] >= 0) Printf(
" PARAMETER %4d %s IGNORED.",iext,(
const char*)chwhy);
2937 if (lfreed || lfixed) mnrset(0);
2945 if (fISW[4] > 1) mnprin(5, fAmin);
2949 it = Int_t(fWord7[0]);
2950 if (it > 1 || it < 0)
goto L1005;
2951 lfreed = fNpfix > 0;
2961 Printf(
" IGNORED. UNKNOWN ARGUMENT:%4d",it);
2970 iext = Int_t(fWord7[0]);
2971 if (iext <= 0)
goto L1210;
2973 if (iext <= fNu) it2 = fNiofex[iext-1];
2974 if (it2 <= 0)
goto L1250;
2980 Printf(
" PARAMETER %4d NOT VARIABLE.",iext);
2985 ke1 = Int_t(fWord7[0]);
2986 ke2 = Int_t(fWord7[1]);
2992 Printf(
"%s: NO PARAMETERS REQUESTED ",(
const char*)fCword);
2998 mncntr(ke1-1, ke2-1, ierrf);
2999 if (ierrf > 0) ierflg = 3;
3005 if (fISW[4] >= 0) mnprin(2, fAmin);
3006 if (fISW[4] >= 1) mnmatu(1);
3016 if (fLnewmn)
goto L400;
3021 iflag = Int_t(fWord7[0]);
3024 Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
3027 if (fAmin == fUndefi) {
3030 }
else if (f < fAmin) {
3034 if (fISW[4] >= 0 && iflag <= 5 && nowprt == 1) {
3037 if (iflag == 3) fFval3 = f;
3039 if (iflag > 5) mnrset(1);
3047 it = Int_t(fWord7[0]);
3048 if (fFval3 != fAmin && it == 0) {
3050 if (fISW[4] >= 0) Printf(
" CALL TO USER FUNCTION WITH IFLAG = 3");
3052 Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
3055 if (fCword(0,3) ==
"END") ierflg = 10;
3056 if (fCword(0,3) ==
"RET") ierflg = 12;
3062 Printf(
" MINUIT MEMORY CLEARED. NO PARAMETERS NOW DEFINED.");
3068 for (icol = 5; icol <= lk; ++icol) {
3069 if (fCword[icol-1] ==
' ')
continue;
3074 if (kcol == 0) comd =
"* ";
3075 else comd = fCword(kcol-1,lk-kcol+1);
3081 ke1 = Int_t(fWord7[0]);
3082 ke2 = Int_t(fWord7[1]);
3083 if (ke1 == 0 && fNpar == 2) {
3087 nptu = Int_t(fWord7[2]);
3088 if (nptu <= 0) nptu = 20;
3089 if (nptu > 101) nptu = 101;
3090 fNfcnmx = (nptu + 5)*100*(fNpar + 1);
3091 mncont(ke1-1, ke2-1, nptu, xptu, yptu, ierrf);
3092 if (ierrf < nptu) ierflg = 4;
3093 if (ierrf == -1) ierflg = 3;
3098 if (step <= 0) step = 2;
3101 for (i = 1; i <= fNpar; ++i) {
3104 fX[i-1] += rno*step*fWerr[i-1];
3112 Printf(
" BLANK COMMAND IGNORED.");
3118 Printf(
" THE *COVARIANCE* COMMAND IS OSBSOLETE. THE COVARIANCE MATRIX IS NOW SAVED IN A DIFFERENT FORMAT WITH THE *SAVE* COMMAND AND READ IN WITH:*SET COVARIANCE*");
3123 cneway =
"SET PRInt ";
3127 cneway =
"SET GRAd ";
3131 cneway =
"SHOW COVar";
3135 cneway =
"SET ERRdef";
3139 cneway =
"SET LIMits";
3146 Printf(
" OBSOLETE COMMAND:%s PLEASE USE:%s",(
const char*)fCword
3147 ,(
const char*)cneway);
3149 if (fCword ==
"SAVE ")
goto L1500;
3160 void TMinuit::mnexin(Double_t *pint)
3166 for (iint = 1; iint <= fNpar; ++iint) {
3167 iext = fNexofi[iint-1];
3168 mnpint(fU[iext-1], iext-1, pinti);
3169 pint[iint-1] = pinti;
3178 void TMinuit::mnfixp(Int_t iint1, Int_t &ierr)
3182 Int_t kold, nold, ndex, knew, iext, i, j, m, n, lc, ik;
3186 Int_t iint = iint1+1;
3187 if (iint > fNpar || iint <= 0) {
3189 Printf(
" MINUIT ERROR. ARGUMENT TO MNFIXP=%4d",iint);
3192 iext = fNexofi[iint-1];
3193 if (fNpfix >= fMaxpar) {
3195 Printf(
" MINUIT CANNOT FIX PARAMETER %4d MAXIMUM NUMBER THAT CAN BE FIXED IS %d",iext,fMaxpar);
3200 fNiofex[iext-1] = 0;
3206 fIpfix[fNpfix-1] = iext;
3208 fXs[fNpfix-1] = fX[lc-1];
3209 fXts[fNpfix-1] = fXt[lc-1];
3210 fDirins[fNpfix-1] = fWerr[lc-1];
3211 fGrds[fNpfix-1] = fGrd[lc-1];
3212 fG2s[fNpfix-1] = fG2[lc-1];
3213 fGsteps[fNpfix-1] = fGstep[lc-1];
3215 for (ik = iext + 1; ik <= fNu; ++ik) {
3216 if (fNiofex[ik-1] > 0) {
3217 lc = fNiofex[ik-1] - 1;
3221 fXt[lc-1] = fXt[lc];
3222 fDirin[lc-1] = fDirin[lc];
3223 fWerr[lc-1] = fWerr[lc];
3224 fGrd[lc-1] = fGrd[lc];
3225 fG2[lc-1] = fG2[lc];
3226 fGstep[lc-1] = fGstep[lc];
3229 if (fISW[1] <= 0)
return;
3231 if (fNpar <= 0)
return;
3232 for (i = 1; i <= nold; ++i) {
3233 m = TMath::Max(i,iint);
3234 n = TMath::Min(i,iint);
3235 ndex = m*(m-1) / 2 + n;
3236 fFIXPyy[i-1] = fVhmat[ndex-1];
3238 yyover = 1 / fFIXPyy[iint-1];
3241 for (i = 1; i <= nold; ++i) {
3242 for (j = 1; j <= i; ++j) {
3244 if (j == iint || i == iint)
continue;
3246 fVhmat[knew-1] = fVhmat[kold-1] - fFIXPyy[j-1]*fFIXPyy[i-1]*yyover;
3265 void TMinuit::mnfree(Int_t k)
3268 Double_t grdv, xv, dirinv, g2v, gstepv, xtv;
3269 Int_t i, ipsav, ka, lc, ik, iq, ir, is;
3272 Printf(
" CALL TO MNFREE IGNORED. ARGUMENT GREATER THAN ONE");
3275 Printf(
" CALL TO MNFREE IGNORED. THERE ARE NO FIXED PARAMETERS");
3277 if (k == 1 || k == 0)
goto L40;
3281 if (fNiofex[ka-1] == 0)
goto L15;
3282 Printf(
" IGNORED. PARAMETER SPECIFIED IS ALREADY VARIABLE.");
3285 if (fNpfix < 1)
goto L21;
3286 for (ik = 1; ik <= fNpfix; ++ik) {
if (fIpfix[ik-1] == ka)
goto L24; }
3288 Printf(
" PARAMETER %4d NOT FIXED. CANNOT BE RELEASED.",ka);
3291 if (ik == fNpfix)
goto L40;
3297 dirinv = fDirins[ik-1];
3300 gstepv = fGsteps[ik-1];
3301 for (i = ik + 1; i <= fNpfix; ++i) {
3302 fIpfix[i-2] = fIpfix[i-1];
3303 fXs[i-2] = fXs[i-1];
3304 fXts[i-2] = fXts[i-1];
3305 fDirins[i-2] = fDirins[i-1];
3306 fGrds[i-2] = fGrds[i-1];
3307 fG2s[i-2] = fG2s[i-1];
3308 fGsteps[i-2] = fGsteps[i-1];
3310 fIpfix[fNpfix-1] = ipsav;
3312 fXts[fNpfix-1] = xtv;
3313 fDirins[fNpfix-1] = dirinv;
3314 fGrds[fNpfix-1] = grdv;
3315 fG2s[fNpfix-1] = g2v;
3316 fGsteps[fNpfix-1] = gstepv;
3319 if (fNpfix < 1)
goto L300;
3320 ir = fIpfix[fNpfix-1];
3322 for (ik = fNu; ik >= ir; --ik) {
3323 if (fNiofex[ik-1] > 0) {
3324 lc = fNiofex[ik-1] + 1;
3328 fX[lc-1] = fX[lc-2];
3329 fXt[lc-1] = fXt[lc-2];
3330 fDirin[lc-1] = fDirin[lc-2];
3331 fWerr[lc-1] = fWerr[lc-2];
3332 fGrd[lc-1] = fGrd[lc-2];
3333 fG2[lc-1] = fG2[lc-2];
3334 fGstep[lc-1] = fGstep[lc-2];
3338 if (is == 0) is = fNpar;
3342 fX[is-1] = fXs[iq-1];
3343 fXt[is-1] = fXts[iq-1];
3344 fDirin[is-1] = fDirins[iq-1];
3345 fWerr[is-1] = fDirins[iq-1];
3346 fGrd[is-1] = fGrds[iq-1];
3347 fG2[is-1] = fG2s[iq-1];
3348 fGstep[is-1] = fGsteps[iq-1];
3352 if (fISW[4] - fItaur >= 1) {
3353 Printf(
" PARAMETER %4d %s RESTORED TO VARIABLE.",ir,
3354 (
const char*)fCpnam[ir-1]);
3356 if (k == 0)
goto L40;
3371 void TMinuit::mngrad()
3374 Double_t fzero, err;
3375 Int_t i, nparx, lc, istsav;
3380 if (fWord7[0] > 0)
goto L2000;
3383 for (i = 1; i <= fNu; ++i) { fGin[i-1] = fUndefi; }
3385 Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
3387 for (i = 1; i <= fNpar; ++i) { fGRADgf[i-1] = fGrd[i-1]; }
3394 Printf(
" CHECK OF GRADIENT CALCULATION IN FCN");
3395 Printf(
" PARAMETER G(IN FCN) G(MINUIT) DG(MINUIT) AGREEMENT");
3398 for (lc = 1; lc <= fNpar; ++lc) {
3400 const char *cwd =
"GOOD";
3402 if (TMath::Abs(fGRADgf[lc-1] - fGrd[lc-1]) > err) {
3406 if (fGin[i-1] == fUndefi) {
3412 Printf(
" %5d %10s%12.4e%12.4e%12.4e %s",i
3413 ,(
const char*)fCpnam[i-1]
3414 ,fGRADgf[lc-1],fGrd[lc-1],err,cwd);
3417 Printf(
" AGREEMENT=NONE MEANS FCN DID NOT CALCULATE THE DERIVATIVE");
3420 Printf(
" MINUIT DOES NOT ACCEPT DERIVATIVE CALCULATIONS BY FCN");
3421 Printf(
" TO FORCE ACCEPTANCE, ENTER *SET GRAD 1*");
3431 void TMinuit::mnhelp(
const char *command)
3433 TString comd = command;
3448 void TMinuit::mnhelp(TString comd)
3455 if( comd.Length() == 0 || comd[0] ==
'*' || comd[0] ==
'?' || comd[0] == 0 || comd==
"HELP" ) {
3456 Printf(
" ==>List of MINUIT Interactive commands:");
3457 Printf(
" CLEar Reset all parameter names and values undefined");
3458 Printf(
" CONtour Make contour map of the user function");
3459 Printf(
" EXIT Exit from Interactive Minuit");
3460 Printf(
" FIX Cause parameter(s) to remain constant");
3461 Printf(
" HESse Calculate the Hessian or error matrix.");
3462 Printf(
" IMPROVE Search for a new minimum around current minimum");
3463 Printf(
" MIGrad Minimize by the method of Migrad");
3464 Printf(
" MINImize MIGRAD + SIMPLEX method if Migrad fails");
3465 Printf(
" MINOs Exact (non-linear) parameter error analysis");
3466 Printf(
" MNContour Calculate one MINOS function contour");
3467 Printf(
" PARameter Define or redefine new parameters and values");
3468 Printf(
" RELease Make previously FIXed parameters variable again");
3469 Printf(
" REStore Release last parameter fixed");
3470 Printf(
" SAVe Save current parameter values on a file");
3471 Printf(
" SCAn Scan the user function by varying parameters");
3472 Printf(
" SEEk Minimize by the method of Monte Carlo");
3473 Printf(
" SET Set various MINUIT constants or conditions");
3474 Printf(
" SHOw Show values of current constants or conditions");
3475 Printf(
" SIMplex Minimize by the method of Simplex");
3483 if( !strncmp(comd.Data(),
"CLE",3) ) {
3484 Printf(
" ***>CLEAR");
3485 Printf(
" Resets all parameter names and values to undefined.");
3486 Printf(
" Must normally be followed by a PARameters command or ");
3487 Printf(
" equivalent, in order to define parameter values.");
3494 if( !strncmp(comd.Data(),
"CON",3) ) {
3495 Printf(
" ***>CONTOUR <par1> <par2> [devs] [ngrid]");
3496 Printf(
" Instructs Minuit to trace contour lines of the user function");
3497 Printf(
" with respect to the two parameters whose external numbers");
3498 Printf(
" are <par1> and <par2>.");
3499 Printf(
" Other variable parameters of the function, if any, will have");
3500 Printf(
" their values fixed at the current values during the contour");
3501 Printf(
" tracing. The optional parameter [devs] (default value 2.)");
3502 Printf(
" gives the number of standard deviations in each parameter");
3503 Printf(
" which should lie entirely within the plotting area.");
3504 Printf(
" Optional parameter [ngrid] (default value 25 unless page");
3505 Printf(
" size is too small) determines the resolution of the plot,");
3506 Printf(
" i.e. the number of rows and columns of the grid at which the");
3507 Printf(
" function will be evaluated. [See also MNContour.]");
3514 if( !strncmp(comd.Data(),
"END",3) ) {
3516 Printf(
" Signals the end of a data block (i.e., the end of a fit),");
3517 Printf(
" and implies that execution should continue, because another");
3518 Printf(
" Data Block follows. A Data Block is a set of Minuit data");
3519 Printf(
" consisting of");
3520 Printf(
" (1) A Title,");
3521 Printf(
" (2) One or more Parameter Definitions,");
3522 Printf(
" (3) A blank line, and");
3523 Printf(
" (4) A set of Minuit Commands.");
3524 Printf(
" The END command is used when more than one Data Block is to");
3525 Printf(
" be used with the same FCN function. It first causes Minuit");
3526 Printf(
" to issue a CALL FCN with IFLAG=3, in order to allow FCN to");
3527 Printf(
" perform any calculations associated with the final fitted");
3528 Printf(
" parameter values, unless a CALL FCN 3 command has already");
3529 Printf(
" been executed at the current FCN value.");
3536 if( !strncmp(comd.Data(),
"EXI",3) ) {
3537 Printf(
" ***>EXIT");
3538 Printf(
" Signals the end of execution.");
3539 Printf(
" The EXIT command first causes Minuit to issue a CALL FCN");
3540 Printf(
" with IFLAG=3, to allow FCN to perform any calculations");
3541 Printf(
" associated with the final fitted parameter values, unless a");
3542 Printf(
" CALL FCN 3 command has already been executed.");
3549 if( !strncmp(comd.Data(),
"FIX",3) ) {
3550 Printf(
" ***>FIX} <parno> [parno] ... [parno]");
3551 Printf(
" Causes parameter(s) <parno> to be removed from the list of");
3552 Printf(
" variable parameters, and their value(s) will remain constant");
3553 Printf(
" during subsequent minimizations, etc., until another command");
3554 Printf(
" changes their value(s) or status.");
3561 if( !strncmp(comd.Data(),
"HES",3) ) {
3562 Printf(
" ***>HESse [maxcalls]");
3563 Printf(
" Calculate, by finite differences, the Hessian or error matrix.");
3564 Printf(
" That is, it calculates the full matrix of second derivatives");
3565 Printf(
" of the function with respect to the currently variable");
3566 Printf(
" parameters, and inverts it, printing out the resulting error");
3567 Printf(
" matrix. The optional argument [maxcalls] specifies the");
3568 Printf(
" (approximate) maximum number of function calls after which");
3569 Printf(
" the calculation will be stopped.");
3576 if( !strncmp(comd.Data(),
"IMP",3) ) {
3577 Printf(
" ***>IMPROVE [maxcalls]");
3578 Printf(
" If a previous minimization has converged, and the current");
3579 Printf(
" values of the parameters therefore correspond to a local");
3580 Printf(
" minimum of the function, this command requests a search for");
3581 Printf(
" additional distinct local minima.");
3582 Printf(
" The optional argument [maxcalls] specifies the (approximate");
3583 Printf(
" maximum number of function calls after which the calculation");
3584 Printf(
" will be stopped.");
3591 if( !strncmp(comd.Data(),
"MIG",3) ) {
3592 Printf(
" ***>MIGrad [maxcalls] [tolerance]");
3593 Printf(
" Causes minimization of the function by the method of Migrad,");
3594 Printf(
" the most efficient and complete single method, recommended");
3595 Printf(
" for general functions (see also MINImize).");
3596 Printf(
" The minimization produces as a by-product the error matrix");
3597 Printf(
" of the parameters, which is usually reliable unless warning");
3598 Printf(
" messages are produced.");
3599 Printf(
" The optional argument [maxcalls] specifies the (approximate)");
3600 Printf(
" maximum number of function calls after which the calculation");
3601 Printf(
" will be stopped even if it has not yet converged.");
3602 Printf(
" The optional argument [tolerance] specifies required tolerance");
3603 Printf(
" on the function value at the minimum.");
3604 Printf(
" The default tolerance is 0.1, and the minimization will stop");
3605 Printf(
" when the estimated vertical distance to the minimum (EDM) is");
3606 Printf(
" less than 0.001*[tolerance]*UP (see [SET ERRordef]).");
3613 if( !strncmp(comd.Data(),
"MINI",4) ) {
3614 Printf(
" ***>MINImize [maxcalls] [tolerance]");
3615 Printf(
" Causes minimization of the function by the method of Migrad,");
3616 Printf(
" as does the MIGrad command, but switches to the SIMplex method");
3617 Printf(
" if Migrad fails to converge. Arguments are as for MIGrad.");
3618 Printf(
" Note that command requires four characters to be unambiguous.");
3625 if( !strncmp(comd.Data(),
"MIN0",4) ) {
3626 Printf(
" ***>MINOs [maxcalls] [parno] [parno] ...");
3627 Printf(
" Causes a Minos error analysis to be performed on the parameters");
3628 Printf(
" whose numbers [parno] are specified. If none are specified,");
3629 Printf(
" Minos errors are calculated for all variable parameters.");
3630 Printf(
" Minos errors may be expensive to calculate, but are very");
3631 Printf(
" reliable since they take account of non-linearities in the");
3632 Printf(
" problem as well as parameter correlations, and are in general");
3633 Printf(
" asymmetric.");
3634 Printf(
" The optional argument [maxcalls] specifies the (approximate)");
3635 Printf(
" maximum number of function calls per parameter requested,");
3636 Printf(
" after which the calculation will stop for that parameter.");
3643 if( !strncmp(comd.Data(),
"MNC",3) ) {
3644 Printf(
" ***>MNContour <par1> <par2> [npts]");
3645 Printf(
" Calculates one function contour of FCN with respect to");
3646 Printf(
" parameters par1 and par2, with FCN minimized always with");
3647 Printf(
" respect to all other NPAR-2 variable parameters (if any).");
3648 Printf(
" Minuit will try to find npts points on the contour (default 20)");
3649 Printf(
" If only two parameters are variable at the time, it is not");
3650 Printf(
" necessary to specify their numbers. To calculate more than");
3651 Printf(
" one contour, it is necessary to SET ERRordef to the appropriate");
3652 Printf(
" value and issue the MNContour command for each contour.");
3659 if( !strncmp(comd.Data(),
"PAR",3) ) {
3660 Printf(
" ***>PARameters");
3661 Printf(
" followed by one or more parameter definitions.");
3662 Printf(
" Parameter definitions are of the form:");
3663 Printf(
" <number> ''name'' <value> <step> [lolim] [uplim] ");
3664 Printf(
" for example:");
3665 Printf(
" 3 ''K width'' 1.2 0.1");
3666 Printf(
" the last definition is followed by a blank line or a zero.");
3673 if( !strncmp(comd.Data(),
"REL",3) ) {
3674 Printf(
" ***>RELease <parno> [parno] ... [parno]");
3675 Printf(
" If <parno> is the number of a previously variable parameter");
3676 Printf(
" which has been fixed by a command: FIX <parno>, then that");
3677 Printf(
" parameter will return to variable status. Otherwise a warning");
3678 Printf(
" message is printed and the command is ignored.");
3679 Printf(
" Note that this command operates only on parameters which were");
3680 Printf(
" at one time variable and have been FIXed. It cannot make");
3681 Printf(
" constant parameters variable; that must be done by redefining");
3682 Printf(
" the parameter with a PARameters command.");
3689 if( !strncmp(comd.Data(),
"RES",3) ) {
3690 Printf(
" ***>REStore [code]");
3691 Printf(
" If no [code] is specified, this command restores all previously");
3692 Printf(
" FIXed parameters to variable status. If [code]=1, then only");
3693 Printf(
" the last parameter FIXed is restored to variable status.");
3694 Printf(
" If code is neither zero nor one, the command is ignored.");
3701 if( !strncmp(comd.Data(),
"RET",3) ) {
3702 Printf(
" ***>RETURN");
3703 Printf(
" Signals the end of a data block, and instructs Minuit to return");
3704 Printf(
" to the program which called it. The RETurn command first");
3705 Printf(
" causes Minuit to CALL FCN with IFLAG=3, in order to allow FCN");
3706 Printf(
" to perform any calculations associated with the final fitted");
3707 Printf(
" parameter values, unless a CALL FCN 3 command has already been");
3708 Printf(
" executed at the current FCN value.");
3715 if( !strncmp(comd.Data(),
"SAV",3) ) {
3716 Printf(
" ***>SAVe");
3717 Printf(
" Causes the current parameter values to be saved on a file in");
3718 Printf(
" such a format that they can be read in again as Minuit");
3719 Printf(
" parameter definitions. If the covariance matrix exists, it is");
3720 Printf(
" also output in such a format. The unit number is by default 7,");
3721 Printf(
" or that specified by the user in their call to MINTIO or");
3722 Printf(
" MNINIT. The user is responsible for opening the file previous");
3723 Printf(
" to issuing the [SAVe] command (except where this can be done");
3724 Printf(
" interactively).");
3731 if( !strncmp(comd.Data(),
"SCA",3) ) {
3732 Printf(
" ***>SCAn [parno] [numpts] [from] [to]");
3733 Printf(
" Scans the value of the user function by varying parameter");
3734 Printf(
" number [parno], leaving all other parameters fixed at the");
3735 Printf(
" current value. If [parno] is not specified, all variable");
3736 Printf(
" parameters are scanned in sequence.");
3737 Printf(
" The number of points [numpts] in the scan is 40 by default,");
3738 Printf(
" and cannot exceed 100. The range of the scan is by default");
3739 Printf(
" 2 standard deviations on each side of the current best value,");
3740 Printf(
" but can be specified as from [from] to [to].");
3741 Printf(
" After each scan, if a new minimum is found, the best parameter");
3742 Printf(
" values are retained as start values for future scans or");
3743 Printf(
" minimizations. The curve resulting from each scan is plotted");
3744 Printf(
" on the output unit in order to show the approximate behaviour");
3745 Printf(
" of the function.");
3746 Printf(
" This command is not intended for minimization, but is sometimes");
3747 Printf(
" useful for debugging the user function or finding a");
3748 Printf(
" reasonable starting point.");
3755 if( !strncmp(comd.Data(),
"SEE",3) ) {
3756 Printf(
" ***>SEEk [maxcalls] [devs]");
3757 Printf(
" Causes a Monte Carlo minimization of the function, by choosing");
3758 Printf(
" random values of the variable parameters, chosen uniformly");
3759 Printf(
" over a hypercube centered at the current best value.");
3760 Printf(
" The region size is by default 3 standard deviations on each");
3761 Printf(
" side, but can be changed by specifying the value of [devs].");
3768 if( !strncmp(comd.Data(),
"SET",3) ) {
3769 Printf(
" ***>SET <option_name>");
3770 Printf(
" SET BATch");
3771 Printf(
" Informs Minuit that it is running in batch mode.");
3774 Printf(
" SET EPSmachine <accuracy>");
3775 Printf(
" Informs Minuit that the relative floating point arithmetic");
3776 Printf(
" precision is <accuracy>. Minuit determines the nominal");
3777 Printf(
" precision itself, but the SET EPSmachine command can be");
3778 Printf(
" used to override Minuit own determination, when the user");
3779 Printf(
" knows that the FCN function value is not calculated to");
3780 Printf(
" the nominal machine accuracy. Typical values of <accuracy>");
3781 Printf(
" are between 10**-5 and 10**-14.");
3784 Printf(
" SET ERRordef <up>");
3785 Printf(
" Sets the value of UP (default value= 1.), defining parameter");
3786 Printf(
" errors. Minuit defines parameter errors as the change");
3787 Printf(
" in parameter value required to change the function value");
3788 Printf(
" by UP. Normally, for chisquared fits UP=1, and for negative");
3789 Printf(
" log likelihood, UP=0.5.");
3792 Printf(
" SET GRAdient [force]");
3793 Printf(
" Informs Minuit that the user function is prepared to");
3794 Printf(
" calculate its own first derivatives and return their values");
3795 Printf(
" in the array GRAD when IFLAG=2 (see specs of FCN).");
3796 Printf(
" If [force] is not specified, Minuit will calculate");
3797 Printf(
" the FCN derivatives by finite differences at the current");
3798 Printf(
" point and compare with the user calculation at that point,");
3799 Printf(
" accepting the user values only if they agree.");
3800 Printf(
" If [force]=1, Minuit does not do its own derivative");
3801 Printf(
" calculation, and uses the derivatives calculated in FCN.");
3804 Printf(
" SET INPut [unitno] [filename]");
3805 Printf(
" Causes Minuit, in data-driven mode only, to read subsequent");
3806 Printf(
" commands (or parameter definitions) from a different input");
3807 Printf(
" file. If no [unitno] is specified, reading reverts to the");
3808 Printf(
" previous input file, assuming that there was one.");
3809 Printf(
" If [unitno] is specified, and that unit has not been opened,");
3810 Printf(
" then Minuit attempts to open the file [filename]} if a");
3811 Printf(
" name is specified. If running in interactive mode and");
3812 Printf(
" [filename] is not specified and [unitno] is not opened,");
3813 Printf(
" Minuit prompts the user to enter a file name.");
3814 Printf(
" If the word REWIND is added to the command (note:no blanks");
3815 Printf(
" between INPUT and REWIND), the file is rewound before");
3816 Printf(
" reading. Note that this command is implemented in standard");
3817 Printf(
" Fortran 77 and the results may depend on the system;");
3818 Printf(
" for example, if a filename is given under VM/CMS, it must");
3819 Printf(
" be preceded by a slash.");
3822 Printf(
" SET INTeractive");
3823 Printf(
" Informs Minuit that it is running interactively.");
3826 Printf(
" SET LIMits [parno] [lolim] [uplim]");
3827 Printf(
" Allows the user to change the limits on one or all");
3828 Printf(
" parameters. If no arguments are specified, all limits are");
3829 Printf(
" removed from all parameters. If [parno] alone is specified,");
3830 Printf(
" limits are removed from parameter [parno].");
3831 Printf(
" If all arguments are specified, then parameter [parno] will");
3832 Printf(
" be bounded between [lolim] and [uplim].");
3833 Printf(
" Limits can be specified in either order, Minuit will take");
3834 Printf(
" the smaller as [lolim] and the larger as [uplim].");
3835 Printf(
" However, if [lolim] is equal to [uplim], an error condition");
3836 Printf(
" results.");
3839 Printf(
" SET LINesperpage");
3840 Printf(
" Sets the number of lines for one page of output.");
3841 Printf(
" Default value is 24 for interactive mode");
3844 Printf(
" SET NOGradient");
3845 Printf(
" The inverse of SET GRAdient, instructs Minuit not to");
3846 Printf(
" use the first derivatives calculated by the user in FCN.");
3849 Printf(
" SET NOWarnings");
3850 Printf(
" Supresses Minuit warning messages.");
3853 Printf(
" SET OUTputfile <unitno>");
3854 Printf(
" Instructs Minuit to write further output to unit <unitno>.");
3857 Printf(
" SET PAGethrow <integer>");
3858 Printf(
" Sets the carriage control character for ``new page'' to");
3859 Printf(
" <integer>. Thus the value 1 produces a new page, and 0");
3860 Printf(
" produces a blank line, on some devices (see TOPofpage)");
3864 Printf(
" SET PARameter <parno> <value>");
3865 Printf(
" Sets the value of parameter <parno> to <value>.");
3866 Printf(
" The parameter in question may be variable, fixed, or");
3867 Printf(
" constant, but must be defined.");
3870 Printf(
" SET PRIntout <level>");
3871 Printf(
" Sets the print level, determining how much output will be");
3872 Printf(
" produced. Allowed values and their meanings are displayed");
3873 Printf(
" after a SHOw PRInt command, and are currently <level>=:");
3874 Printf(
" [-1] no output except from SHOW commands");
3875 Printf(
" [0] minimum output");
3876 Printf(
" [1] default value, normal output");
3877 Printf(
" [2] additional output giving intermediate results.");
3878 Printf(
" [3] maximum output, showing progress of minimizations.");
3879 Printf(
" Note: See also the SET WARnings command.");
3882 Printf(
" SET RANdomgenerator <seed>");
3883 Printf(
" Sets the seed of the random number generator used in SEEk.");
3884 Printf(
" This can be any integer between 10000 and 900000000, for");
3885 Printf(
" example one which was output from a SHOw RANdom command of");
3886 Printf(
" a previous run.");
3889 Printf(
" SET STRategy <level>");
3890 Printf(
" Sets the strategy to be used in calculating first and second");
3891 Printf(
" derivatives and in certain minimization methods.");
3892 Printf(
" In general, low values of <level> mean fewer function calls");
3893 Printf(
" and high values mean more reliable minimization.");
3894 Printf(
" Currently allowed values are 0, 1 (default), and 2.");
3897 Printf(
" SET TITle");
3898 Printf(
" Informs Minuit that the next input line is to be considered");
3899 Printf(
" the (new) title for this task or sub-task. This is for");
3900 Printf(
" the convenience of the user in reading their output.");
3903 Printf(
" SET WARnings");
3904 Printf(
" Instructs Minuit to output warning messages when suspicious");
3905 Printf(
" conditions arise which may indicate unreliable results.");
3906 Printf(
" This is the default.");
3909 Printf(
" SET WIDthpage");
3910 Printf(
" Informs Minuit of the output page width.");
3911 Printf(
" Default values are 80 for interactive jobs");
3918 if( !strncmp(comd.Data(),
"SHO",3) ) {
3919 Printf(
" ***>SHOw <option_name>");
3920 Printf(
" All SET XXXX commands have a corresponding SHOw XXXX command.");
3921 Printf(
" In addition, the SHOw commands listed starting here have no");
3922 Printf(
" corresponding SET command for obvious reasons.");
3925 Printf(
" SHOw CORrelations");
3926 Printf(
" Calculates and prints the parameter correlations from the");
3927 Printf(
" error matrix.");
3930 Printf(
" SHOw COVariance");
3931 Printf(
" Prints the (external) covariance (error) matrix.");
3934 Printf(
" SHOw EIGenvalues");
3935 Printf(
" Calculates and prints the eigenvalues of the covariance");
3939 Printf(
" SHOw FCNvalue");
3940 Printf(
" Prints the current value of FCN.");
3947 if( !strncmp(comd.Data(),
"SIM",3) ) {
3948 Printf(
" ***>SIMplex [maxcalls] [tolerance]");
3949 Printf(
" Performs a function minimization using the simplex method of");
3950 Printf(
" Nelder and Mead. Minimization terminates either when the");
3951 Printf(
" function has been called (approximately) [maxcalls] times,");
3952 Printf(
" or when the estimated vertical distance to minimum (EDM) is");
3953 Printf(
" less than [tolerance].");
3954 Printf(
" The default value of [tolerance] is 0.1*UP(see SET ERRordef).");
3961 if( !strncmp(comd.Data(),
"STA",3) ) {
3962 Printf(
" ***>STAndard");
3969 if( !strncmp(comd.Data(),
"STO",3) ) {
3970 Printf(
" ***>STOP");
3971 Printf(
" Same as EXIT.");
3978 if( !strncmp(comd.Data(),
"TOP",3) ) {
3979 Printf(
" ***>TOPofpage");
3980 Printf(
" Causes Minuit to write the character specified in a");
3981 Printf(
" SET PAGethrow command (default = 1) to column 1 of the output");
3982 Printf(
" file, which may or may not position your output medium to");
3983 Printf(
" the top of a page depending on the device and system.");
3987 Printf(
" Unknown MINUIT command. Type HELP for list of commands.");
4002 void TMinuit::mnhess()
4005 Double_t dmin_, dxdi, elem, wint, tlrg2, d, dlast, ztemp, g2bfor;
4006 Double_t df, aimsag, fs1, tlrstp, fs2, stpinm, g2i, sag=0, xtf, xti, xtj;
4007 Int_t icyc, ncyc, ndex, idrv, iext, npar2, i, j, ifail, npard, nparx, id, multpy;
4010 ldebug = fIdbg[3] >= 1;
4011 if (fAmin == fUndefi) {
4018 }
else if (fIstrat == 1) {
4027 if (fISW[4] >= 2 || ldebug) {
4028 Printf(
" START COVARIANCE MATRIX CALCULATION.");
4037 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4040 mnwarn(
"D",
"MNHESS", TString::Format(
"function value differs from AMIN by %g",df));
4044 Printf(
" PAR D GSTEP D G2 GRD SAG ");
4051 aimsag = TMath::Sqrt(fEpsma2)*(TMath::Abs(fAmin) + fUp);
4053 npar2 = fNpar*(fNpar + 1) / 2;
4054 for (i = 1; i <= npar2; ++i) { fVhmat[i-1] = 0; }
4058 for (
id = 1;
id <= npard; ++id) {
4059 i =
id + fNpar - npard;
4060 iext = fNexofi[i-1];
4061 if (fG2[i-1] == 0) {
4062 mnwarn(
"W",
"HESSE", Form(
"Second derivative enters zero, param %d",iext));
4064 if (fNvarl[iext-1] > 1) {
4065 mndxdi(fX[i-1], i-1, dxdi);
4066 if (TMath::Abs(dxdi) < .001) wint = .01;
4067 else wint /= TMath::Abs(dxdi);
4069 fG2[i-1] = fUp / (wint*wint);
4072 dmin_ = fEpsma2*8*TMath::Abs(xtf);
4075 d = TMath::Abs(fGstep[i-1]);
4077 for (icyc = 1; icyc <= ncyc; ++icyc) {
4079 for (multpy = 1; multpy <= 5; ++multpy) {
4084 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4087 Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
4089 sag = (fs1 + fs2 - fAmin*2)*.5;
4090 if (sag != 0)
goto L30;
4091 if (fGstep[i-1] < 0) {
4092 if (d >= .5)
goto L26;
4094 if (d > .5) d = .51;
4100 mnwarn(
"W",
"HESSE", TString::Format(
"Second derivative zero for parameter%d",iext));
4105 fG2[i-1] = sag*2 / (d*d);
4106 fGrd[i-1] = (fs1 - fs2) / (d*2);
4108 Printf(
"%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],d,fG2[i-1],fGrd[i-1],sag);
4110 if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(d);
4111 else fGstep[i-1] = -TMath::Abs(d);
4115 d = TMath::Sqrt(aimsag*2 / TMath::Abs(fG2[i-1]));
4118 if (fGstep[i-1] < 0) d = TMath::Min(d,stpinm);
4119 if (d < dmin_) d = dmin_;
4121 if (TMath::Abs((d - dlast) / d) < tlrstp ||
4122 TMath::Abs((fG2[i-1] - g2bfor) / fG2[i-1]) < tlrg2) {
4126 d = TMath::Min(d,dlast*102);
4127 d = TMath::Max(d,dlast*.1);
4131 mnwarn(
"D",
"MNHESS", TString::Format(
"Second Deriv. SAG,AIM= %d%g%g",iext,sag,aimsag));
4133 ndex = i*(i + 1) / 2;
4134 fVhmat[ndex-1] = fG2[i-1];
4139 if (fIstrat > 0) mnhes1();
4144 if (fNpar == 1)
goto L214;
4145 for (i = 1; i <= fNpar; ++i) {
4146 for (j = 1; j <= i-1; ++j) {
4149 fX[i-1] = xti + fDirin[i-1];
4150 fX[j-1] = xtj + fDirin[j-1];
4152 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4155 elem = (fs1 + fAmin - fHESSyy[i-1] - fHESSyy[j-1]) / (
4156 fDirin[i-1]*fDirin[j-1]);
4157 ndex = i*(i-1) / 2 + j;
4158 fVhmat[ndex-1] = elem;
4165 for (i = 1; i <= fNpar; ++i) {
4166 for (j = 1; j <= i; ++j) {
4167 ndex = i*(i-1) / 2 + j;
4168 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
4169 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
4172 mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
4174 mnwarn(
"W",
"HESSE",
"Matrix inversion fails.");
4180 for (i = 1; i <= fNpar; ++i) {
4183 for (j = 1; j <= i-1; ++j) {
4185 ztemp = fP[i + j*fMaxpar - fMaxpar-1]*2;
4186 fEDM += fGrd[i-1]*ztemp*fGrd[j-1];
4187 fVhmat[ndex-1] = ztemp;
4191 fVhmat[ndex-1] = fP[i + i*fMaxpar - fMaxpar-1]*2;
4192 fEDM += fP[i + i*fMaxpar - fMaxpar-1]*(fGrd[i-1]*fGrd[i-1]);
4194 if (fISW[4] >= 1 && fISW[1] == 3 && fItaur == 0) {
4195 Printf(
" COVARIANCE MATRIX CALCULATED SUCCESSFULLY");
4202 fCstatu =
"FAILED ";
4204 Printf(
" MNHESS FAILS AND WILL RETURN DIAGONAL MATRIX. ");
4206 for (i = 1; i <= fNpar; ++i) {
4208 for (j = 1; j <= i-1; ++j) {
4214 if (g2i <= 0) g2i = 1;
4215 fVhmat[ndex-1] = 2 / g2i;
4227 void TMinuit::mnhes1()
4230 Double_t dmin_, d, dfmin, dgmin=0, change, chgold, grdold=0, epspri;
4231 Double_t fs1, optstp, fs2, grdnew=0, sag, xtf;
4232 Int_t icyc, ncyc=0, idrv, i, nparx;
4235 ldebug = fIdbg[5] >= 1;
4236 if (fIstrat <= 0) ncyc = 1;
4237 if (fIstrat == 1) ncyc = 2;
4238 if (fIstrat > 1) ncyc = 6;
4241 dfmin = fEpsma2*4*(TMath::Abs(fAmin) + fUp);
4243 for (i = 1; i <= fNpar; ++i) {
4245 dmin_ = fEpsma2*4*TMath::Abs(xtf);
4246 epspri = fEpsma2 + TMath::Abs(fGrd[i-1]*fEpsma2);
4247 optstp = TMath::Sqrt(dfmin / (TMath::Abs(fG2[i-1]) + epspri));
4248 d = TMath::Abs(fGstep[i-1])*.2;
4249 if (d > optstp) d = optstp;
4250 if (d < dmin_) d = dmin_;
4253 for (icyc = 1; icyc <= ncyc; ++icyc) {
4256 Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4259 Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
4262 sag = (fs1 + fs2 - fAmin*2)*.5;
4264 grdnew = (fs1 - fs2) / (d*2);
4265 dgmin = fEpsmac*(TMath::Abs(fs1) + TMath::Abs(fs2)) / d;
4267 Printf(
"%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],d,fG2[i-1],grdnew,sag);
4269 if (grdnew == 0)
goto L60;
4270 change = TMath::Abs((grdold - grdnew) / grdnew);
4271 if (change > chgold && icyc > 1)
goto L60;
4274 if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(d);
4275 else fGstep[i-1] = -TMath::Abs(d);
4277 if (change < .05)
goto L60;
4278 if (TMath::Abs(grdold - grdnew) < dgmin)
goto L60;
4280 mnwarn(
"D",
"MNHES1",
"Step size too small for 1st drv.");
4286 mnwarn(
"D",
"MNHES1", TString::Format(
"Too many iterations on D1.%g%g",grdold,grdnew));
4288 fDgrd[i-1] = TMath::Max(dgmin,TMath::Abs(grdold - grdnew));
4304 void TMinuit::mnimpr()
4311 Double_t amax, ycalf, ystar, ystst;
4312 Double_t pb, ep, wg, xi, sigsav, reg, sig2;
4313 Int_t npfn, ndex, loop=0, i, j, ifail, iseed=0;
4314 Int_t jhold, nloop, nparx, nparp1, jh, jl, iswtr;
4316 if (fNpar <= 0)
return;
4317 if (fAmin == fUndefi) mnamin();
4318 fCstatu =
"UNCHANGED ";
4322 nloop = Int_t(fWord7[1]);
4323 if (nloop <= 0) nloop = fNpar + 4;
4326 wg = 1 / Double_t(fNpar);
4329 iswtr = fISW[4] - 2*fItaur;
4330 for (i = 1; i <= fNpar; ++i) {
4332 fIMPRdsav[i-1] = fWerr[i-1];
4333 for (j = 1; j <= i; ++j) {
4334 ndex = i*(i-1) / 2 + j;
4335 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
4336 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
4339 mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
4340 if (ifail >= 1)
goto L280;
4342 for (i = 1; i <= fNpar; ++i) {
4344 for (j = 1; j <= i; ++j) {
4346 fVthmat[ndex-1] = fP[i + j*fMaxpar - fMaxpar-1];
4352 for (i = 1; i <= fNpar; ++i) {
4353 fDirin[i-1] = fIMPRdsav[i-1]*2;
4354 mnrn15(rnum, iseed);
4355 fX[i-1] = fXt[i-1] + fDirin[i-1]*2*(rnum - .5);
4360 Printf(
"START ATTEMPT NO.%2d TO FIND NEW MINIMUM",loop);
4368 fIMPRy[nparp1-1] = fAmin;
4370 for (i = 1; i <= fNpar; ++i) {
4372 mnrn15(rnum, iseed);
4373 fX[i-1] = xi - fDirin[i-1]*(rnum - .5);
4375 fIMPRy[i-1] = ycalf;
4376 if (fIMPRy[i-1] < fAmin) {
4377 fAmin = fIMPRy[i-1];
4379 }
else if (fIMPRy[i-1] > amax) {
4383 for (j = 1; j <= fNpar; ++j) { fP[j + i*fMaxpar - fMaxpar-1] = fX[j-1]; }
4384 fP[i + nparp1*fMaxpar - fMaxpar-1] = xi;
4392 if (fAmin < 0)
goto L95;
4393 if (fISW[1] <= 2)
goto L280;
4395 if (sig2 < ep && fEDM < ep)
goto L100;
4397 if (fNfcn - npfn > fNfcnmx)
goto L300;
4399 for (i = 1; i <= fNpar; ++i) {
4401 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
4402 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
4403 fPstar[i-1] = fPbar[i-1]*2 - fP[i + jh*fMaxpar - fMaxpar-1]*1;
4405 mncalf(fPstar, ycalf);
4407 if (ystar >= fAmin)
goto L70;
4409 for (i = 1; i <= fNpar; ++i) {
4410 fPstst[i-1] = fPstar[i-1]*2 + fPbar[i- 1]*-1;
4412 mncalf(fPstst, ycalf);
4414 if (ystst < fIMPRy[jl-1])
goto L67;
4415 mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4418 mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4422 if (ystar >= fIMPRy[jh-1])
goto L73;
4424 mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4425 if (jhold != jh)
goto L50;
4428 for (i = 1; i <= fNpar; ++i) {
4429 fPstst[i-1] = fP[i + jh*fMaxpar - fMaxpar-1]*.5 + fPbar[i-1]*.5;
4431 mncalf(fPstst, ycalf);
4433 if (ystst > fIMPRy[jh-1])
goto L30;
4435 if (ystst < fAmin)
goto L67;
4436 mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4441 Printf(
" AN IMPROVEMENT ON THE PREVIOUS MINIMUM HAS BEEN FOUND");
4447 Eval(nparx, fGin, fAmin, fU, 4); ++fNfcn;
4448 for (i = 1; i <= fNpar; ++i) {
4449 fDirin[i-1] = reg*fIMPRdsav[i-1];
4450 if (TMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1])
goto L150;
4454 fNfcnmx = fNfcnmx + npfn - fNfcn;
4457 if (fAmin >= fApsi)
goto L325;
4458 for (i = 1; i <= fNpar; ++i) {
4459 fDirin[i-1] = fIMPRdsav[i-1]*.1;
4460 if (TMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1])
goto L250;
4463 if (fAmin < fApsi)
goto L350;
4470 fDcovar = TMath::Max(fDcovar,.5);
4473 fNfcnmx = fNfcnmx + npfn - fNfcn;
4474 fCstatu =
"NEW MINIMU";
4476 Printf(
" IMPROVE HAS FOUND A TRULY NEW MINIMUM");
4477 Printf(
" *************************************");
4483 Printf(
" COVARIANCE MATRIX WAS NOT POSITIVE-DEFINITE");
4489 for (i = 1; i <= fNpar; ++i) {
4490 fDirin[i-1] = fIMPRdsav[i-1]*.01;
4498 Printf(
" IMPROVE HAS RETURNED TO REGION OF ORIGINAL MINIMUM");
4500 fCstatu =
"UNCHANGED ";
4502 if (fISW[1] < 2)
goto L380;
4503 if (loop < nloop && fISW[0] < 1)
goto L20;
4505 if (iswtr >= 0) mnprin(5, fAmin);
4515 void TMinuit::mninex(Double_t *pint)
4519 for (j = 0; j < fNpar; ++j) {
4521 if (fNvarl[i] == 1) {
4524 fU[i] = fAlim[i] + (TMath::Sin(pint[j]) + 1)*.5*(fBlim[i] - fAlim[i]);
4535 void TMinuit::mninit(Int_t i1, Int_t i2, Int_t i3)
4538 volatile Double_t epsp1;
4539 Double_t piby2, epstry, epsbak, distnn;
4545 fIstkwr[0] = fIsyswr;
4550 fCvrsn =
"95.03++ ";
4553 fMaxext = 2*fMaxpar;
4556 fCundef =
")UNDEFINED";
4557 fCovmes[0] =
"NO ERROR MATRIX ";
4558 fCovmes[1] =
"ERR MATRIX APPROXIMATE";
4559 fCovmes[2] =
"ERR MATRIX NOT POS-DEF";
4560 fCovmes[3] =
"ERROR MATRIX ACCURATE ";
4568 fCstatu =
"INITIALIZE";
4578 for (idb = 0; idb <= 10; ++idb) { fIdbg[idb] = 0; }
4598 for (i = 1; i <= 100; ++i) {
4601 mntiny(epsp1, epsbak);
4602 if (epsbak < epstry)
goto L35;
4606 Printf(
" MNINIT UNABLE TO DETERMINE ARITHMETIC PRECISION. WILL ASSUME:%g",fEpsmac);
4609 fEpsma2 = TMath::Sqrt(fEpsmac)*2;
4612 piby2 = TMath::ATan(1)*2;
4613 distnn = TMath::Sqrt(fEpsma2)*8;
4614 fVlimhi = piby2 - distnn;
4615 fVlimlo = -piby2 + distnn;
4625 void TMinuit::mnlims()
4628 Double_t dxdi, snew;
4629 Int_t kint, i2, newcod, ifx=0, inu;
4631 fCfrom =
"SET LIM ";
4633 fCstatu =
"NO CHANGE ";
4634 i2 = Int_t(fWord7[0]);
4635 if (i2 > fMaxext || i2 < 0)
goto L900;
4636 if (i2 > 0)
goto L30;
4639 if (fWord7[1] == fWord7[2]) newcod = 1;
4640 for (inu = 1; inu <= fNu; ++inu) {
4641 if (fNvarl[inu-1] <= 0)
continue;
4642 if (fNvarl[inu-1] == 1 && newcod == 1)
continue;
4643 kint = fNiofex[inu-1];
4647 Printf(
" LIMITS NOT CHANGED FOR FIXED PARAMETER:%4d",inu);
4654 Printf(
" LIMITS REMOVED FROM PARAMETER :%3d",inu);
4656 fCstatu =
"NEW LIMITS";
4657 mndxdi(fX[kint-1], kint-1, dxdi);
4658 snew = fGstep[kint-1]*dxdi;
4659 fGstep[kint-1] = TMath::Abs(snew);
4663 fAlim[inu-1] = TMath::Min(fWord7[1],fWord7[2]);
4664 fBlim[inu-1] = TMath::Max(fWord7[1],fWord7[2]);
4666 Printf(
" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",inu,fAlim[inu-1],fBlim[inu-1]);
4669 fCstatu =
"NEW LIMITS";
4670 fGstep[kint-1] = -.1;
4676 if (fNvarl[i2-1] <= 0) {
4677 Printf(
" PARAMETER %3d IS NOT VARIABLE.", i2);
4680 kint = fNiofex[i2-1];
4683 Printf(
" REQUEST TO CHANGE LIMITS ON FIXED PARAMETER:%3d",i2);
4684 for (ifx = 1; ifx <= fNpfix; ++ifx) {
4685 if (i2 == fIpfix[ifx-1])
goto L92;
4687 Printf(
" MINUIT BUG IN MNLIMS. SEE F. JAMES");
4691 if (fWord7[1] != fWord7[2])
goto L235;
4693 if (fNvarl[i2-1] != 1) {
4695 Printf(
" LIMITS REMOVED FROM PARAMETER %2d",i2);
4697 fCstatu =
"NEW LIMITS";
4699 fGsteps[ifx-1] = TMath::Abs(fGsteps[ifx-1]);
4701 mndxdi(fX[kint-1], kint-1, dxdi);
4702 if (TMath::Abs(dxdi) < .01) dxdi = .01;
4703 fGstep[kint-1] = TMath::Abs(fGstep[kint-1]*dxdi);
4704 fGrd[kint-1] *= dxdi;
4708 Printf(
" NO LIMITS SPECIFIED. PARAMETER %3d IS ALREADY UNLIMITED. NO CHANGE.",i2);
4713 fAlim[i2-1] = TMath::Min(fWord7[1],fWord7[2]);
4714 fBlim[i2-1] = TMath::Max(fWord7[1],fWord7[2]);
4717 Printf(
" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",i2,fAlim[i2-1],fBlim[i2-1]);
4719 fCstatu =
"NEW LIMITS";
4720 if (kint <= 0) fGsteps[ifx-1] = -.1;
4721 else fGstep[kint-1] = -.1;
4724 if (fCstatu !=
"NO CHANGE ") {
4745 void TMinuit::mnline(Double_t *start, Double_t fstart, Double_t *step, Double_t slope, Double_t toler)
4748 Double_t xpq[12], ypq[12], slam, sdev, coeff[3], denom, flast;
4749 Double_t fvals[3], xvals[3], f1, fvmin, xvmin, ratio, f2, f3 = 0., fvmax;
4750 Double_t toler8, toler9, overal, undral, slamin, slamax, slopem;
4751 Int_t i, nparx=0, nvmax=0, nxypt, kk, ipt;
4758 l65 = 0; l70 = 0; l80 = 0;
4759 ldebug = fIdbg[1] >= 1;
4766 Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4768 Printf(
" MNLINE start point not consistent, F values, parameters=");
4769 for (kk = 1; kk <= fNpar; ++kk) {
4770 Printf(
" %14.5e",fX[kk-1]);
4778 chpq[0] = charal[0];
4783 for (i = 1; i <= fNpar; ++i) {
4784 if (step[i-1] != 0) {
4785 ratio = TMath::Abs(start[i-1] / step[i-1]);
4786 if (slamin == 0) slamin = ratio;
4787 if (ratio < slamin) slamin = ratio;
4789 fX[i-1] = start[i-1] + step[i-1];
4791 if (slamin == 0) slamin = fEpsmac;
4796 Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4798 chpq[nxypt-1] = charal[nxypt-1];
4813 denom = (flast - fstart - slope*slam)*2 / (slam*slam);
4815 if (denom != 0) slam = -slope / denom;
4816 if (slam < 0) slam = slamax;
4817 if (slam > slamax) slam = slamax;
4818 if (slam < toler8) slam = toler8;
4819 if (slam < slamin) {
4823 if (TMath::Abs(slam - 1) < toler8 && f1 < fstart) {
4827 if (TMath::Abs(slam - 1) < toler8) slam = toler8 + 1;
4832 for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4835 Eval(nparx, fGin, f2, fU, 4); ++fNfcn;
4837 chpq[nxypt-1] = charal[nxypt-1];
4838 xpq[nxypt-1] = slam;
4844 if (fstart == fvmin) {
4846 toler8 = toler*slam;
4847 overal = slam - toler8;
4850 }
while (fstart == fvmin);
4852 if (!l65 && !l70 && !l80) {
4856 xvals[1] = xpq[nxypt-2];
4857 fvals[1] = ypq[nxypt-2];
4858 xvals[2] = xpq[nxypt-1];
4859 fvals[2] = ypq[nxypt-1];
4862 slamax = TMath::Max(slamax,TMath::Abs(xvmin)*2);
4863 mnpfit(xvals, fvals, 3, coeff, sdev);
4864 if (coeff[2] <= 0) {
4865 slopem = coeff[2]*2*xvmin + coeff[1];
4866 if (slopem <= 0) slam = xvmin + slamax;
4867 else slam = xvmin - slamax;
4869 slam = -coeff[1] / (coeff[2]*2);
4870 if (slam > xvmin + slamax) slam = xvmin + slamax;
4871 if (slam < xvmin - slamax) slam = xvmin - slamax;
4876 else if (slam < undral)
4882 toler9 = TMath::Max(toler8,TMath::Abs(toler8*slam));
4883 for (ipt = 1; ipt <= 3; ++ipt) {
4884 if (TMath::Abs(slam - xvals[ipt-1]) < toler9) {
4895 for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4897 Eval(nparx, fGin, f3, fU, 4); ++fNfcn;
4899 chpq[nxypt-1] = charal[nxypt-1];
4900 xpq[nxypt-1] = slam;
4905 if (fvals[1] > fvmax) {
4909 if (fvals[2] > fvmax) {
4919 if (slam > xvmin) overal = TMath::Min(overal,slam - toler8);
4920 if (slam < xvmin) undral = TMath::Max(undral,slam + toler8);
4921 slam = (slam + xvmin)*.5;
4923 }
while (f3 >= fvmax);
4926 if (l65 || l70)
break;
4928 xvals[nvmax-1] = slam;
4929 fvals[nvmax-1] = f3;
4934 if (slam > xvmin) overal = TMath::Min(overal,slam - toler8);
4935 if (slam < xvmin) undral = TMath::Max(undral,slam + toler8);
4937 }
while (nxypt < 12);
4943 cmess =
" LINE SEARCH HAS EXHAUSTED THE LIMIT OF FUNCTION CALLS ";
4945 Printf(
" MNLINE DEBUG: steps=");
4946 for (kk = 1; kk <= fNpar; ++kk) {
4947 Printf(
" %12.4g",step[kk-1]);
4952 if (l70) cmess =
" LINE SEARCH HAS ATTAINED TOLERANCE ";
4953 if (l80) cmess =
" STEP SIZE AT ARITHMETICALLY ALLOWED MINIMUM";
4956 for (i = 1; i <= fNpar; ++i) {
4957 fDirin[i-1] = step[i-1]*xvmin;
4958 fX[i-1] = start[i-1] + fDirin[i-1];
4962 mnwarn(
"D",
"MNLINE",
" LINE MINIMUM IN BACKWARDS DIRECTION");
4964 if (fvmin == fstart) {
4965 mnwarn(
"D",
"MNLINE",
" LINE SEARCH FINDS NO IMPROVEMENT ");
4968 Printf(
" AFTER %3d POINTS,%s",nxypt,(
const char*)cmess);
4969 mnplot(xpq, ypq, chpq, nxypt, fNpagwd, fNpagln);
4979 void TMinuit::mnmatu(Int_t kode)
4982 Int_t ndex, i, j, m, n, ncoef, nparm, id, it, ix;
4983 Int_t nsofar, ndi, ndj, iso, isw2, isw5;
4988 Printf(
"%s",(
const char*)fCovmes[isw2]);
4992 Printf(
" MNMATU: NPAR=0");
4999 mnemat(fP, fMaxint);
5001 Printf(
"%s",(
const char*)fCovmes[isw2]);
5006 if (fNpar <= 1)
return;
5009 ncoef = (fNpagwd - 19) / 6;
5010 ncoef = TMath::Min(ncoef,20);
5011 nparm = TMath::Min(fNpar,ncoef);
5012 Printf(
" PARAMETER CORRELATION COEFFICIENTS ");
5013 ctemp =
" NO. GLOBAL";
5014 for (
id = 1;
id <= nparm; ++id) {
5015 ctemp += TString::Format(
" %6d",fNexofi[
id-1]);
5017 Printf(
"%s",(
const char*)ctemp);
5018 for (i = 1; i <= fNpar; ++i) {
5020 ndi = i*(i + 1) / 2;
5021 for (j = 1; j <= fNpar; ++j) {
5022 m = TMath::Max(i,j);
5023 n = TMath::Min(i,j);
5024 ndex = m*(m-1) / 2 + n;
5025 ndj = j*(j + 1) / 2;
5026 fMATUvline[j-1] = fVhmat[ndex-1] / TMath::Sqrt(TMath::Abs(fVhmat[ndi-1]*fVhmat[ndj-1]));
5028 nparm = TMath::Min(fNpar,ncoef);
5029 ctemp.Form(
" %3d %7.5f ",ix,fGlobcc[i-1]);
5030 for (it = 1; it <= nparm; ++it) {
5031 ctemp += TString::Format(
" %6.3f",fMATUvline[it-1]);
5033 Printf(
"%s",(
const char*)ctemp);
5034 if (i <= nparm)
continue;
5036 for (iso = 1; iso <= 10; ++iso) {
5038 nparm = TMath::Min(fNpar,nsofar + ncoef);
5039 for (it = nsofar + 1; it <= nparm; ++it) {
5040 ctemp = ctemp + TString::Format(
" %6.3f",fMATUvline[it-1]);
5042 Printf(
"%s",(
const char*)ctemp);
5043 if (i <= nparm)
break;
5047 Printf(
" %s",(
const char*)fCovmes[isw2]);
5059 void TMinuit::mnmigr()
5062 Double_t gdel, gami, vlen, dsum, gssq, vsum, d;
5063 Double_t fzero, fs, ri, delgam, rhotol;
5064 Double_t gdgssq, gvg, vgi;
5065 Int_t npfn, ndex, iext, i, j, m, n, npsdf, nparx;
5066 Int_t iswtr, lined2, kk, nfcnmg, nrstrt,iter;
5068 Double_t toler = 0.05;
5070 if (fNpar <= 0)
return;
5071 if (fAmin == fUndefi) mnamin();
5072 ldebug = kFALSE;
if ( fIdbg[4] >= 1) ldebug = kTRUE;
5076 fCstatu =
"INITIATE ";
5077 iswtr = fISW[4] - 2*fItaur;
5080 vlen = (Double_t) (fNpar*(fNpar + 1) / 2);
5085 rhotol = fApsi*.001;
5087 Printf(
" START MIGRAD MINIMIZATION. STRATEGY %2d. CONVERGENCE WHEN EDM .LT.%9.2e",fIstrat,rhotol);
5090 if (fIstrat < 2 || fISW[1] >= 3)
goto L2;
5093 if (nrstrt > fIstrat) {
5094 fCstatu =
"FAILED ";
5102 if (fISW[1] >= 1)
goto L10;
5107 Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
5110 if (fISW[1] >= 1)
goto L10;
5112 for (i = 1; i <= fNpar; ++i) {
5113 fMIGRxxs[i-1] = fX[i-1];
5118 if (lined2 < (fIstrat + 1)*fNpar) {
5119 for (i = 1; i <= fNpar; ++i) {
5120 if (fG2[i-1] > 0)
continue;
5121 if (fGrd[i-1] > 0) fMIGRstep[i-1] = -TMath::Abs(fGstep[i-1]);
5122 else fMIGRstep[i-1] = TMath::Abs(fGstep[i-1]);
5123 gdel = fMIGRstep[i-1]*fGrd[i-1];
5125 mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
5126 mnwarn(
"D",
"MNMIGR",
"Negative G2 line search");
5127 iext = fNexofi[i-1];
5129 Printf(
" Negative G2 line search, param %3d %13.3g%13.3g",iext,fs,fAmin);
5135 for (i = 1; i <= fNpar; ++i) {
5137 for (j = 1; j <= i-1; ++j) {
5142 if (fG2[i-1] <= 0) fG2[i-1] = 1;
5143 fVhmat[ndex-1] = 2 / fG2[i-1];
5147 Printf(
" DEBUG MNMIGR, STARTING MATRIX DIAGONAL, VHMAT=");
5148 for (kk = 1; kk <= Int_t(vlen); ++kk) {
5149 Printf(
" %10.2g",fVhmat[kk-1]);
5155 if (nrstrt > fIstrat + 1) {
5156 fCstatu =
"FAILED ";
5162 for (i = 1; i <= fNpar; ++i) {
5163 fMIGRgs[i-1] = fGrd[i-1];
5164 fMIGRxxs[i-1] = fX[i-1];
5166 for (j = 1; j <= i-1; ++j) {
5168 fEDM += fMIGRgs[i-1]*fVhmat[ndex-1]*fMIGRgs[j-1];
5171 fEDM += fMIGRgs[i-1]*fMIGRgs[i-1]*.5*fVhmat[ndex-1];
5173 fEDM = fEDM*.5*(fDcovar*3 + 1);
5175 mnwarn(
"W",
"MIGRAD",
"STARTING MATRIX NOT POS-DEFINITE.");
5180 if (fISW[1] == 0) fEDM = fBigedm;
5184 if (iswtr >= 1) mnprin(3, fAmin);
5185 if (iswtr >= 2) mnmatu(0);
5188 if (fNfcn - npfn >= fNfcnmx)
goto L190;
5191 for (i = 1; i <= fNpar; ++i) {
5193 gssq += fMIGRgs[i-1]*fMIGRgs[i-1];
5194 for (j = 1; j <= fNpar; ++j) {
5195 m = TMath::Max(i,j);
5196 n = TMath::Min(i,j);
5197 ndex = m*(m-1) / 2 + n;
5198 ri += fVhmat[ndex-1]*fMIGRgs[j-1];
5200 fMIGRstep[i-1] = ri*-.5;
5201 gdel += fMIGRstep[i-1]*fMIGRgs[i-1];
5204 mnwarn(
"D",
"MIGRAD",
" FIRST DERIVATIVES OF FCN ARE ALL ZERO");
5209 mnwarn(
"D",
"MIGRAD",
" NEWTON STEP NOT DESCENT.");
5210 if (npsdf == 1)
goto L1;
5216 mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
5217 if (fAmin == fs)
goto L200;
5220 fCstatu =
"PROGRESS ";
5224 Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
5234 for (i = 1; i <= fNpar; ++i) {
5237 for (j = 1; j <= fNpar; ++j) {
5238 m = TMath::Max(i,j);
5239 n = TMath::Min(i,j);
5240 ndex = m*(m-1) / 2 + n;
5241 vgi += fVhmat[ndex-1]*(fGrd[j-1] - fMIGRgs[j-1]);
5242 ri += fVhmat[ndex-1]*fGrd[j-1];
5244 fMIGRvg[i-1] = vgi*.5;
5245 gami = fGrd[i-1] - fMIGRgs[i-1];
5246 gdgssq += gami*gami;
5247 gvg += gami*fMIGRvg[i-1];
5248 delgam += fDirin[i-1]*gami;
5249 fEDM += fGrd[i-1]*ri*.5;
5251 fEDM = fEDM*.5*(fDcovar*3 + 1);
5253 if (fEDM < 0 || gvg <= 0) {
5254 mnwarn(
"D",
"MIGRAD",
"NOT POS-DEF. EDM OR GVG NEGATIVE.");
5255 fCstatu =
"NOT POSDEF";
5256 if (npsdf == 1)
goto L230;
5263 if (iswtr >= 3 || (iswtr == 2 && iter % 10 == 1)) {
5268 mnwarn(
"D",
"MIGRAD",
"NO CHANGE IN FIRST DERIVATIVES OVER LAST STEP");
5271 mnwarn(
"D",
"MIGRAD",
"FIRST DERIVATIVES INCREASING ALONG SEARCH LINE");
5274 fCstatu =
"IMPROVEMNT";
5276 Printf(
" VHMAT 1 =");
5277 for (kk = 1; kk <= 10; ++kk) {
5278 Printf(
" %10.2g",fVhmat[kk-1]);
5283 for (i = 1; i <= fNpar; ++i) {
5284 for (j = 1; j <= i; ++j) {
5285 if(delgam == 0 || gvg == 0) d = 0;
5286 else d = fDirin[i-1]*fDirin[j-1] / delgam - fMIGRvg[i-1]*fMIGRvg[j-1] / gvg;
5287 dsum += TMath::Abs(d);
5288 ndex = i*(i-1) / 2 + j;
5289 fVhmat[ndex-1] += d*2;
5290 vsum += TMath::Abs(fVhmat[ndex-1]);
5294 fDcovar = (fDcovar + dsum / vsum)*.5;
5295 if (iswtr >= 3 || ldebug) {
5296 Printf(
" RELATIVE CHANGE IN COV. MATRIX=%5.1f per cent",fDcovar*100);
5299 Printf(
" VHMAT 2 =");
5300 for (kk = 1; kk <= 10; ++kk) {
5301 Printf(
" %10.3g",fVhmat[kk-1]);
5304 if (delgam <= gvg)
goto L135;
5305 for (i = 1; i <= fNpar; ++i) {
5306 fMIGRflnu[i-1] = fDirin[i-1] / delgam - fMIGRvg[i-1] / gvg;
5308 for (i = 1; i <= fNpar; ++i) {
5309 for (j = 1; j <= i; ++j) {
5310 ndex = i*(i-1) / 2 + j;
5311 fVhmat[ndex-1] += gvg*2*fMIGRflnu[i-1]*fMIGRflnu[j-1];
5316 if (fEDM < rhotol*.1)
goto L300;
5318 for (i = 1; i <= fNpar; ++i) {
5319 fMIGRxxs[i-1] = fX[i-1];
5320 fMIGRgs[i-1] = fGrd[i-1];
5323 if (fISW[1] == 0 && fDcovar < .5) fISW[1] = 1;
5324 if (fISW[1] == 3 && fDcovar > .1) fISW[1] = 1;
5325 if (fISW[1] == 1 && fDcovar < .05) fISW[1] = 3;
5332 Printf(
" CALL LIMIT EXCEEDED IN MIGRAD.");
5334 fCstatu =
"CALL LIMIT";
5339 Printf(
" MIGRAD FAILS TO FIND IMPROVEMENT");
5341 for (i = 1; i <= fNpar; ++i) { fX[i-1] = fMIGRxxs[i-1]; }
5342 if (fEDM < rhotol)
goto L300;
5343 if (fEDM < TMath::Abs(fEpsma2*fAmin)) {
5345 Printf(
" MACHINE ACCURACY LIMITS FURTHER IMPROVEMENT.");
5351 Printf(
" MIGRAD FAILS WITH STRATEGY=0. WILL TRY WITH STRATEGY=1.");
5359 Printf(
" MIGRAD TERMINATED WITHOUT CONVERGENCE.");
5361 if (fISW[1] == 3) fISW[1] = 1;
5367 Printf(
" MIGRAD MINIMIZATION HAS CONVERGED.");
5370 if (fIstrat >= 2 || (fIstrat == 1 && fISW[1] < 3)) {
5372 Printf(
" MIGRAD WILL VERIFY CONVERGENCE AND ERROR MATRIX.");
5377 if (fEDM > rhotol)
goto L10;
5380 fCstatu =
"CONVERGED ";
5388 if (iswtr >= 0) mnprin(3, fAmin);
5389 if (iswtr >= 1) mnmatu(1);
5399 void TMinuit::mnmnos()
5402 Double_t val2mi, val2pl;
5403 Int_t nbad, ilax, ilax2, ngood, nfcnmi, iin, knt;
5405 if (fNpar <= 0)
goto L700;
5410 for (knt = 1; knt <= fNpar; ++knt) {
5411 if (Int_t(fWord7[1]) == 0) {
5412 ilax = fNexofi[knt-1];
5414 if (knt >= 7)
break;
5415 ilax = Int_t(fWord7[knt]);
5416 if (ilax == 0)
break;
5417 if (ilax > 0 && ilax <= fNu) {
5418 if (fNiofex[ilax-1] > 0)
goto L565;
5420 Printf(
" PARAMETER NUMBER %3d NOT A VARIABLE. IGNORED.",ilax);
5426 mnmnot(ilax, ilax2, val2pl, val2mi);
5427 if (fLnewmn)
goto L650;
5429 iin = fNiofex[ilax-1];
5430 if (fErp[iin-1] > 0) ++ngood;
5432 if (fErn[iin-1] < 0) ++ngood;
5439 fCstatu =
"UNCHANGED ";
5440 if (ngood == 0 && nbad == 0)
goto L700;
5441 if (ngood > 0 && nbad == 0) fCstatu =
"SUCCESSFUL";
5442 if (ngood == 0 && nbad > 0) fCstatu =
"FAILURE ";
5443 if (ngood > 0 && nbad > 0) fCstatu =
"PROBLEMS ";
5444 if (fISW[4] >= 0) mnprin(4, fAmin);
5445 if (fISW[4] >= 2) mnmatu(0);
5451 fCstatu =
"NEW MINIMU";
5452 if (fISW[4] >= 0) mnprin(4, fAmin);
5453 Printf(
" NEW MINIMUM FOUND. GO BACK TO MINIMIZATION STEP.");
5454 Printf(
" =================================================");
5464 Printf(
" THERE ARE NO MINOS ERRORS TO CALCULATE.");
5474 void TMinuit::mnmnot(Int_t ilax, Int_t ilax2, Double_t &val2pl, Double_t &val2mi)
5480 Double_t delu, aopt, eros;
5481 Double_t abest, xunit, dc, ut, sigsav, du1;
5482 Double_t fac, sig, sav;
5483 Int_t marc, isig, mpar, ndex, imax, indx, ierr, i, j;
5484 Int_t iercr, it, istrav, nfmxin, nlimit, isw2, isw4;
5498 for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
5499 i__1 = mpar*(mpar + 1) / 2;
5500 for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
5501 for (i = 1; i <= mpar; ++i) {
5502 fMNOTgcc[i-1] = fGlobcc[i-1];
5503 fMNOTw[i-1] = fWerr[i-1];
5505 it = fNiofex[ilax-1];
5510 if (fNvarl[ilax-1] == 1) {
5511 fAlim[ilax-1] = ut - fMNOTw[it-1]*100;
5512 fBlim[ilax-1] = ut + fMNOTw[it-1]*100;
5514 ndex = it*(it + 1) / 2;
5515 xunit = TMath::Sqrt(fUp / fVthmat[ndex-1]);
5517 for (i = 1; i <= mpar; ++i) {
5518 if (i == it)
continue;
5520 imax = TMath::Max(it,i);
5521 indx = imax*(imax-1) / 2 + TMath::Min(it,i);
5522 fMNOTxdev[marc-1] = xunit*fVthmat[indx-1];
5527 Printf(
" MINUIT ERROR. CANNOT FIX PARAMETER %4d INTERNAL %3d",ilax,it);
5533 for (isig = 1; isig <= 2; ++isig) {
5543 Printf(
" DETERMINATION OF %sTIVE MINOS ERROR FOR PARAMETER %d %s"
5544 ,(
const char*)csig,ilax
5545 ,(
const char*)fCpnam[ilax-1]);
5548 mnwarn(
"D",
"MINOS",
"NO COVARIANCE MATRIX.");
5550 nlimit = fNfcn + nfmxin;
5551 fIstrat = TMath::Max(istrav-1,0);
5553 fU[ilax-1] = ut + sig*du1;
5554 fU[ilax-1] = TMath::Min(fU[ilax-1],fBlim[ilax-1]);
5555 fU[ilax-1] = TMath::Max(fU[ilax-1],fAlim[ilax-1]);
5556 delu = fU[ilax-1] - ut;
5558 if (TMath::Abs(delu) / (TMath::Abs(ut) + TMath::Abs(fU[ilax-1])) < fEpsmac)
goto L440;
5559 fac = delu / fMNOTw[it-1];
5560 for (i = 1; i <= fNpar; ++i) {
5561 fX[i-1] = fXt[i-1] + fac*fMNOTxdev[i-1];
5564 Printf(
" PARAMETER %4d SET TO%11.3e + %10.3e = %12.3e",ilax,ut,delu,fU[ilax-1]);
5569 fXmidcr = fU[ilax-1];
5573 fNfcnmx = nlimit - fNfcn;
5574 mncros(aopt, iercr);
5575 if (abest - fAmin > fUp*.01)
goto L650;
5576 if (iercr == 1)
goto L440;
5577 if (iercr == 2)
goto L450;
5578 if (iercr == 3)
goto L460;
5580 eros = fXmidcr - ut + aopt*fXdircr;
5582 Printf(
" THE %4sTIVE MINOS ERROR OF PARAMETER %3d %10s, IS %12.4e"
5583 ,(
const char*)csig,ilax
5584 ,(
const char*)fCpnam[ilax-1],eros);
5590 Printf(
" THE %4sTIVE MINOS ERROR OF PARAMETER %3d, %s EXCEEDS ITS LIMIT."
5591 ,(
const char*)csig,ilax
5592 ,(
const char*)fCpnam[ilax-1]);
5598 Printf(
" THE %4sTIVE MINOS ERROR %4d REQUIRES MORE THAN %5d FUNCTION CALLS."
5599 ,(
const char*)csig,ilax,nfmxin);
5605 Printf(
" %4sTIVE MINOS ERROR NOT CALCULATED FOR PARAMETER %d"
5606 ,(
const char*)csig,ilax);
5612 Printf(
" **************************************************************************");
5616 if (ilax2 > 0 && ilax2 <= fNu) val2mi = fU[ilax2-1];
5619 if (ilax2 > 0 && ilax2 <= fNu) val2pl = fU[ilax2-1];
5626 i__1 = mpar*(mpar + 1) / 2;
5627 for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
5628 for (i = 1; i <= mpar; ++i) {
5629 fWerr[i-1] = fMNOTw[i-1];
5630 fGlobcc[i-1] = fMNOTgcc[i-1];
5674 void TMinuit::mnparm(Int_t k1, TString cnamj, Double_t uk, Double_t wk, Double_t a, Double_t b, Int_t &ierflg)
5677 Double_t vplu, a_small, gsmin, pinti, vminu, danger, sav, sav2;
5678 Int_t ierr, kint, in, ix, ktofix, lastin, kinfix, nvl;
5679 TString cnamk, chbufi;
5684 if (k < 1 || k > fMaxext) {
5686 Printf(
" MINUIT USER ERROR. PARAMETER NUMBER IS %3d ALLOWED RANGE IS ONE TO %4d",k,fMaxext);
5691 if (fNvarl[k-1] < 0)
goto L50;
5694 for (ix = 1; ix <= fNpfix; ++ix) {
5695 if (fIpfix[ix-1] == k) ktofix = k;
5698 mnwarn(
"W",
"PARAM DEF",
"REDEFINING A FIXED PARAMETER.");
5699 if (kint >= fMaxint) {
5700 Printf(
" CANNOT RELEASE. MAX NPAR EXCEEDED.");
5706 if (fNiofex[k-1] > 0) kint = fNpar - 1;
5710 if (fLphead && fISW[4] >= 0) {
5711 Printf(
" PARAMETER DEFINITIONS:");
5712 Printf(
" NO. NAME VALUE STEP SIZE LIMITS");
5715 if (wk > 0)
goto L122;
5718 Printf(
" %5d %-10s %13.5e constant",k,(
const char*)cnamk,uk);
5723 if (a == 0 && b == 0) {
5727 Printf(
" %5d %-10s %13.5e%13.5e no limits",k,(
const char*)cnamk,uk,wk);
5734 Printf(
" %5d %-10s %13.5e%13.5e %13.5e%13.5e",k,(
const char*)cnamk,uk,wk,a,b);
5739 if (kint > fMaxint) {
5740 Printf(
" MINUIT USER ERROR. TOO MANY VARIABLE PARAMETERS.");
5743 if (nvl == 1)
goto L200;
5745 Printf(
" USER ERROR IN MINUIT PARAMETER");
5746 Printf(
" DEFINITION");
5747 Printf(
" UPPER AND LOWER LIMITS EQUAL.");
5754 mnwarn(
"W",
"PARAM DEF",
"PARAMETER LIMITS WERE REVERSED.");
5755 if (fLwarn) fLphead = kTRUE;
5758 mnwarn(
"W",
"PARAM DEF", TString::Format(
"LIMITS ON PARAM%d TOO FAR APART.",k));
5759 if (fLwarn) fLphead = kTRUE;
5761 danger = (b - uk)*(uk - a);
5763 mnwarn(
"W",
"PARAM DEF",
"STARTING VALUE OUTSIDE LIMITS.");
5766 mnwarn(
"W",
"PARAM DEF",
"STARTING VALUE IS AT LIMIT.");
5771 fCfrom =
"PARAMETR";
5773 fCstatu =
"NEW VALUES";
5774 fNu = TMath::Max(fNu,k);
5775 fCpnam[k-1] = cnamk;
5784 for (ix = 1; ix <= k-1; ++ix) {
if (fNiofex[ix-1] > 0) ++lastin; }
5786 if (kint == fNpar)
goto L280;
5789 for (in = fNpar; in >= lastin + 1; --in) {
5791 fNiofex[ix-1] = in + 1;
5794 fXt[in] = fXt[in-1];
5795 fDirin[in] = fDirin[in-1];
5796 fG2[in] = fG2[in-1];
5797 fGstep[in] = fGstep[in-1];
5798 fWerr[in] = fWerr[in-1];
5799 fGrd[in] = fGrd[in-1];
5803 for (in = lastin + 1; in <= kint; ++in) {
5808 fXt[in-1] = fXt[in];
5809 fDirin[in-1] = fDirin[in];
5810 fG2[in-1] = fG2[in];
5811 fGstep[in-1] = fGstep[in];
5812 fWerr[in-1] = fWerr[in];
5813 fGrd[in-1] = fGrd[in];
5826 mnpint(sav, ix-1, pinti);
5828 fXt[in-1] = fX[in-1];
5831 mnpint(sav2, ix-1, pinti);
5832 vplu = pinti - fX[in-1];
5834 mnpint(sav2, ix-1, pinti);
5835 vminu = pinti - fX[in-1];
5836 fDirin[in-1] = (TMath::Abs(vplu) + TMath::Abs(vminu))*.5;
5837 fG2[in-1] = fUp*2 / (fDirin[in-1]*fDirin[in-1]);
5838 gsmin = fEpsma2*8*TMath::Abs(fX[in-1]);
5839 fGstep[in-1] = TMath::Max(gsmin,fDirin[in-1]*.1);
5840 if (fAmin != fUndefi) {
5841 a_small = TMath::Sqrt(fEpsma2*(fAmin + fUp) / fUp);
5842 fGstep[in-1] = TMath::Max(gsmin,a_small*fDirin[in-1]);
5844 fGrd[in-1] = fG2[in-1]*fDirin[in-1];
5846 if (fNvarl[k-1] > 1) {
5847 if (fGstep[in-1] > .5) fGstep[in-1] = .5;
5848 fGstep[in-1] = -fGstep[in-1];
5853 kinfix = fNiofex[ktofix-1];
5854 if (kinfix > 0) mnfixp(kinfix-1, ierr);
5855 if (ierr > 0)
goto L800;
5876 void TMinuit::mnpars(TString &crdbuf, Int_t &icondn)
5879 Double_t a=0, b=0, fk=0, uk=0, wk=0, xk=0;
5880 Int_t ierr, kapo1, kapo2;
5881 Int_t k, llist, ibegin, lenbuf, istart, lnc, icy;
5882 TString cnamk, comand, celmnt, ctemp;
5885 lenbuf = strlen((
const char*)crdbuf);
5887 kapo1 = strspn((
const char*)crdbuf,
"'");
5888 if (kapo1 == 0)
goto L150;
5889 kapo2 = strspn((
const char*)crdbuf + kapo1,
"'");
5890 if (kapo2 == 0)
goto L150;
5894 for (istart = 1; istart <= kapo1-1; ++istart) {
5895 if (crdbuf(istart-1,1) !=
' ')
goto L120;
5900 celmnt = crdbuf(istart-1, kapo1-istart);
5901 if (scanf((
const char*)celmnt,&fk)) {;}
5903 if (k <= 0)
goto L210;
5904 cnamk =
"PARAM " + celmnt;
5905 if (kapo2 - kapo1 > 1) {
5906 cnamk = crdbuf(kapo1, kapo2-1-kapo1);
5909 for (icy = kapo2 + 1; icy <= lenbuf; ++icy) {
5910 if (crdbuf(icy-1,1) ==
',')
goto L139;
5911 if (crdbuf(icy-1,1) !=
' ')
goto L140;
5922 ctemp = crdbuf(ibegin-1,lenbuf-ibegin);
5923 mncrck(ctemp, 20, comand, lnc, fMaxpar, fPARSplist, llist, ierr, fIsyswr);
5924 if (ierr > 0)
goto L180;
5927 if (llist >= 2) wk = fPARSplist[1];
5929 if (llist >= 3) a = fPARSplist[2];
5931 if (llist >= 4) b = fPARSplist[3];
5935 if (scanf((
const char*)crdbuf,&xk,stmp,&uk,&wk,&a,&b)) {;}
5938 if (k == 0)
goto L210;
5941 mnparm(k-1, cnamk, uk, wk, a, b, ierr);
5965 void TMinuit::mnpfit(Double_t *parx2p, Double_t *pary2p, Int_t npar2p, Double_t *coef2p, Double_t &sdev2p)
5968 Double_t a, f, s, t, y, s2, x2, x3, x4, y2, cz[3], xm, xy, x2y;
5978 for (i = 1; i <= 3; ++i) { cz[i-1] = 0; }
5980 if (npar2p < 3)
goto L10;
5981 f = (Double_t) (npar2p);
5984 for (i = 1; i <= npar2p; ++i) { xm += parx2p[i]; }
5993 for (i = 1; i <= npar2p; ++i) {
6005 a = (f*x4 - x2*x2)*x2 - f*(x3*x3);
6006 if (a == 0)
goto L10;
6007 cz[2] = (x2*(f*x2y - x2*y) - f*x3*xy) / a;
6008 cz[1] = (xy - x3*cz[2]) / x2;
6009 cz[0] = (y - x2*cz[2]) / f;
6010 if (npar2p == 3)
goto L6;
6011 sdev2p = y2 - (cz[0]*y + cz[1]*xy + cz[2]*x2y);
6012 if (sdev2p < 0) sdev2p = 0;
6015 cz[0] += xm*(xm*cz[2] - cz[1]);
6016 cz[1] -= xm*2*cz[2];
6018 for (i = 1; i <= 3; ++i) { coef2p[i] = cz[i-1]; }
6026 void TMinuit::mnpint(Double_t &pexti, Int_t i1, Double_t &pinti)
6029 Double_t a, alimi, blimi, yy, yy2;
6031 TString chbuf2, chbufi;
6040 yy = (pexti - alimi)*2 / (blimi - alimi) - 1;
6042 if (yy2 >= 1 - fEpsma2) {
6045 chbuf2 =
" IS AT ITS LOWER ALLOWED LIMIT.";
6048 chbuf2 =
" IS AT ITS UPPER ALLOWED LIMIT.";
6051 pexti = alimi + (blimi - alimi)*.5*(TMath::Sin(a) + 1);
6053 if (yy2 > 1) chbuf2 =
" BROUGHT BACK INSIDE LIMITS.";
6054 mnwarn(
"W", fCfrom, TString::Format(
"VARIABLE%d%s",i,chbuf2.Data()));
6056 pinti = TMath::ASin(yy);
6077 void TMinuit::mnplot(Double_t *xpt, Double_t *ypt,
char *chpt, Int_t nxypt, Int_t npagwd, Int_t npagln)
6080 if (fGraphicsMode) {
6082 if ((h = gROOT->GetPluginManager()->FindHandler(
"TMinuitGraph"))) {
6084 if (h->LoadPlugin() != -1)
6085 fPlot = (TObject*)h->ExecPlugin(3,nxypt-2,&xpt[2],&ypt[2]);
6091 Double_t xmin, ymin, xmax, ymax, savx, savy, yprt;
6092 Double_t bwidx, bwidy, xbest, ybest, ax, ay, bx, by;
6093 Double_t xvalus[12], any, dxx, dyy;
6094 Int_t iten, i, j, k, maxnx, maxny, iquit, ni, linodd;
6095 Int_t nxbest, nybest, km1, ibk, isp1, nx, ny, ks, ix;
6096 TString chmess, ctemp;
6103 maxnx = TMath::Min(npagwd-20,100);
6104 if (maxnx < 10) maxnx = 10;
6106 if (maxny < 10) maxny = 10;
6107 if (nxypt <= 1)
return;
6113 for (i = 1; i <= km1; ++i) {
6116 for (j = 1; j <= ni; ++j) {
6117 if (ypt[j-1] > ypt[j])
continue;
6129 if (iquit == 0)
break;
6134 for (i = 1; i <= nxypt; ++i) {
6135 if (xpt[i-1] > xmax) xmax = xpt[i-1];
6136 if (xpt[i-1] < xmin) xmin = xpt[i-1];
6138 dxx = (xmax - xmin)*.001;
6141 mnbins(xmin, xmax, maxnx, xmin, xmax, nx, bwidx);
6143 ymin = ypt[nxypt-1];
6144 if (ymax == ymin) ymax = ymin + 1;
6145 dyy = (ymax - ymin)*.001;
6148 mnbins(ymin, ymax, maxny, ymin, ymax, ny, bwidy);
6149 any = (Double_t) ny;
6151 if (chbest ==
' ')
goto L50;
6152 xbest = (xmax + xmin)*.5;
6153 ybest = (ymax + ymin)*.5;
6161 for (i = 1; i <= nxypt; ++i) {
6162 xpt[i-1] = ax*xpt[i-1] + bx;
6163 ypt[i-1] = any - ay*ypt[i-1] - by;
6165 nxbest = Int_t((ax*xbest + bx));
6166 nybest = Int_t((any - ay*ybest - by));
6173 for (i = 1; i <= ny; ++i) {
6174 for (ibk = 1; ibk <= nx; ++ibk) { cline[ibk-1] =
' '; }
6179 if (nx>0) cline[nx-1] =
'.';
6180 cline[nxbest-1] =
'.';
6181 if (i != 1 && i != nybest && i != ny)
goto L320;
6182 for (j = 1; j <= nx; ++j) { cline[j-1] =
'.'; }
6184 yprt = ymax - Double_t(i-1)*bwidy;
6185 if (isp1 > nxypt)
goto L350;
6187 for (k = isp1; k <= nxypt; ++k) {
6188 ks = Int_t(ypt[k-1]);
6189 if (ks > i)
goto L345;
6190 ix = Int_t(xpt[k-1]);
6191 if (cline[ix-1] ==
'.')
goto L340;
6192 if (cline[ix-1] ==
' ')
goto L340;
6193 if (cline[ix-1] == chpt[k-1])
continue;
6200 cline[ix-1] = chpt[k-1];
6207 if (linodd == 1 || i == ny)
goto L380;
6210 Printf(
" %s",(
const char*)ctemp);
6214 Printf(
" %14.7g ..%s",yprt,(
const char*)ctemp);
6220 for (ibk = 1; ibk <= nx; ++ibk) {
6222 if (ibk % 10 == 1) cline[ibk-1] =
'/';
6224 Printf(
" %s",cline);
6226 for (ibk = 1; ibk <= 12; ++ibk) {
6227 xvalus[ibk-1] = xmin + Double_t(ibk-1)*10*bwidx;
6229 iten = (nx + 9) / 10;
6231 for (ibk = 1; ibk <= iten; ++ibk)
6232 Printf(
"%# 8.3g ", xvalus[ibk-1]);
6235 if (overpr) chmess =
" Overprint character is &";
6236 Printf(
" ONE COLUMN=%13.7g%s",bwidx,(
const char*)chmess);
6256 void TMinuit::mnpout(Int_t iuext1, TString &chnam, Double_t &val, Double_t &err, Double_t &xlolim, Double_t &xuplim, Int_t &iuint)
const
6259 Int_t iint, iext, nvl;
6261 Int_t iuext = iuext1 + 1;
6265 if (iuext == 0)
goto L100;
6269 if (iint > fNpar)
goto L100;
6270 iext = fNexofi[iint-1];
6275 if (iext > fNu)
goto L100;
6276 iint = fNiofex[iext-1];
6280 nvl = fNvarl[iext-1];
6281 if (nvl < 0)
goto L100;
6282 chnam = fCpnam[iext-1];
6284 if (iint > 0) err = fWerr[iint-1];
6286 xlolim = fAlim[iext-1];
6287 xuplim = fBlim[iext-1];
6293 chnam =
"undefined";
6313 void TMinuit::mnprin(Int_t inkode, Double_t fval)
6317 static const TString cblank =
" ";
6318 TString cnambf =
" ";
6321 Double_t dcmax, x1, x2, x3, dc;
6323 Int_t nadd, i, k, l, m, ikode, ic, nc, ntrail, lbl;
6325 TString colhdl[6], colhdu[6], cx2, cx3, cheval;
6328 Printf(
" THERE ARE CURRENTLY NO PARAMETERS DEFINED");
6334 ikode = fISW[1] + 1;
6335 if (ikode > 3) ikode = 3;
6338 for (k = 1; k <= 6; ++k) {
6339 colhdu[k-1] =
"UNDEFINED";
6340 colhdl[k-1] =
"COLUMN HEAD";
6343 if (ikode == 4 && fCtitl != fCundef) {
6344 Printf(
" MINUIT TASK: %s",(
const char*)fCtitl);
6347 if (fval == fUndefi) cheval =
" unknown ";
6348 else cheval.Form(
"%g",fval);
6350 if (fEDM == fBigedm) chedm =
" unknown ";
6351 else chedm.Form(
"%g",fEDM);
6353 nc = fNfcn - fNfcnfr;
6354 Printf(
" FCN=%s FROM %8s STATUS=%10s %6d CALLS %9d TOTAL"
6355 ,(
const char*)cheval
6356 ,(
const char*)fCfrom
6357 ,(
const char*)fCstatu,nc,fNfcn);
6359 if (m == 0 || m == 2 || fDcovar == 0) {
6360 Printf(
" EDM=%s STRATEGY=%2d %s"
6361 ,(
const char*)chedm,fIstrat
6362 ,(
const char*)fCovmes[m]);
6365 dc = TMath::Min(fDcovar,dcmax)*100;
6366 Printf(
" EDM=%s STRATEGY=%2d ERROR MATRIX UNCERTAINTY %5.1f per cent"
6367 ,(
const char*)chedm,fIstrat,dc);
6370 if (ikode == 0)
return;
6373 for (i = 1; i <= fNu; ++i) {
6374 if (fNvarl[i-1] < 0)
continue;
6375 for (ic = 10; ic >= 1; --ic) {
6376 if (fCpnam[i-1](ic-1,1) !=
" ")
goto L16;
6381 if (lbl < ntrail) ntrail = lbl;
6383 nadd = ntrail / 2 + 1;
6386 colhdl[0] =
" ERROR ";
6387 colhdu[1] =
" PHYSICAL";
6388 colhdu[2] =
" LIMITS ";
6389 colhdl[1] =
" NEGATIVE ";
6390 colhdl[2] =
" POSITIVE ";
6394 colhdl[0] =
" ERROR ";
6395 colhdu[1] =
" INTERNAL ";
6396 colhdl[1] =
" STEP SIZE ";
6397 colhdu[2] =
" INTERNAL ";
6398 colhdl[2] =
" VALUE ";
6402 colhdl[0] =
" ERROR ";
6403 colhdu[1] =
" STEP ";
6404 colhdl[1] =
" SIZE ";
6405 colhdu[2] =
" FIRST ";
6406 colhdl[2] =
" DERIVATIVE ";
6409 colhdu[0] =
" PARABOLIC ";
6410 colhdl[0] =
" ERROR ";
6411 colhdu[1] =
" MINOS ";
6412 colhdu[2] =
"ERRORS ";
6413 colhdl[1] =
" NEGATIVE ";
6414 colhdl[2] =
" POSITIVE ";
6418 if (fISW[1] < 3) colhdu[0] =
" APPROXIMATE ";
6419 if (fISW[1] < 1) colhdu[0] =
" CURRENT GUESS";
6421 Printf(
" EXT PARAMETER %-14s%-14s%-14s",(
const char*)colhdu[0]
6422 ,(
const char*)colhdu[1]
6423 ,(
const char*)colhdu[2]);
6424 Printf(
" NO. NAME VALUE %-14s%-14s%-14s",(
const char*)colhdl[0]
6425 ,(
const char*)colhdl[1]
6426 ,(
const char*)colhdl[2]);
6428 for (i = 1; i <= fNu; ++i) {
6429 if (fNvarl[i-1] < 0)
continue;
6431 cnambf = cblank(0,nadd) + fCpnam[i-1];
6432 if (l == 0)
goto L55;
6435 cx2 =
"PLEASE GET X..";
6436 cx3 =
"PLEASE GET X..";
6438 if (fNvarl[i-1] <= 1) {
6439 Printf(
"%4d %-11s%14.5e%14.5e",i,(
const char*)cnambf,fU[i-1],x1);
6453 if (fNvarl[i-1] > 1 && TMath::Abs(TMath::Cos(fX[l-1])) < .001) {
6454 cx3 =
"** at limit **";
6459 if (x2 == 0) cx2 =
" ";
6460 if (x2 == fUndefi) cx2 =
" at limit ";
6462 if (x3 == 0) cx3 =
" ";
6463 if (x3 == fUndefi) cx3 =
" at limit ";
6465 if (cx2 ==
"PLEASE GET X..") cx2.Form(
"%14.5e",x2);
6466 if (cx3 ==
"PLEASE GET X..") cx3.Form(
"%14.5e",x3);
6467 Printf(
"%4d %-11s%14.5e%14.5e%-14s%-14s",i
6468 ,(
const char*)cnambf,fU[i-1],x1
6469 ,(
const char*)cx2,(
const char*)cx3);
6472 if (fNvarl[i-1] <= 1 || ikode == 3)
continue;
6473 if (TMath::Abs(TMath::Cos(fX[l-1])) < .001) {
6474 Printf(
" WARNING - - ABOVE PARAMETER IS AT LIMIT.");
6480 colhdu[0] =
" constant ";
6481 if (fNvarl[i-1] > 0) colhdu[0] =
" fixed ";
6482 if (fNvarl[i-1] == 4 && ikode == 1) {
6483 Printf(
"%4d %-11s%14.5e%-14s%14.5e%14.5e",i
6484 ,(
const char*)cnambf,fU[i-1]
6485 ,(
const char*)colhdu[0],fAlim[i-1],fBlim[i-1]);
6487 Printf(
"%4d %-11s%14.5e%s",i
6488 ,(
const char*)cnambf,fU[i-1],(
const char*)colhdu[0]);
6492 if (fUp != fUpdflt) {
6493 Printf(
" ERR DEF= %g",fUp);
6503 void TMinuit::mnpsdf()
6506 Double_t dgmin, padd, pmin, pmax, dg, epspdf, epsmin;
6507 Int_t ndex, i, j, ndexd, ip, ifault;
6508 TString chbuff, ctemp;
6511 epspdf = TMath::Max(epsmin,fEpsma2);
6514 for (i = 1; i <= fNpar; ++i) {
6515 ndex = i*(i + 1) / 2;
6516 if (fVhmat[ndex-1] <= 0) {
6517 mnwarn(
"W", fCfrom, TString::Format(
"Negative diagonal element %d in Error Matrix",i));
6519 if (fVhmat[ndex-1] < dgmin) dgmin = fVhmat[ndex-1];
6522 dg = epspdf + 1 - dgmin;
6523 mnwarn(
"W", fCfrom, TString::Format(
"%g added to diagonal of error matrix",dg));
6528 for (i = 1; i <= fNpar; ++i) {
6531 fVhmat[ndexd-1] += dg;
6532 if (fVhmat[ndexd-1]==0) {
6533 fPSDFs[i-1] = 1 / 1e-19;
6535 fPSDFs[i-1] = 1 / TMath::Sqrt(fVhmat[ndexd-1]);
6537 for (j = 1; j <= i; ++j) {
6539 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1]*fPSDFs[i-1]*fPSDFs[j-1];
6543 mneig(fP, fMaxint, fNpar, fMaxint, fPstar, epspdf, ifault);
6546 for (ip = 2; ip <= fNpar; ++ip) {
6547 if (fPstar[ip-1] < pmin) pmin = fPstar[ip-1];
6548 if (fPstar[ip-1] > pmax) pmax = fPstar[ip-1];
6550 pmax = TMath::Max(TMath::Abs(pmax),Double_t(1));
6551 if ((pmin <= 0 && fLwarn) || fISW[4] >= 2) {
6552 Printf(
" EIGENVALUES OF SECOND-DERIVATIVE MATRIX:");
6554 for (ip = 1; ip <= fNpar; ++ip) {
6555 ctemp += TString::Format(
" %11.4e",fPstar[ip-1]);
6557 Printf(
"%s", ctemp.Data());
6559 if (pmin > epspdf*pmax)
return;
6560 if (fISW[1] == 3) fISW[1] = 2;
6561 padd = pmax*.001 - pmin;
6562 for (ip = 1; ip <= fNpar; ++ip) {
6563 ndex = ip*(ip + 1) / 2;
6564 fVhmat[ndex-1] *= padd + 1;
6566 fCstatu =
"NOT POSDEF";
6567 mnwarn(
"W", fCfrom, Form(
"MATRIX FORCED POS-DEF BY ADDING %f TO DIAGONAL.",padd));
6577 void TMinuit::mnrazz(Double_t ynew, Double_t *pnew, Double_t *y, Int_t &jh, Int_t &jl)
6580 Double_t pbig, plit;
6584 for (i = 1; i <= fNpar; ++i) { fP[i + jh*fMaxpar - fMaxpar-1] = pnew[i-1]; }
6587 for (i = 1; i <= fNpar; ++i) { fX[i-1] = pnew[i-1]; }
6590 fCstatu =
"PROGRESS ";
6595 for (j = 2; j <= nparp1; ++j) {
if (y[j-1] > y[jh-1]) jh = j; }
6596 fEDM = y[jh-1] - y[jl-1];
6597 if (fEDM <= 0)
goto L45;
6598 for (i = 1; i <= fNpar; ++i) {
6601 for (j = 2; j <= nparp1; ++j) {
6602 if (fP[i + j*fMaxpar - fMaxpar-1] > pbig) pbig = fP[i + j*fMaxpar - fMaxpar-1];
6603 if (fP[i + j*fMaxpar - fMaxpar-1] < plit) plit = fP[i + j*fMaxpar - fMaxpar-1];
6605 fDirin[i-1] = pbig - plit;
6610 Printf(
" FUNCTION VALUE DOES NOT SEEM TO DEPEND ON ANY OF THE %d VARIABLE PARAMETERS.",fNpar);
6611 Printf(
" VERIFY THAT STEP SIZES ARE BIG ENOUGH AND CHECK FCN LOGIC.");
6612 Printf(
" *******************************************************************************");
6613 Printf(
" *******************************************************************************");
6626 void TMinuit::mnrn15(Double_t &val, Int_t &inseed)
6630 static std::atomic<Int_t> g_iseed( 12345 );
6636 g_iseed.store(inseed, std::memory_order_release);
6640 int starting_seed = g_iseed.load( std::memory_order_acquire );
6644 next_seed = inseed = starting_seed;
6647 k = next_seed / 53668;
6648 next_seed = (next_seed - k*53668)*40014 - k*12211;
6649 if (next_seed < 0) next_seed += 2147483563;
6651 val = Double_t(next_seed*4.656613e-10);
6656 }
while (! g_iseed.compare_exchange_strong(starting_seed, next_seed) );
6668 void TMinuit::mnrset(Int_t iopt)
6675 fFval3 = TMath::Abs(fAmin)*2 + 1;
6683 for (i = 1; i <= fNpar; ++i) {
6684 iext = fNexofi[i-1];
6685 if (fNvarl[iext-1] >= 4) fLnolim = kFALSE;
6692 fDcovar = TMath::Max(fDcovar,.5);
6702 void TMinuit::mnsave()
6704 Printf(
"mnsave is dummy in TMinuit");
6715 void TMinuit::mnscan()
6718 Double_t step, uhigh, xhreq, xlreq, ubest, fnext, unext, xh, xl;
6719 Int_t ipar, iint, icall, ncall, nbins, nparx;
6720 Int_t nxypt, nccall, iparwd;
6722 xlreq = TMath::Min(fWord7[2],fWord7[3]);
6723 xhreq = TMath::Max(fWord7[2],fWord7[3]);
6724 ncall = Int_t((fWord7[1] + .01));
6725 if (ncall <= 1) ncall = 41;
6726 if (ncall > 98) ncall = 98;
6728 if (fAmin == fUndefi) mnamin();
6729 iparwd = Int_t((fWord7[0] + .1));
6730 ipar = TMath::Max(iparwd,0);
6731 fCstatu =
"NO CHANGE";
6732 if (iparwd > 0)
goto L200;
6737 if (ipar > fNu)
goto L900;
6738 iint = fNiofex[ipar-1];
6739 if (iint <= 0)
goto L100;
6742 iint = fNiofex[ipar-1];
6751 if (fNvarl[ipar-1] > 1)
goto L300;
6754 if (xlreq == xhreq)
goto L250;
6756 step = (xhreq - xlreq) / Double_t(ncall-1);
6759 xl = ubest - fWerr[iint-1];
6760 xh = ubest + fWerr[iint-1];
6761 mnbins(xl, xh, ncall, unext, uhigh, nbins, step);
6766 if (xlreq == xhreq)
goto L350;
6768 xl = TMath::Max(xlreq,fAlim[ipar-1]);
6770 xh = TMath::Min(xhreq,fBlim[ipar-1]);
6771 if (xl >= xh)
goto L700;
6773 step = (xh - xl) / Double_t(ncall-1);
6776 unext = fAlim[ipar-1];
6777 step = (fBlim[ipar-1] - fAlim[ipar-1]) / Double_t(ncall-1);
6780 for (icall = 1; icall <= nccall; ++icall) {
6783 Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
6785 fXpt[nxypt-1] = unext;
6786 fYpt[nxypt-1] = fnext;
6787 fChpt[nxypt-1] =
'*';
6788 if (fnext < fAmin) {
6791 fCstatu =
"IMPROVED ";
6801 Printf(
"%dSCAN OF PARAMETER NO. %d, %s"
6802 ,fNewpag,ipar,(
const char*)fCpnam[ipar-1]);
6803 mnplot(fXpt, fYpt, fChpt, nxypt, fNpagwd, fNpagln);
6806 Printf(
" REQUESTED RANGE OUTSIDE LIMITS FOR PARAMETER %d",ipar);
6808 if (iparwd <= 0)
goto L100;
6811 if (fISW[4] >= 0) mnprin(5, fAmin);
6825 void TMinuit::mnseek()
6828 Double_t dxdi, rnum, ftry, rnum1, rnum2, alpha;
6829 Double_t flast, bar;
6830 Int_t ipar, iext, j, ifail, iseed=0, nparx, istep, ib, mxfail, mxstep;
6832 mxfail = Int_t(fWord7[0]);
6833 if (mxfail <= 0) mxfail = fNpar*20 + 100;
6835 if (fAmin == fUndefi) mnamin();
6837 if (alpha <= 0) alpha = 3;
6839 Printf(
" MNSEEK: MONTE CARLO MINIMIZATION USING METROPOLIS ALGORITHM");
6840 Printf(
" TO STOP AFTER %6d SUCCESSIVE FAILURES, OR %7d STEPS",mxfail,mxstep);
6841 Printf(
" MAXIMUM STEP SIZE IS %9.3f ERROR BARS.",alpha);
6843 fCstatu =
"INITIAL ";
6844 if (fISW[4] >= 2) mnprin(2, fAmin);
6845 fCstatu =
"UNCHANGED ";
6853 for (ipar = 1; ipar <= fNpar; ++ipar) {
6854 iext = fNexofi[ipar-1];
6855 fDirin[ipar-1] = alpha*2*fWerr[ipar-1];
6856 if (fNvarl[iext-1] > 1) {
6858 mndxdi(fX[ipar-1], ipar-1, dxdi);
6859 if (dxdi == 0) dxdi = 1;
6860 fDirin[ipar-1] = alpha*2*fWerr[ipar-1] / dxdi;
6861 if (TMath::Abs(fDirin[ipar-1]) > 6.2831859999999997) {
6862 fDirin[ipar-1] = 6.2831859999999997;
6865 fSEEKxmid[ipar-1] = fX[ipar-1];
6866 fSEEKxbest[ipar-1] = fX[ipar-1];
6869 for (istep = 1; istep <= mxstep; ++istep) {
6870 if (ifail >= mxfail)
break;
6871 for (ipar = 1; ipar <= fNpar; ++ipar) {
6872 mnrn15(rnum1, iseed);
6873 mnrn15(rnum2, iseed);
6874 fX[ipar-1] = fSEEKxmid[ipar-1] + (rnum1 + rnum2 - 1)*.5*fDirin[ipar-1];
6877 Eval(nparx, fGin, ftry, fU, 4); ++fNfcn;
6880 fCstatu =
"IMPROVEMNT";
6882 for (ib = 1; ib <= fNpar; ++ib) { fSEEKxbest[ib-1] = fX[ib-1]; }
6884 if (fISW[4] >= 2) mnprin(2, fAmin);
6890 bar = (fAmin - ftry) / fUp;
6891 mnrn15(rnum, iseed);
6892 if (bar < TMath::Log(rnum))
continue;
6896 for (j = 1; j <= fNpar; ++j) { fSEEKxmid[j-1] = fX[j-1]; }
6901 Printf(
" MNSEEK: %5d SUCCESSIVE UNSUCCESSFUL TRIALS.",ifail);
6903 for (ib = 1; ib <= fNpar; ++ib) { fX[ib-1] = fSEEKxbest[ib-1]; }
6905 if (fISW[4] >= 1) mnprin(2, fAmin);
6906 if (fISW[4] == 0) mnprin(0, fAmin);
6920 void TMinuit::mnset()
6924 static const char *
const cname[30] = {
6956 static constexpr Int_t nname = 25;
6957 static constexpr Int_t nntot =
sizeof(cname)/
sizeof(
char*);
6958 static const TString cprlev[5] = {
6959 "-1: NO OUTPUT EXCEPT FROM SHOW ",
6960 " 0: REDUCED OUTPUT ",
6961 " 1: NORMAL OUTPUT ",
6962 " 2: EXTRA OUTPUT FOR PROBLEM CASES",
6963 " 3: MAXIMUM OUTPUT "};
6965 static const TString cstrat[3] = {
6966 " 0: MINIMIZE THE NUMBER OF CALLS TO FUNCTION",
6967 " 1: TRY TO BALANCE SPEED AGAINST RELIABILITY",
6968 " 2: MAKE SURE MINIMUM TRUE, ERRORS CORRECT "};
6970 static const TString cdbopt[7] = {
6971 "REPORT ALL EXCEPTIONAL CONDITIONS ",
6972 "MNLINE: LINE SEARCH MINIMIZATION ",
6973 "MNDERI: FIRST DERIVATIVE CALCULATIONS ",
6974 "MNHESS: SECOND DERIVATIVE CALCULATIONS ",
6975 "MNMIGR: COVARIANCE MATRIX UPDATES ",
6976 "MNHES1: FIRST DERIVATIVE UNCERTAINTIES ",
6977 "MNCONT: MNCONTOUR PLOT (MNCROS SEARCH) "};
6984 Int_t iset, iprm, i, jseed, kname, iseed, iunit, id, ii, kk;
6985 Int_t ikseed, idbopt, igrain=0, iswsav, isw2;
6986 TString cfname, cmode, ckind, cwarn, copt, ctemp, ctemp2;
6987 Bool_t lname=kFALSE;
6989 for (i = 1; i <= nntot; ++i) {
6992 ctemp2 = fCword(4,6);
6993 if (strstr(ctemp2.Data(),ckind.Data()))
goto L5;
7000 ctemp2 = fCword(0,3);
7001 if ( ctemp2.Contains(
"HEL"))
goto L2000;
7002 if ( ctemp2.Contains(
"SHO"))
goto L1000;
7003 if (!ctemp2.Contains(
"SET"))
goto L1900;
7007 if (kname <= 0)
goto L1900;
7009 switch ((
int)kname) {
7027 case 18:
goto L3000;
7029 case 20:
goto L3000;
7034 case 25:
goto L3000;
7035 case 26:
goto L1900;
7044 iprm = Int_t(fWord7[0]);
7045 if (iprm > fNu)
goto L25;
7046 if (iprm <= 0)
goto L25;
7047 if (fNvarl[iprm-1] < 0)
goto L25;
7048 fU[iprm-1] = fWord7[1];
7053 fISW[1] = TMath::Min(isw2,1);
7054 fCfrom =
"SET PARM";
7056 fCstatu =
"NEW VALUES";
7059 Printf(
" UNDEFINED PARAMETER NUMBER. IGNORED.");
7071 fISW[4] = Int_t(fWord7[0]);
7083 if (fWord7[0] == fUp)
return;
7084 if (fWord7[0] <= 0) {
7085 if (fUp == fUpdflt)
return;
7090 for (i = 1; i <= fNpar; ++i) {
7103 fNpagwd = Int_t(fWord7[0]);
7104 fNpagwd = TMath::Max(fNpagwd,50);
7108 fNpagln = Int_t(fWord7[0]);
7118 mnwarn(
"W",
"SHO",
"SHO");
7122 jseed = Int_t(fWord7[0]);
7126 Printf(
" MINUIT RANDOM NUMBER SEED SET TO %d",jseed);
7135 fIstrat = Int_t(fWord7[0]);
7136 fIstrat = TMath::Max(fIstrat,0);
7137 fIstrat = TMath::Min(fIstrat,2);
7138 if (fISW[4] > 0)
goto L1172;
7142 fNewpag = Int_t(fWord7[0]);
7146 if (fWord7[0] > 0 && fWord7[0] < .1) {
7147 fEpsmac = fWord7[0];
7149 fEpsma2 = TMath::Sqrt(fEpsmac);
7153 iunit = Int_t(fWord7[0]);
7156 if (fISW[4] >= 0)
goto L1220;
7161 if (fISW[4] >= 0)
goto L1100;
7166 if (fISW[4] >= 0)
goto L1100;
7176 idbopt = Int_t(fWord7[0]);
7177 if (idbopt > 6)
goto L288;
7179 fIdbg[idbopt] = iset;
7180 if (iset == 1) fIdbg[0] = 1;
7183 for (
id = 0;
id <= 6; ++id) { fIdbg[id] = iset; }
7185 fLrepor = fIdbg[0] >= 1;
7186 mnwarn(
"D",
"SHO",
"SHO");
7189 Printf(
" UNKNOWN DEBUG OPTION %d REQUESTED. IGNORED",idbopt);
7200 if (kname <= 0)
goto L1900;
7202 switch ((
int)kname) {
7212 case 10:
goto L1100;
7213 case 11:
goto L1110;
7214 case 12:
goto L1120;
7215 case 13:
goto L1130;
7216 case 14:
goto L1130;
7217 case 15:
goto L1150;
7218 case 16:
goto L1160;
7219 case 17:
goto L1170;
7220 case 18:
goto L1180;
7221 case 19:
goto L1190;
7222 case 20:
goto L1200;
7223 case 21:
goto L1210;
7224 case 22:
goto L1220;
7225 case 23:
goto L1100;
7226 case 24:
goto L1100;
7227 case 25:
goto L1250;
7228 case 26:
goto L1900;
7229 case 27:
goto L1270;
7230 case 28:
goto L1270;
7231 case 29:
goto L1290;
7232 case 30:
goto L1300;
7237 if (fAmin == fUndefi) mnamin();
7242 if (fAmin == fUndefi) mnamin();
7247 if (fAmin == fUndefi) mnamin();
7260 if (fISW[4] < -1) fISW[4] = -1;
7261 if (fISW[4] > 3) fISW[4] = 3;
7262 Printf(
" ALLOWED PRINT LEVELS ARE:");
7263 Printf(
" %s",cprlev[0].Data());
7264 Printf(
" %s",cprlev[1].Data());
7265 Printf(
" %s",cprlev[2].Data());
7266 Printf(
" %s",cprlev[3].Data());
7267 Printf(
" %s",cprlev[4].Data());
7268 Printf(
" CURRENT PRINTOUT LEVEL IS %s",cprlev[fISW[4]+1].Data());
7273 Printf(
" NOGRAD IS SET. DERIVATIVES NOT COMPUTED IN FCN.");
7275 Printf(
" GRAD IS SET. USER COMPUTES DERIVATIVES IN FCN.");
7280 Printf(
" ERRORS CORRESPOND TO FUNCTION CHANGE OF %g",fUp);
7304 cmode =
"BATCH MODE ";
7305 if (fISW[5] == 1) cmode =
"INTERACTIVE MODE";
7306 if (! lname) cfname =
"unknown";
7307 Printf(
" INPUT NOW BEING READ IN %s FROM UNIT NO. %d FILENAME: %s"
7308 ,(
const char*)cmode,fIsysrd,(
const char*)cfname);
7312 Printf(
" PAGE WIDTH IS SET TO %d COLUMNS",fNpagwd);
7316 Printf(
" PAGE LENGTH IS SET TO %d LINES",fNpagln);
7320 cwarn =
"SUPPRESSED";
7321 if (fLwarn) cwarn =
"REPORTED ";
7322 Printf(
"%s",(
const char*)cwarn);
7323 if (! fLwarn) mnwarn(
"W",
"SHO",
"SHO");
7328 mnrn15(val, igrain);
7330 Printf(
" MINUIT RNDM SEED IS CURRENTLY=%d",ikseed);
7337 Printf(
" TITLE OF CURRENT TASK IS:%s",(
const char*)fCtitl);
7341 Printf(
" ALLOWED STRATEGIES ARE:");
7342 Printf(
" %s",cstrat[0].Data());
7343 Printf(
" %s",cstrat[1].Data());
7344 Printf(
" %s",cstrat[2].Data());
7346 Printf(
" NOW USING STRATEGY %s",(
const char*)cstrat[fIstrat]);
7353 Printf(
"%s",(
const char*)fCovmes[0]);
7361 Printf(
" PAGE THROW CARRIAGE CONTROL = %d",fNewpag);
7363 Printf(
" NO PAGE THROWS IN MINUIT OUTPUT");
7368 for (ii = 1; ii <= fNpar; ++ii) {
7369 if (fErp[ii-1] > 0 || fErn[ii-1] < 0)
goto L1204;
7371 Printf(
" THERE ARE NO MINOS ERRORS CURRENTLY VALID.");
7378 Printf(
" FLOATING-POINT NUMBERS ASSUMED ACCURATE TO %g",fEpsmac);
7382 Printf(
" MINUIT PRIMARY OUTPUT TO UNIT %d",fIsyswr);
7386 Printf(
" THIS IS MINUIT VERSION:%s",(
const char*)fCvrsn);
7390 for (
id = 0;
id <= 6; ++id) {
7392 if (fIdbg[
id] >= 1) copt =
"ON ";
7393 Printf(
" DEBUG OPTION %3d IS %3s :%s"
7394 ,
id,(
const char*)copt,(
const char*)cdbopt[
id]);
7396 if (! fLrepor) mnwarn(
"D",
"SHO",
"SHO");
7409 Printf(
" THE COMMAND:%10s IS UNKNOWN.",(
const char*)fCword);
7415 ctemp2 = fCword(3,7);
7416 if (strcmp(ctemp2.Data(),
"SHO")) ckind =
"SHOW";
7418 Printf(
" THE FORMAT OF THE %4s COMMAND IS:",(
const char*)ckind);
7419 Printf(
" %s xxx [numerical arguments if any]",(
const char*)ckind);
7420 Printf(
" WHERE xxx MAY BE ONE OF THE FOLLOWING:");
7421 for (kk = 1; kk <= nname; ++kk) {
7422 Printf(
" %s",cname[kk-1]);
7428 Printf(
" ABOVE COMMAND IS ILLEGAL. IGNORED");
7438 void TMinuit::mnsimp()
7442 static constexpr Double_t alpha = 1;
7443 static constexpr Double_t beta = .5;
7444 static constexpr Double_t gamma = 2;
7445 static constexpr Double_t rhomin = 4;
7446 static constexpr Double_t rhomax = 8;
7449 Double_t dmin_, dxdi, yrho, f, ynpp1, aming, ypbar;
7450 Double_t bestx, ystar, y1, y2, ystst, pb, wg;
7451 Double_t absmin, rho, sig2, rho1, rho2;
7452 Int_t npfn, i, j, k, jhold, ncycl, nparx;
7453 Int_t nparp1, kg, jh, nf, jl, ns;
7455 if (fNpar <= 0)
return;
7456 if (fAmin == fUndefi) mnamin();
7457 fCfrom =
"SIMPLEX ";
7459 fCstatu =
"UNCHANGED ";
7464 rho2 = rho1 + alpha*gamma;
7465 wg = 1 / Double_t(fNpar);
7467 Printf(
" START SIMPLEX MINIMIZATION. CONVERGENCE WHEN EDM .LT. %g",fEpsi);
7469 for (i = 1; i <= fNpar; ++i) {
7470 fDirin[i-1] = fWerr[i-1];
7471 mndxdi(fX[i-1], i-1, dxdi);
7472 if (dxdi != 0) fDirin[i-1] = fWerr[i-1] / dxdi;
7473 dmin_ = fEpsma2*TMath::Abs(fX[i-1]);
7474 if (fDirin[i-1] < dmin_) fDirin[i-1] = dmin_;
7480 fSIMPy[nparp1-1] = fAmin;
7482 for (i = 1; i <= fNpar; ++i) {
7484 fPbar[i-1] = fX[i-1];
7490 fX[i-1] = bestx + fDirin[i-1];
7492 Eval(nparx, fGin, f, fU, 4); ++fNfcn;
7493 if (f <= aming)
goto L6;
7495 if (kg == 1)
goto L8;
7499 if (nf < 3)
goto L4;
7506 fCstatu =
"PROGRESS ";
7509 if (ns < 6)
goto L4;
7512 fSIMPy[i-1] = aming;
7513 if (aming < absmin) jl = i;
7514 if (aming < absmin) absmin = aming;
7516 for (k = 1; k <= fNpar; ++k) { fP[k + i*fMaxpar - fMaxpar-1] = fX[k-1]; }
7519 fAmin = fSIMPy[jl-1];
7520 mnrazz(ynpp1, fPbar, fSIMPy, jh, jl);
7521 for (i = 1; i <= fNpar; ++i) { fX[i-1] = fP[i + jl*fMaxpar - fMaxpar-1]; }
7523 fCstatu =
"PROGRESS ";
7524 if (fISW[4] >= 1) mnprin(5, fAmin);
7530 if (sig2 < fEpsi && fEDM < fEpsi)
goto L76;
7532 if (fNfcn - npfn > fNfcnmx)
goto L78;
7534 for (i = 1; i <= fNpar; ++i) {
7536 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7537 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7538 fPstar[i-1] = (alpha + 1)*fPbar[i-1] - alpha*fP[i + jh*fMaxpar - fMaxpar-1];
7541 Eval(nparx, fGin, ystar, fU, 4); ++fNfcn;
7542 if (ystar >= fAmin)
goto L70;
7544 for (i = 1; i <= fNpar; ++i) {
7545 fPstst[i-1] = gamma*fPstar[i-1] + (1 - gamma)*fPbar[i-1];
7548 Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7550 y1 = (ystar - fSIMPy[jh-1])*rho2;
7551 y2 = (ystst - fSIMPy[jh-1])*rho1;
7552 rho = (rho2*y1 - rho1*y2)*.5 / (y1 - y2);
7553 if (rho < rhomin)
goto L66;
7554 if (rho > rhomax) rho = rhomax;
7555 for (i = 1; i <= fNpar; ++i) {
7556 fPrho[i-1] = rho*fPbar[i-1] + (1 - rho)*fP[i + jh*fMaxpar - fMaxpar-1];
7559 Eval(nparx, fGin, yrho, fU, 4); ++fNfcn;
7560 if (yrho < fSIMPy[jl-1] && yrho < ystst)
goto L65;
7561 if (ystst < fSIMPy[jl-1])
goto L67;
7562 if (yrho > fSIMPy[jl-1])
goto L66;
7565 mnrazz(yrho, fPrho, fSIMPy, jh, jl);
7568 if (ystst < fSIMPy[jl-1])
goto L67;
7569 mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7572 mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7575 if (fISW[4] < 2)
goto L50;
7576 if (fISW[4] >= 3 || ncycl % 10 == 0) {
7582 if (ystar >= fSIMPy[jh-1])
goto L73;
7584 mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7585 if (jhold != jh)
goto L50;
7588 for (i = 1; i <= fNpar; ++i) {
7589 fPstst[i-1] = beta*fP[i + jh*fMaxpar - fMaxpar-1] + (1 - beta)*fPbar[i-1];
7592 Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7593 if (ystst > fSIMPy[jh-1])
goto L1;
7595 if (ystst < fAmin)
goto L67;
7596 mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7601 Printf(
" SIMPLEX MINIMIZATION HAS CONVERGED.");
7607 Printf(
" SIMPLEX TERMINATES WITHOUT CONVERGENCE.");
7609 fCstatu =
"CALL LIMIT";
7613 for (i = 1; i <= fNpar; ++i) {
7615 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7616 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7619 Eval(nparx, fGin, ypbar, fU, 4); ++fNfcn;
7620 if (ypbar < fAmin) mnrazz(ypbar, fPbar, fSIMPy, jh, jl);
7622 if (fNfcnmx + npfn - fNfcn < fNpar*3)
goto L90;
7623 if (fEDM > fEpsi*2)
goto L1;
7625 if (fISW[4] >= 0) mnprin(5, fAmin);
7645 void TMinuit::mnstat(Double_t &fmin, Double_t &fedm, Double_t &errdef, Int_t &npari, Int_t &nparx, Int_t &istat)
7653 if (fEDM == fBigedm) fedm = fUp;
7654 if (fAmin == fUndefi) {
7668 void TMinuit::mntiny(
volatile Double_t epsp1, Double_t &epsbak)
7677 Bool_t TMinuit::mnunpt(TString &cfname)
7681 static const TString cpt =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./;:[]$%*_!@#&+()";
7684 l = strlen((
const char*)cfname);
7685 for (i = 1; i <= l; ++i) {
7686 for (ic = 1; ic <= 80; ++ic) {
7687 if (cfname[i-1] == cpt[ic-1])
goto L100;
7703 void TMinuit::mnvert(Double_t *a, Int_t l, Int_t, Int_t n, Int_t &ifail)
7710 Int_t i, j, k, kp1, km1;
7718 if (n < 1)
goto L100;
7719 if (n > fMaxint)
goto L100;
7721 for (i = 1; i <= n; ++i) {
7723 if (si <= 0)
goto L100;
7724 fVERTs[i-1] = 1 / TMath::Sqrt(si);
7726 for (i = 1; i <= n; ++i) {
7727 for (j = 1; j <= n; ++j) {
7728 a[i + j*l] = a[i + j*l]*fVERTs[i-1]*fVERTs[j-1];
7732 for (i = 1; i <= n; ++i) {
7735 if (a[k + k*l] != 0) fVERTq[k-1] = 1 / a[k + k*l];
7741 if (km1 < 0)
goto L100;
7742 else if (km1 == 0)
goto L50;
7745 for (j = 1; j <= km1; ++j) {
7746 fVERTpp[j-1] = a[j + k*l];
7747 fVERTq[j-1] = a[j + k*l]*fVERTq[k-1];
7751 if (k - n < 0)
goto L51;
7752 else if (k - n == 0)
goto L60;
7755 for (j = kp1; j <= n; ++j) {
7756 fVERTpp[j-1] = a[k + j*l];
7757 fVERTq[j-1] = -a[k + j*l]*fVERTq[k-1];
7762 for (j = 1; j <= n; ++j) {
7763 for (k = j; k <= n; ++k) { a[j + k*l] += fVERTpp[j-1]*fVERTq[k-1]; }
7767 for (j = 1; j <= n; ++j) {
7768 for (k = 1; k <= j; ++k) {
7769 a[k + j*l] = a[k + j*l]*fVERTs[k-1]*fVERTs[j-1];
7770 a[j + k*l] = a[k + j*l];
7791 void TMinuit::mnwarn(
const char *copt1,
const char *corg1,
const char *cmes1)
7793 TString copt = copt1;
7794 TString corg = corg1;
7795 TString cmes = cmes1;
7797 const Int_t kMAXMES = 10;
7798 Int_t ityp, i, ic, nm;
7799 TString englsh, ctyp;
7801 if (corg(0,3) !=
"SHO" || cmes(0,3) !=
"SHO") {
7807 Printf(
" MINUIT WARNING IN %s",(
const char*)corg);
7808 Printf(
" ============== %s",(
const char*)cmes);
7814 Printf(
" MINUIT DEBUG FOR %s",(
const char*)corg);
7815 Printf(
" =============== %s ",(
const char*)cmes);
7820 if (fNwrmes[ityp-1] == 0) fIcirc[ityp-1] = 0;
7823 if (fIcirc[ityp-1] > 10) fIcirc[ityp-1] = 1;
7824 ic = fIcirc[ityp-1];
7827 fNfcwar[ic] = fNfcn;
7839 if (fNwrmes[ityp-1] > 0) {
7840 englsh =
" WAS SUPPRESSED. ";
7841 if (fNwrmes[ityp-1] > 1) englsh =
"S WERE SUPPRESSED.";
7842 Printf(
" %5d MINUIT %s MESSAGE%s",fNwrmes[ityp-1]
7843 ,(
const char*)ctyp,(
const char*)englsh);
7844 nm = fNwrmes[ityp-1];
7847 Printf(
" ONLY THE MOST RECENT 10 WILL BE LISTED BELOW.");
7849 ic = fIcirc[ityp-1];
7851 Printf(
" CALLS ORIGIN MESSAGE");
7852 for (i = 1; i <= nm; ++i) {
7854 if (ic > kMAXMES) ic = 1;
7855 Printf(
" %6d %s %s", fNfcwar[ic],fOrigin[ic].Data(),fWarmes[ic].Data());
7857 fNwrmes[ityp-1] = 0;
7868 void TMinuit::mnwerr()
7870 Double_t denom, ba, al, dx, du1, du2;
7871 Int_t ndex, ierr, i, j, k, l, ndiag, k1, iin;
7875 for (l = 1; l <= fNpar; ++l) {
7876 ndex = l*(l + 1) / 2;
7877 dx = TMath::Sqrt(TMath::Abs(fVhmat[ndex-1]*fUp));
7879 if (fNvarl[i-1] > 1) {
7881 ba = fBlim[i-1] - al;
7882 du1 = al + 0.5*(TMath::Sin(fX[l-1] + dx) + 1)*ba - fU[i-1];
7883 du2 = al + 0.5*(TMath::Sin(fX[l-1] - dx) + 1)*ba - fU[i-1];
7884 if (dx > 1) du1 = ba;
7885 dx = 0.5*(TMath::Abs(du1) + TMath::Abs(du2));
7892 for (i = 1; i <= fNpar; ++i) {
7895 for (j = 1; j <= i; ++j) {
7897 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[k-1];
7898 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
7901 mnvert(fP, fMaxint, fMaxint, fNpar, ierr);
7903 for (iin = 1; iin <= fNpar; ++iin) {
7904 ndiag = iin*(iin + 1) / 2;
7905 denom = fP[iin + iin*fMaxpar - fMaxpar-1]*fVhmat[ndiag-1];
7906 if (denom <= 1 && denom >= 0) fGlobcc[iin-1] = 0;
7907 else fGlobcc[iin-1] = TMath::Sqrt(1 - 1 / denom);