00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include <cstdlib>
00104
00105 #include <cstdio>
00106
00107 #include <cstring>
00108
00109 #include <cstdarg>
00110
00111 #include <cmath>
00112
00113
00114
00115 #include "CalRecon/Midnight.h"
00116
00117
00118
00119 #define TMath_Min(a,b) ((a)<(b)?a:b)
00120
00121 #define TMath_Max(a,b) ((a)>(b)?a:b)
00122
00123 #define TMath_Log(a) log(a)
00124
00125 #define TMath_Log10(a) log10(a)
00126
00127 #define TMath_Sqrt(a) sqrt(a)
00128
00129 #define TMath_Power(a,b) pow(a,b)
00130
00131 #define TMath_Abs(a) fabs(a)
00132
00133 #define TMath_Sin(a) sin(a)
00134
00135 #define TMath_Cos(a) cos(a)
00136
00137 #define TMath_ATan(a) atan(a)
00138
00139 #define TMath_ASin(a) asin(a)
00140
00141
00142
00143 static char sBuffer[1024];
00144
00145 static char* Form(char*,...);
00146
00147 static void Printf(const char*,...);
00148
00149
00150
00151 const MInt kMAXDIM = 50;
00152
00153 const MBool kTRUE = 1;
00154
00155 const MBool kFALSE = 0;
00156
00157
00158
00159
00160
00161 Midnight::Midnight()
00162
00163 {
00164
00165
00166
00167
00168
00169
00170
00171 fEmpty = 1;
00172
00173 fPrintf = Printf;
00174
00175
00176
00177 }
00178
00179
00180
00181
00182
00183 Midnight::Midnight(MInt maxpar)
00184
00185 {
00186
00187
00188
00189
00190
00191
00192
00193 BuildArrays(maxpar);
00194
00195
00196
00197 fEmpty = 0;
00198
00199 fPrintf = Printf;
00200
00201
00202
00203 mninit(5,6,7);
00204
00205 }
00206
00207
00208
00209
00210
00211 Midnight::Midnight(const Midnight &)
00212
00213 {
00214
00215
00216
00217
00218
00219
00220
00221 fPrintf("Midnight can not copy construct Midnight");
00222
00223 }
00224
00225
00226
00227
00228
00229 Midnight::~Midnight()
00230
00231 {
00232
00233
00234
00235
00236
00237
00238
00239 DeleteArrays();
00240
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 int Midnight::GetParameter( int parNo, double ¤tValue, double ¤tError )
00252
00253 {
00254
00255
00256
00257 int err;
00258
00259 MString name;
00260
00261 double bnd1, bnd2;
00262
00263
00264
00265 mnpout( parNo, name, currentValue, currentError, bnd1, bnd2, err );
00266
00267
00268
00269 return err;
00270
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 void Midnight::BuildArrays(MInt maxpar)
00280
00281 {
00282
00283
00284
00285
00286
00287
00288
00289 MInt mni = 25;
00290
00291 if (maxpar > 10 && maxpar < 200) mni = maxpar;
00292
00293 fMaxpar = mni;
00294
00295 MInt mnihl = mni*(mni+1)/2;
00296
00297 MInt maxcpt = 101;
00298
00299 MInt mne = 2*mni;
00300
00301 fCpnam = new MString[mne];
00302
00303 fU = new MDouble[mne];
00304
00305 fAlim = new MDouble[mne];
00306
00307 fBlim = new MDouble[mne];
00308
00309 fErp = new MDouble[mni];
00310
00311 fErn = new MDouble[mni];
00312
00313 fWerr = new MDouble[mni];
00314
00315 fGlobcc = new MDouble[mni];
00316
00317 fNvarl = new MInt[mne];
00318
00319 fNiofex = new MInt[mne];
00320
00321 fNexofi = new MInt[mne];
00322
00323 fX = new MDouble[mni];
00324
00325 fXt = new MDouble[mni];
00326
00327 fDirin = new MDouble[mni];
00328
00329 fXs = new MDouble[mni];
00330
00331 fXts = new MDouble[mni];
00332
00333 fDirins = new MDouble[mni];
00334
00335 fGrd = new MDouble[mni];
00336
00337 fG2 = new MDouble[mni];
00338
00339 fGstep = new MDouble[mni];
00340
00341 fGin = new MDouble[mni];
00342
00343 fDgrd = new MDouble[mni];
00344
00345 fGrds = new MDouble[mni];
00346
00347 fG2s = new MDouble[mni];
00348
00349 fGsteps = new MDouble[mni];
00350
00351 fIpfix = new MInt[mni];
00352
00353 fVhmat = new MDouble[mnihl];
00354
00355 fVthmat = new MDouble[mnihl];
00356
00357 fP = new MDouble[mni*(mni+1)];
00358
00359 fPstar = new MDouble[mni];
00360
00361 fPstst = new MDouble[mni];
00362
00363 fPbar = new MDouble[mni];
00364
00365 fPrho = new MDouble[mni];
00366
00367 fWord7 = new MDouble[30];
00368
00369 fXpt = new MDouble[maxcpt];
00370
00371 fYpt = new MDouble[maxcpt];
00372
00373 fChpt = new MString[maxcpt];
00374
00375 fOrigin = new MString[100];
00376
00377 fWarmes = new MString[100];
00378
00379
00380
00381 for (int i = 0; i < fMaxpar; i++) {
00382
00383 fErp[i] = 0;
00384
00385 fErn[i] = 0;
00386
00387 }
00388
00389 }
00390
00391
00392
00393
00394
00395 void Midnight::DeleteArrays()
00396
00397 {
00398
00399
00400
00401
00402
00403 if (fEmpty) return;
00404
00405 delete [] fCpnam;
00406
00407 delete [] fU;
00408
00409 delete [] fAlim;
00410
00411 delete [] fBlim;
00412
00413 delete [] fErp;
00414
00415 delete [] fErn;
00416
00417 delete [] fWerr;
00418
00419 delete [] fGlobcc;
00420
00421 delete [] fNvarl;
00422
00423 delete [] fNiofex;
00424
00425 delete [] fNexofi;
00426
00427 delete [] fX;
00428
00429 delete [] fXt;
00430
00431 delete [] fDirin;
00432
00433 delete [] fXs;
00434
00435 delete [] fXts;
00436
00437 delete [] fDirins;
00438
00439 delete [] fGrd;
00440
00441 delete [] fG2;
00442
00443 delete [] fGstep;
00444
00445 delete [] fGin;
00446
00447 delete [] fDgrd;
00448
00449 delete [] fGrds;
00450
00451 delete [] fG2s;
00452
00453 delete [] fGsteps;
00454
00455 delete [] fIpfix;
00456
00457 delete [] fVhmat;
00458
00459 delete [] fVthmat;
00460
00461 delete [] fP;
00462
00463 delete [] fPstar;
00464
00465 delete [] fPstst;
00466
00467 delete [] fPbar;
00468
00469 delete [] fPrho;
00470
00471 delete [] fWord7;
00472
00473 delete [] fXpt;
00474
00475 delete [] fYpt;
00476
00477 delete [] fChpt;
00478
00479 delete [] fOrigin;
00480
00481 delete [] fWarmes;
00482
00483 fEmpty = 1;
00484
00485 }
00486
00487
00488
00489
00490
00491 void Midnight::SetFCN(MFunction fcn)
00492
00493 {
00494
00495
00496
00497
00498
00499
00500
00501 fFCN = fcn;
00502
00503 }
00504
00505
00506
00507 void Midnight::SetPrintf(MPrintf aPrintf)
00508
00509 {
00510
00511
00512
00513
00514
00515
00516
00517 fPrintf = aPrintf;
00518
00519 }
00520
00521
00522
00523
00524
00525 void Midnight::mnamin()
00526
00527 {
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 static MDouble fnew;
00546
00547 static MInt nparx;
00548
00549
00550
00551 nparx = fNpar;
00552
00553 if (fISW[4] >= 1) {
00554
00555 fPrintf(" FIRST CALL TO USER FUNCTION AT NEW START POINT, WITH IFLAG=4.");
00556
00557 }
00558
00559 mnexin(fX);
00560
00561 (*fFCN)(nparx, fGin, fnew, fU, 4); ++fNfcn;
00562
00563 fAmin = fnew;
00564
00565 fEDM = fBigedm;
00566
00567 }
00568
00569
00570
00571
00572
00573 void Midnight::mnbins(MDouble a1, MDouble a2, MInt naa, MDouble &bl, MDouble &bh, MInt &nb, MDouble &bwid)
00574
00575 {
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 MDouble awid,ah, al, sigfig, sigrnd, alb;
00598
00599 static MInt kwid, lwid, na, log_;
00600
00601
00602
00603 al = TMath_Min(a1,a2);
00604
00605 ah = TMath_Max(a1,a2);
00606
00607 if (al == ah) ah = al + 1;
00608
00609
00610
00611
00612
00613 if (naa == -1) goto L150;
00614
00615 L10:
00616
00617 na = naa - 1;
00618
00619 if (na < 1) na = 1;
00620
00621
00622
00623
00624
00625 L20:
00626
00627 awid = (ah-al) / MDouble(na);
00628
00629 log_ = MInt(TMath_Log10(awid));
00630
00631 if (awid <= 1) --log_;
00632
00633 sigfig = awid*TMath_Power(10., -log_);
00634
00635
00636
00637 if (sigfig > 2) goto L40;
00638
00639 sigrnd = 2;
00640
00641 goto L100;
00642
00643 L40:
00644
00645 if (sigfig > 2.5) goto L50;
00646
00647 sigrnd = 2.5;
00648
00649 goto L100;
00650
00651 L50:
00652
00653 if (sigfig > 5) goto L60;
00654
00655 sigrnd = 5;
00656
00657 goto L100;
00658
00659 L60:
00660
00661 sigrnd = 1;
00662
00663 ++log_;
00664
00665 L100:
00666
00667 bwid = sigrnd*TMath_Power(10., log_);
00668
00669 goto L200;
00670
00671
00672
00673 L150:
00674
00675 if (bwid <= 0) goto L10;
00676
00677 L200:
00678
00679 alb = al / bwid;
00680
00681 lwid = MInt(alb);
00682
00683 if (alb < 0) --lwid;
00684
00685 bl = bwid*MDouble(lwid);
00686
00687 alb = ah / bwid + 1;
00688
00689 kwid = MInt(alb);
00690
00691 if (alb < 0) --kwid;
00692
00693 bh = bwid*MDouble(kwid);
00694
00695 nb = kwid - lwid;
00696
00697 if (naa > 5) goto L240;
00698
00699 if (naa == -1) return;
00700
00701
00702
00703 if (naa > 1 || nb == 1) return;
00704
00705 bwid *= 2;
00706
00707 nb = 1;
00708
00709 return;
00710
00711 L240:
00712
00713 if (nb << 1 != naa) return;
00714
00715 ++na;
00716
00717 goto L20;
00718
00719 }
00720
00721
00722
00723
00724
00725 void Midnight::mncalf(MDouble *pvec, MDouble &ycalf)
00726
00727 {
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 static MInt ndex, i, j, m, n, nparx;
00746
00747 static MDouble denom, f;
00748
00749
00750
00751 nparx = fNpar;
00752
00753 mninex(&pvec[0]);
00754
00755 (*fFCN)(nparx, fGin, f, fU, 4); ++fNfcn;
00756
00757 for (i = 1; i <= fNpar; ++i) {
00758
00759 fGrd[i-1] = 0;
00760
00761 for (j = 1; j <= fNpar; ++j) {
00762
00763 m = TMath_Max(i,j);
00764
00765 n = TMath_Min(i,j);
00766
00767 ndex = m*(m-1) / 2 + n;
00768
00769 fGrd[i-1] += fVthmat[ndex-1]*(fXt[j-1] - pvec[j-1]);
00770
00771 }
00772
00773 }
00774
00775 denom = 0;
00776
00777 for (i = 1; i <= fNpar; ++i) {denom += fGrd[i-1]*(fXt[i-1] - pvec[i-1]); }
00778
00779 if (denom <= 0) {
00780
00781 fDcovar = 1;
00782
00783 fISW[1] = 0;
00784
00785 denom = 1;
00786
00787 }
00788
00789 ycalf = (f - fApsi) / denom;
00790
00791 }
00792
00793
00794
00795
00796
00797 void Midnight::mncler()
00798
00799 {
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 MInt i;
00812
00813
00814
00815 fNpfix = 0;
00816
00817 fNu = 0;
00818
00819 fNpar = 0;
00820
00821 fNfcn = 0;
00822
00823 fNwrmes[0] = 0;
00824
00825 fNwrmes[1] = 0;
00826
00827 for (i = 1; i <= fMaxext; ++i) {
00828
00829 fU[i-1] = 0;
00830
00831 fCpnam[i-1] = fCundef;
00832
00833 fNvarl[i-1] = -1;
00834
00835 fNiofex[i-1] = 0;
00836
00837 }
00838
00839 mnrset(1);
00840
00841 fCfrom = "CLEAR ";
00842
00843 fNfcnfr = fNfcn;
00844
00845 fCstatu = "UNDEFINED ";
00846
00847 fLnolim = kTRUE;
00848
00849 fLphead = kTRUE;
00850
00851 }
00852
00853
00854
00855
00856
00857 void Midnight::mncntr(MInt ke1, MInt ke2, MInt &ierrf)
00858
00859 {
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 static MString clabel = "0123456789ABCDEFGHIJ";
00874
00875
00876
00877
00878
00879 MDouble d__1, d__2;
00880
00881 MDouble fcna[115], fcnb[115], contur[20];
00882
00883 MDouble ylabel, fmn, fmx, xlo, ylo, xup, yup;
00884
00885 MDouble devs, xsav, ysav, bwidx, bwidy, unext, ff, xb4;
00886
00887 static MInt i, ngrid, ixmid, nparx, ix, nx, ny, ki1, ki2, ixzero, iy, ics;
00888
00889 static MString chmid, chln, chzero;
00890
00891
00892
00893 if (ke1 <= 0 || ke2 <= 0) goto L1350;
00894
00895 if (ke1 > fNu || ke2 > fNu) goto L1350;
00896
00897 ki1 = fNiofex[ke1-1];
00898
00899 ki2 = fNiofex[ke2-1];
00900
00901 if (ki1 <= 0 || ki2 <= 0) goto L1350;
00902
00903 if (ki1 == ki2) goto L1350;
00904
00905
00906
00907 if (fISW[1] < 1) {
00908
00909 mnhess();
00910
00911 mnwerr();
00912
00913 }
00914
00915 nparx = fNpar;
00916
00917 xsav = fU[ke1-1];
00918
00919 ysav = fU[ke2-1];
00920
00921 devs = fWord7[2];
00922
00923 if (devs <= 0) devs = 2;
00924
00925 xlo = fU[ke1-1] - devs*fWerr[ki1-1];
00926
00927 xup = fU[ke1-1] + devs*fWerr[ki1-1];
00928
00929 ylo = fU[ke2-1] - devs*fWerr[ki2-1];
00930
00931 yup = fU[ke2-1] + devs*fWerr[ki2-1];
00932
00933 ngrid = MInt(fWord7[3]);
00934
00935 if (ngrid <= 0) {
00936
00937 ngrid = 25;
00938
00939
00940
00941 nx = TMath_Min(fNpagwd - 15,ngrid);
00942
00943
00944
00945 ny = TMath_Min(fNpagln - 7,ngrid);
00946
00947 } else {
00948
00949 nx = ngrid;
00950
00951 ny = ngrid;
00952
00953 }
00954
00955 if (nx < 11) nx = 11;
00956
00957 if (ny < 11) ny = 11;
00958
00959 if (nx >= 115) nx = 114;
00960
00961
00962
00963
00964
00965 if (fNvarl[ke1-1] > 1) {
00966
00967 if (xlo < fAlim[ke1-1]) xlo = fAlim[ke1-1];
00968
00969 if (xup > fBlim[ke1-1]) xup = fBlim[ke1-1];
00970
00971 }
00972
00973 if (fNvarl[ke2-1] > 1) {
00974
00975 if (ylo < fAlim[ke2-1]) ylo = fAlim[ke2-1];
00976
00977 if (yup > fBlim[ke2-1]) yup = fBlim[ke2-1];
00978
00979 }
00980
00981 bwidx = (xup - xlo) / MDouble(nx);
00982
00983 bwidy = (yup - ylo) / MDouble(ny);
00984
00985 ixmid = MInt(((xsav - xlo)*MDouble(nx) / (xup - xlo)) + 1);
00986
00987 if (fAmin == fUndefi) mnamin();
00988
00989
00990
00991 for (i = 1; i <= 20; ++i) { contur[i-1] = fAmin + fUp*(i-1)*(i-1); }
00992
00993 contur[0] += fUp*.01;
00994
00995
00996
00997 fU[ke2-1] = yup;
00998
00999 ixzero = 0;
01000
01001 xb4 = 1;
01002
01003
01004
01005 chmid.resize(nx+1);
01006
01007 chzero.resize(nx+1);
01008
01009 chln.resize(nx+1);
01010
01011 for (ix = 1; ix <= nx + 1; ++ix) {
01012
01013 fU[ke1-1] = xlo + MDouble(ix-1)*bwidx;
01014
01015 (*fFCN)(nparx, fGin, ff, fU, 4);
01016
01017 fcnb[ix-1] = ff;
01018
01019 if (xb4 < 0 && fU[ke1-1] > 0) ixzero = ix - 1;
01020
01021 xb4 = fU[ke1-1];
01022
01023 chmid[ix-1] = '*';
01024
01025 chzero[ix-1] = '-';
01026
01027 }
01028
01029 fPrintf(" Y-AXIS: PARAMETER %3d: %s",ke2,(const char*)fCpnam[ke2-1]);
01030
01031 if (ixzero > 0) {
01032
01033 chzero[ixzero-1] = '+';
01034
01035 chln = " ";
01036
01037 fPrintf(" X=0");
01038
01039 }
01040
01041
01042
01043 for (iy = 1; iy <= ny; ++iy) {
01044
01045 unext = fU[ke2-1] - bwidy;
01046
01047
01048
01049 chln = " ";
01050
01051
01052
01053 chln.resize(nx+1);
01054
01055 chln[ixmid-1] = '*';
01056
01057 if (ixzero != 0) chln[ixzero-1] = ':';
01058
01059 if (fU[ke2-1] > ysav && unext < ysav) chln = chmid;
01060
01061 if (fU[ke2-1] > 0 && unext < 0) chln = chzero;
01062
01063 fU[ke2-1] = unext;
01064
01065 ylabel = fU[ke2-1] + bwidy*.5;
01066
01067
01068
01069 for (ix = 1; ix <= nx + 1; ++ix) {
01070
01071 fcna[ix-1] = fcnb[ix-1];
01072
01073 fU[ke1-1] = xlo + MDouble(ix-1)*bwidx;
01074
01075 (*fFCN)(nparx, fGin, ff, fU, 4);
01076
01077 fcnb[ix-1] = ff;
01078
01079 }
01080
01081
01082
01083 for (ix = 1; ix <= nx; ++ix) {
01084
01085 d__1 = TMath_Max(fcna[ix-1],fcnb[ix-1]),
01086
01087 d__2 = TMath_Max(fcna[ix],fcnb[ix]);
01088
01089 fmx = TMath_Max(d__1,d__2);
01090
01091 d__1 = TMath_Min(fcna[ix-1],fcnb[ix-1]),
01092
01093 d__2 = TMath_Min(fcna[ix],fcnb[ix]);
01094
01095 fmn = TMath_Min(d__1,d__2);
01096
01097 for (ics = 1; ics <= 20; ++ics) {
01098
01099 if (contur[ics-1] > fmn) goto L240;
01100
01101 }
01102
01103 continue;
01104
01105 L240:
01106
01107 if (contur[ics-1] < fmx) chln[ix-1] = clabel[ics-1];
01108
01109 }
01110
01111
01112
01113 fPrintf(" %12.4g %s",ylabel,(const char*)chln);
01114
01115 }
01116
01117
01118
01119 chln = " ";
01120
01121 chln[0] = 'I';
01122
01123 chln[ixmid-1] = 'I';
01124
01125 chln[nx-1] = 'I';
01126
01127 fPrintf(" %s",(const char*)chln);
01128
01129
01130
01131
01132
01133 chln = " ";
01134
01135 if (nx <= 26) {
01136
01137 fPrintf(" %12.4g%s%12.4g",xlo,(const char*)chln,xup);
01138
01139 fPrintf(" %s%12.4g",(const char*)chln,xsav);
01140
01141 } else {
01142
01143 fPrintf(" %12.4g%s%12.4g%s%12.4g",xlo,(const char*)chln,xsav,(const char*)chln,xup);
01144
01145 }
01146
01147 fPrintf(" X-AXIS: PARAMETER%3d: %s ONE COLUMN=%12.4g"
01148
01149 ,ke1,(const char*)fCpnam[ke1-1],bwidx);
01150
01151 fPrintf(" FUNCTION VALUES: F(I)=%12.4g +%12.4g *I**2",fAmin,fUp);
01152
01153
01154
01155 fU[ke1-1] = xsav;
01156
01157 fU[ke2-1] = ysav;
01158
01159 ierrf = 0;
01160
01161 return;
01162
01163 L1350:
01164
01165 fPrintf(" INVALID PARAMETER NUMBER(S) REQUESTED. IGNORED.");
01166
01167 ierrf = 1;
01168
01169 }
01170
01171
01172
01173
01174
01175 void Midnight::mncomd(MString crdbin, MInt &icondn)
01176
01177 {
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 static MString clower = "abcdefghijklmnopqrstuvwxyz";
01224
01225 static MString cupper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
01226
01227
01228
01229
01230
01231 static MDouble plist[30];
01232
01233 static MInt ierr, ipos, i, llist, ic, lenbuf, lnc;
01234
01235 static MBool leader;
01236
01237 static MString comand, crdbuf, ctemp;
01238
01239
01240
01241 lenbuf = strlen((const char*)crdbin);
01242
01243 crdbuf = crdbin;
01244
01245 icondn = 0;
01246
01247
01248
01249 leader = kTRUE;
01250
01251 ipos = 1;
01252
01253 for (i = 1; i <= TMath_Min(20,lenbuf); ++i) {
01254
01255 if (crdbuf[i-1] == '\'') goto L111;
01256
01257 if (crdbuf[i-1] == ' ') {
01258
01259 if (leader) ++ipos;
01260
01261 continue;
01262
01263 }
01264
01265 leader = kFALSE;
01266
01267 for (ic = 1; ic <= 26; ++ic) {
01268
01269 if (crdbuf[i-1] == clower[ic-1]) crdbuf[i-1] = cupper[ic-1];
01270
01271 }
01272
01273 }
01274
01275 L111:
01276
01277
01278
01279 if (ipos > lenbuf) {
01280
01281 fPrintf(" BLANK COMMAND IGNORED.");
01282
01283 icondn = 1;
01284
01285 goto L900;
01286
01287 }
01288
01289
01290
01291
01292
01293 if (crdbuf(ipos-1,3) == "PAR") {
01294
01295 icondn = 5;
01296
01297 fLphead = kTRUE;
01298
01299 goto L900;
01300
01301 }
01302
01303
01304
01305 if (crdbuf(ipos-1,3) == "SET INP") {
01306
01307 icondn = 6;
01308
01309 fLphead = kTRUE;
01310
01311 goto L900;
01312
01313 }
01314
01315
01316
01317 if (crdbuf(ipos-1,7) == "SET TIT") {
01318
01319 icondn = 7;
01320
01321 fLphead = kTRUE;
01322
01323 goto L900;
01324
01325 }
01326
01327
01328
01329 if (crdbuf(ipos-1,7) == "SET COV") {
01330
01331 icondn = 8;
01332
01333 fLphead = kTRUE;
01334
01335 goto L900;
01336
01337 }
01338
01339
01340
01341 ctemp = crdbuf(ipos-1,7);
01342
01343 mncrck(ctemp, 20, comand, lnc, 30, plist, llist, ierr, fIsyswr);
01344
01345 if (ierr > 0) {
01346
01347 fPrintf(" COMMAND CANNOT BE INTERPRETED");
01348
01349 icondn = 2;
01350
01351 goto L900;
01352
01353 }
01354
01355
01356
01357 mnexcm(comand, plist, llist, ierr);
01358
01359 icondn = ierr;
01360
01361 L900:
01362
01363 return;
01364
01365 }
01366
01367
01368
01369
01370
01371 void Midnight::mncont(MInt ke1, MInt ke2, MInt nptu, MDouble *xptu, MDouble *yptu, MInt &ierrf)
01372
01373 {
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405 MInt i__1;
01406
01407
01408
01409
01410
01411 MDouble d__1, d__2;
01412
01413 static MDouble dist, xdir, ydir, aopt, u1min, u2min;
01414
01415 static MDouble gcc[kMAXDIM], w[kMAXDIM], abest, scalx, scaly;
01416
01417 static MDouble a1, a2, val2mi, val2pl, dc, sclfac, bigdis, sigsav;
01418
01419 static MInt nall, iold, line, mpar, ierr, inew, move, next, i, j, nfcol, iercr;
01420
01421 static MInt idist, npcol, kints, i2, i1, lr, nfcnco, ki1, ki2, ki3, ke3;
01422
01423 static MInt nowpts, istrav, nfmxin, isw2, isw4;
01424
01425 static MBool ldebug;
01426
01427
01428
01429
01430
01431 ldebug = fIdbg[6] >= 1;
01432
01433 if (ke1 <= 0 || ke2 <= 0) goto L1350;
01434
01435 if (ke1 > fNu || ke2 > fNu) goto L1350;
01436
01437 ki1 = fNiofex[ke1-1];
01438
01439 ki2 = fNiofex[ke2-1];
01440
01441 if (ki1 <= 0 || ki2 <= 0) goto L1350;
01442
01443 if (ki1 == ki2) goto L1350;
01444
01445 if (nptu < 4) goto L1400;
01446
01447
01448
01449 nfcnco = fNfcn;
01450
01451 fNfcnmx = (nptu + 5)*100*(fNpar + 1);
01452
01453
01454
01455 mncuve();
01456
01457 u1min = fU[ke1-1];
01458
01459 u2min = fU[ke2-1];
01460
01461 ierrf = 0;
01462
01463 fCfrom = "MNContour ";
01464
01465 fNfcnfr = nfcnco;
01466
01467 if (fISW[4] >= 0) {
01468
01469 fPrintf(" START MNCONTOUR CALCULATION OF%4d POINTS ON CONTOUR.",nptu);
01470
01471 if (fNpar > 2) {
01472
01473 if (fNpar == 3) {
01474
01475 ki3 = 6 - ki1 - ki2;
01476
01477 ke3 = fNexofi[ki3-1];
01478
01479 fPrintf(" EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER %3d %s",ke3,(const char*)fCpnam[ke3-1]);
01480
01481 } else {
01482
01483 fPrintf(" EACH POINT IS A MINIMUM WITH RESPECT TO THE OTHER%3d VARIABLE PARAMETERS.",fNpar - 2);
01484
01485 }
01486
01487 }
01488
01489 }
01490
01491
01492
01493
01494
01495
01496
01497 mnmnot(ke1, ke2, val2pl, val2mi);
01498
01499 if (fErn[ki1-1] == fUndefi) {
01500
01501 xptu[0] = fAlim[ke1-1];
01502
01503 mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
01504
01505 } else {
01506
01507 if (fErn[ki1-1] >= 0) goto L1500;
01508
01509 xptu[0] = u1min + fErn[ki1-1];
01510
01511 }
01512
01513 yptu[0] = val2mi;
01514
01515
01516
01517 if (fErp[ki1-1] == fUndefi) {
01518
01519 xptu[2] = fBlim[ke1-1];
01520
01521 mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
01522
01523 } else {
01524
01525 if (fErp[ki1-1] <= 0) goto L1500;
01526
01527 xptu[2] = u1min + fErp[ki1-1];
01528
01529 }
01530
01531 yptu[2] = val2pl;
01532
01533 scalx = 1 / (xptu[2] - xptu[0]);
01534
01535
01536
01537 mnmnot(ke2, ke1, val2pl, val2mi);
01538
01539 if (fErn[ki2-1] == fUndefi) {
01540
01541 yptu[1] = fAlim[ke2-1];
01542
01543 mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
01544
01545 } else {
01546
01547 if (fErn[ki2-1] >= 0) goto L1500;
01548
01549 yptu[1] = u2min + fErn[ki2-1];
01550
01551 }
01552
01553 xptu[1] = val2mi;
01554
01555 if (fErp[ki2-1] == fUndefi) {
01556
01557 yptu[3] = fBlim[ke2-1];
01558
01559 mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
01560
01561 } else {
01562
01563 if (fErp[ki2-1] <= 0) goto L1500;
01564
01565 yptu[3] = u2min + fErp[ki2-1];
01566
01567 }
01568
01569 xptu[3] = val2pl;
01570
01571 scaly = 1 / (yptu[3] - yptu[1]);
01572
01573 nowpts = 4;
01574
01575 next = 5;
01576
01577 if (ldebug) {
01578
01579 fPrintf(" Plot of four points found by MINOS");
01580
01581 fXpt[0] = u1min;
01582
01583 fYpt[0] = u2min;
01584
01585 fChpt[0] = ' ';
01586
01587
01588
01589 nall = TMath_Min(nowpts + 1,101);
01590
01591 for (i = 2; i <= nall; ++i) {
01592
01593 fXpt[i-1] = xptu[i-2];
01594
01595 fYpt[i-1] = yptu[i-2];
01596
01597 }
01598
01599 fChpt[1] = 'A';
01600
01601 fChpt[2] = 'B';
01602
01603 fChpt[3] = 'C';
01604
01605 fChpt[4] = 'D';
01606
01607 mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
01608
01609 }
01610
01611
01612
01613
01614
01615 isw2 = fISW[1];
01616
01617 isw4 = fISW[3];
01618
01619 sigsav = fEDM;
01620
01621 istrav = fIstrat;
01622
01623 dc = fDcovar;
01624
01625 fApsi = fEpsi*.5;
01626
01627 abest = fAmin;
01628
01629 mpar = fNpar;
01630
01631 nfmxin = fNfcnmx;
01632
01633 for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
01634
01635 i__1 = mpar*(mpar + 1) / 2;
01636
01637 for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
01638
01639 for (i = 1; i <= mpar; ++i) {
01640
01641 gcc[i-1] = fGlobcc[i-1];
01642
01643 w[i-1] = fWerr[i-1];
01644
01645 }
01646
01647
01648
01649 kints = fNiofex[ke1-1];
01650
01651 mnfixp(kints-1, ierr);
01652
01653 kints = fNiofex[ke2-1];
01654
01655 mnfixp(kints-1, ierr);
01656
01657
01658
01659 for (inew = next; inew <= nptu; ++inew) {
01660
01661
01662
01663 bigdis = 0;
01664
01665 for (iold = 1; iold <= inew - 1; ++iold) {
01666
01667 i2 = iold + 1;
01668
01669 if (i2 == inew) i2 = 1;
01670
01671 d__1 = scalx*(xptu[iold-1] - xptu[i2-1]);
01672
01673 d__2 = scaly*(yptu[iold-1] - yptu[i2-1]);
01674
01675 dist = d__1*d__1 + d__2*d__2;
01676
01677 if (dist > bigdis) {
01678
01679 bigdis = dist;
01680
01681 idist = iold;
01682
01683 }
01684
01685 }
01686
01687 i1 = idist;
01688
01689 i2 = i1 + 1;
01690
01691 if (i2 == inew) i2 = 1;
01692
01693
01694
01695 a1 = .5;
01696
01697 a2 = .5;
01698
01699 L300:
01700
01701 fXmidcr = a1*xptu[i1-1] + a2*xptu[i2-1];
01702
01703 fYmidcr = a1*yptu[i1-1] + a2*yptu[i2-1];
01704
01705 xdir = yptu[i2-1] - yptu[i1-1];
01706
01707 ydir = xptu[i1-1] - xptu[i2-1];
01708
01709 sclfac = TMath_Max(TMath_Abs(xdir*scalx),TMath_Abs(ydir*scaly));
01710
01711 fXdircr = xdir / sclfac;
01712
01713 fYdircr = ydir / sclfac;
01714
01715 fKe1cr = ke1;
01716
01717 fKe2cr = ke2;
01718
01719
01720
01721 fAmin = abest;
01722
01723 mncros(aopt, iercr);
01724
01725 if (iercr > 1) {
01726
01727
01728
01729 if (a1 > .5) {
01730
01731 if (fISW[4] >= 0) {
01732
01733 fPrintf(" MNCONT CANNOT FIND NEXT POINT ON CONTOUR. ONLY%3d POINTS FOUND.",nowpts);
01734
01735 }
01736
01737 goto L950;
01738
01739 }
01740
01741 mnwarn("W", "MNContour ", "Cannot find midpoint, try closer.");
01742
01743 a1 = .75;
01744
01745 a2 = .25;
01746
01747 goto L300;
01748
01749 }
01750
01751
01752
01753 for (move = nowpts; move >= i1 + 1; --move) {
01754
01755 xptu[move] = xptu[move-1];
01756
01757 yptu[move] = yptu[move-1];
01758
01759 }
01760
01761 ++nowpts;
01762
01763 xptu[i1] = fXmidcr + fXdircr*aopt;
01764
01765 yptu[i1] = fYmidcr + fYdircr*aopt;
01766
01767 }
01768
01769 L950:
01770
01771
01772
01773 ierrf = nowpts;
01774
01775 fCstatu = "SUCCESSFUL";
01776
01777 if (nowpts < nptu) fCstatu = "INCOMPLETE";
01778
01779
01780
01781
01782
01783 if (fISW[4] >= 0) {
01784
01785 fXpt[0] = u1min;
01786
01787 fYpt[0] = u2min;
01788
01789 fChpt[0] = ' ';
01790
01791 nall = TMath_Min(nowpts + 1,101);
01792
01793 for (i = 2; i <= nall; ++i) {
01794
01795 fXpt[i-1] = xptu[i-2];
01796
01797 fYpt[i-1] = yptu[i-2];
01798
01799 fChpt[i-1] = 'X';
01800
01801 }
01802
01803 fPrintf(" Y-AXIS: PARAMETER %3d %s",ke2,(const char*)fCpnam[ke2-1]);
01804
01805
01806
01807 mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
01808
01809
01810
01811 fPrintf(" X-AXIS: PARAMETER %3d %s",ke1,(const char*)fCpnam[ke1-1]);
01812
01813 }
01814
01815
01816
01817 if (fISW[4] >= 1) {
01818
01819 npcol = (nowpts + 1) / 2;
01820
01821 nfcol = nowpts / 2;
01822
01823 fPrintf("%5d POINTS ON CONTOUR. FMIN=%13.5e ERRDEF=%11.3g",nowpts,abest,fUp);
01824
01825 fPrintf(" %s%s%s%s",(const char*)fCpnam[ke1-1],
01826
01827 (const char*)fCpnam[ke2-1],
01828
01829 (const char*)fCpnam[ke1-1],
01830
01831 (const char*)fCpnam[ke2-1]);
01832
01833 for (line = 1; line <= nfcol; ++line) {
01834
01835 lr = line + npcol;
01836
01837 fPrintf(" %5d%13.5e%13.5e %5d%13.5e%13.5e",line,xptu[line-1],yptu[line-1],lr,xptu[lr-1],yptu[lr-1]);
01838
01839 }
01840
01841 if (nfcol < npcol) {
01842
01843 fPrintf(" %5d%13.5e%13.5e",npcol,xptu[npcol-1],yptu[npcol-1]);
01844
01845 }
01846
01847 }
01848
01849
01850
01851 fItaur = 1;
01852
01853 mnfree(1);
01854
01855 mnfree(1);
01856
01857 i__1 = mpar*(mpar + 1) / 2;
01858
01859 for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
01860
01861 for (i = 1; i <= mpar; ++i) {
01862
01863 fGlobcc[i-1] = gcc[i-1];
01864
01865 fWerr[i-1] = w[i-1];
01866
01867 fX[i-1] = fXt[i-1];
01868
01869 }
01870
01871 mninex(fX);
01872
01873 fEDM = sigsav;
01874
01875 fAmin = abest;
01876
01877 fISW[1] = isw2;
01878
01879 fISW[3] = isw4;
01880
01881 fDcovar = dc;
01882
01883 fItaur = 0;
01884
01885 fNfcnmx = nfmxin;
01886
01887 fIstrat = istrav;
01888
01889 fU[ke1-1] = u1min;
01890
01891 fU[ke2-1] = u2min;
01892
01893 goto L2000;
01894
01895
01896
01897 L1350:
01898
01899 fPrintf(" INVALID PARAMETER NUMBERS.");
01900
01901 goto L1450;
01902
01903 L1400:
01904
01905 fPrintf(" LESS THAN FOUR POINTS REQUESTED.");
01906
01907 L1450:
01908
01909 ierrf = -1;
01910
01911 fCstatu = "USER ERROR";
01912
01913 goto L2000;
01914
01915 L1500:
01916
01917 fPrintf(" MNCONT UNABLE TO FIND FOUR POINTS.");
01918
01919 fU[ke1-1] = u1min;
01920
01921 fU[ke2-1] = u2min;
01922
01923 ierrf = 0;
01924
01925 fCstatu = "FAILED";
01926
01927 L2000:
01928
01929 fCfrom = "MNContour ";
01930
01931 fNfcnfr = nfcnco;
01932
01933 }
01934
01935
01936
01937
01938
01939 void Midnight::mncrck(MString &crdbuf, MInt maxcwd, MString &comand, MInt &lnc,
01940
01941 MInt mxp, MDouble *plist, MInt &llist, MInt &ierr, MInt)
01942
01943 {
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975 static MString cnull = ")NULL STRING ";
01976
01977 static MString cnumer = "123456789-.0+";
01978
01979
01980
01981
01982
01983 static MInt ifld, iend, lend, left, nreq, ipos, kcmnd, nextb, ic, ibegin, ltoadd;
01984
01985 static MInt ielmnt, lelmnt[25], nelmnt;
01986
01987 static MString celmnt[25], ctemp;
01988
01989
01990
01991
01992
01993 ielmnt = 0;
01994
01995 lend = strlen((const char*)crdbuf);
01996
01997 nextb = 1;
01998
01999 ierr = 0;
02000
02001
02002
02003 L10:
02004
02005 for (ipos = nextb; ipos <= lend; ++ipos) {
02006
02007 ibegin = ipos;
02008
02009 if (crdbuf[ipos-1] == ' ') continue;
02010
02011 if (crdbuf[ipos-1] == ',') goto L250;
02012
02013 goto L150;
02014
02015 }
02016
02017 goto L300;
02018
02019 L150:
02020
02021
02022
02023 for (ipos = ibegin + 1; ipos <= lend; ++ipos) {
02024
02025 if (crdbuf[ipos-1] == ' ') goto L250;
02026
02027 if (crdbuf[ipos-1] == ',') goto L250;
02028
02029 }
02030
02031 ipos = lend + 1;
02032
02033 L250:
02034
02035 iend = ipos - 1;
02036
02037 ++ielmnt;
02038
02039 if (iend >= ibegin) celmnt[ielmnt-1] = crdbuf(ibegin-1, iend-ibegin+1);
02040
02041 else celmnt[ielmnt-1] = cnull;
02042
02043 lelmnt[ielmnt-1] = iend - ibegin + 1;
02044
02045 if (lelmnt[ielmnt-1] > 19) {
02046
02047 fPrintf(" MINUIT WARNING: INPUT DATA WORD TOO LONG.");
02048
02049 ctemp = crdbuf(ibegin-1,iend-ibegin+1);
02050
02051 fPrintf(" ORIGINAL:%s",(const char*)ctemp);
02052
02053 fPrintf(" TRUNCATED TO:%s",(const char*)celmnt[ielmnt-1]);
02054
02055 lelmnt[ielmnt-1] = 19;
02056
02057 }
02058
02059 if (ipos >= lend) goto L300;
02060
02061 if (ielmnt >= 25) goto L300;
02062
02063
02064
02065 for (ipos = iend + 1; ipos <= lend; ++ipos) {
02066
02067 if (crdbuf[ipos-1] == ' ') continue;
02068
02069 nextb = ipos;
02070
02071 if (crdbuf[ipos-1] == ',') nextb = ipos + 1;
02072
02073 goto L10;
02074
02075 }
02076
02077
02078
02079
02080
02081 L300:
02082
02083 nelmnt = ielmnt;
02084
02085 comand = " ";
02086
02087 lnc = 1;
02088
02089 plist[0] = 0;
02090
02091 llist = 0;
02092
02093 if (ielmnt == 0) goto L900;
02094
02095 kcmnd = 0;
02096
02097 for (ielmnt = 1; ielmnt <= nelmnt; ++ielmnt) {
02098
02099 if ( celmnt[ielmnt-1] == cnull) goto L450;
02100
02101 for (ic = 1; ic <= 13; ++ic) {
02102
02103 if (celmnt[ielmnt-1](0,1) == cnumer(ic-1,1)) goto L450;
02104
02105 }
02106
02107 if (kcmnd >= maxcwd) continue;
02108
02109 left = maxcwd - kcmnd;
02110
02111 ltoadd = lelmnt[ielmnt-1];
02112
02113 if (ltoadd > left) ltoadd = left;
02114
02115
02116
02117 comand.replace(kcmnd,ltoadd,celmnt[ielmnt-1](0,ltoadd));
02118
02119 kcmnd += ltoadd;
02120
02121 if (kcmnd == maxcwd) continue;
02122
02123 comand[kcmnd] = ' ';
02124
02125 ++kcmnd;
02126
02127 }
02128
02129 lnc = kcmnd;
02130
02131 goto L900;
02132
02133 L450:
02134
02135 lnc = kcmnd;
02136
02137
02138
02139 llist = 0;
02140
02141 for (ifld = ielmnt; ifld <= nelmnt; ++ifld) {
02142
02143 ++(llist);
02144
02145 if (llist > mxp) {
02146
02147 nreq = nelmnt - ielmnt + 1;
02148
02149 fPrintf(" MINUIT WARNING IN MNCRCK: ");
02150
02151 fPrintf(" COMMAND HAS INPUT%5d NUMERIC FIELDS, BUT MINUIT CAN ACCEPT ONLY%3d",nreq,mxp);
02152
02153 goto L900;
02154
02155 }
02156
02157 if (celmnt[ifld-1] == cnull) plist[llist-1] = 0;
02158
02159 else {
02160
02161 fPrintf("Fatal Error: mnerr code not yet implemented.");
02162
02163 }
02164
02165 }
02166
02167
02168
02169 L900:
02170
02171 if (lnc <= 0) lnc = 1;
02172
02173 }
02174
02175
02176
02177
02178
02179 void Midnight::mncros(MDouble &aopt, MInt &iercr)
02180
02181 {
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 static MString charal = " .ABCDEFGHIJKLMNOPQRSTUVWXYZ";
02206
02207
02208
02209
02210
02211 static MDouble alsb[3], flsb[3], bmin, bmax, zmid, sdev, zdir, zlim;
02212
02213 static MDouble coeff[3], aleft, aulim, fdist, adist, aminsv;
02214
02215 static MDouble anext, fnext, slope, s1, s2, x1, x2, ecarmn, ecarmx;
02216
02217 static MDouble determ, rt, smalla, aright, aim, tla, tlf, dfda,ecart;
02218
02219 static MInt iout, i, ileft, ierev, maxlk, ibest, ik, it;
02220
02221 static MInt noless, iworst, iright, itoohi, kex, ipt;
02222
02223 static MBool ldebug;
02224
02225 static const char *chsign;
02226
02227 x2 = 0;
02228
02229
02230
02231 ldebug = fIdbg[6] >= 1;
02232
02233 aminsv = fAmin;
02234
02235
02236
02237
02238
02239 aim = fAmin + fUp;
02240
02241 tlf = fUp*.01;
02242
02243 tla = .01;
02244
02245 fXpt[0] = 0;
02246
02247 fYpt[0] = aim;
02248
02249 fChpt[0] = ' ';
02250
02251 ipt = 1;
02252
02253 if (fKe2cr == 0) {
02254
02255 fXpt[1] = -1;
02256
02257 fYpt[1] = fAmin;
02258
02259 fChpt[1] = '.';
02260
02261 ipt = 2;
02262
02263 }
02264
02265
02266
02267 aulim = 100;
02268
02269 for (ik = 1; ik <= 2; ++ik) {
02270
02271 if (ik == 1) {
02272
02273 kex = fKe1cr;
02274
02275 zmid = fXmidcr;
02276
02277 zdir = fXdircr;
02278
02279 } else {
02280
02281 if (fKe2cr == 0) continue;
02282
02283 kex = fKe2cr;
02284
02285 zmid = fYmidcr;
02286
02287 zdir = fYdircr;
02288
02289 }
02290
02291 if (fNvarl[kex-1] <= 1) continue;
02292
02293 if (zdir == 0) continue;
02294
02295 zlim = fAlim[kex-1];
02296
02297 if (zdir > 0) zlim = fBlim[kex-1];
02298
02299 aulim = TMath_Min(aulim,(zlim - zmid) / zdir);
02300
02301 }
02302
02303
02304
02305
02306
02307 anext = 0;
02308
02309 aopt = anext;
02310
02311 fLimset = kFALSE;
02312
02313 if (aulim < aopt + tla) fLimset = kTRUE;
02314
02315 mneval(anext, fnext, ierev);
02316
02317
02318
02319 if (ldebug) {
02320
02321 fPrintf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
02322
02323 }
02324
02325 if (ierev > 0) goto L900;
02326
02327 if (fLimset && fnext <= aim) goto L930;
02328
02329 ++ipt;
02330
02331 fXpt[ipt-1] = anext;
02332
02333 fYpt[ipt-1] = fnext;
02334
02335 fChpt[ipt-1] = charal(ipt-1,1);
02336
02337 alsb[0] = anext;
02338
02339 flsb[0] = fnext;
02340
02341 fnext = TMath_Max(fnext,aminsv + fUp*.1);
02342
02343 aopt = TMath_Sqrt(fUp / (fnext - aminsv)) - 1;
02344
02345 if (TMath_Abs(fnext - aim) < tlf) goto L800;
02346
02347
02348
02349 if (aopt < -.5)aopt = -.5;
02350
02351 if (aopt > 1) aopt = 1;
02352
02353 fLimset = kFALSE;
02354
02355 if (aopt > aulim) {
02356
02357 aopt = aulim;
02358
02359 fLimset = kTRUE;
02360
02361 }
02362
02363 mneval(aopt, fnext, ierev);
02364
02365
02366
02367 if (ldebug) {
02368
02369 fPrintf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
02370
02371 }
02372
02373 if (ierev > 0) goto L900;
02374
02375 if (fLimset && fnext <= aim) goto L930;
02376
02377 alsb[1] = aopt;
02378
02379 ++ipt;
02380
02381 fXpt[ipt-1] = alsb[1];
02382
02383 fYpt[ipt-1] = fnext;
02384
02385 fChpt[ipt-1] = charal(ipt-1,1);
02386
02387 flsb[1] = fnext;
02388
02389 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
02390
02391
02392
02393 if (dfda > 0) goto L460;
02394
02395 L300:
02396
02397 mnwarn("D", "MNCROS ", "Looking for slope of the right sign");
02398
02399 maxlk = 15 - ipt;
02400
02401 for (it = 1; it <= maxlk; ++it) {
02402
02403 alsb[0] = alsb[1];
02404
02405 flsb[0] = flsb[1];
02406
02407 aopt = alsb[0] + MDouble(it)*.2;
02408
02409 fLimset = kFALSE;
02410
02411 if (aopt > aulim) {
02412
02413 aopt = aulim;
02414
02415 fLimset = kTRUE;
02416
02417 }
02418
02419 mneval(aopt, fnext, ierev);
02420
02421
02422
02423 if (ldebug) {
02424
02425 fPrintf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
02426
02427 }
02428
02429 if (ierev > 0) goto L900;
02430
02431 if (fLimset && fnext <= aim) goto L930;
02432
02433 alsb[1] = aopt;
02434
02435 ++ipt;
02436
02437 fXpt[ipt-1] = alsb[1];
02438
02439 fYpt[ipt-1] = fnext;
02440
02441 fChpt[ipt-1] = charal(ipt-1,1);
02442
02443 flsb[1] = fnext;
02444
02445 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
02446
02447 if (dfda > 0) goto L450;
02448
02449 }
02450
02451 mnwarn("W", "MNCROS ", "Cannot find slope of the right sign");
02452
02453 goto L950;
02454
02455 L450:
02456
02457
02458
02459 L460:
02460
02461 aopt = alsb[1] + (aim - flsb[1]) / dfda;
02462
02463 fdist = TMath_Min(TMath_Abs(aim - flsb[0]),TMath_Abs(aim - flsb[1]));
02464
02465 adist = TMath_Min(TMath_Abs(aopt - alsb[0]),TMath_Abs(aopt - alsb[1]));
02466
02467 tla = .01;
02468
02469 if (TMath_Abs(aopt) > 1) tla = TMath_Abs(aopt)*.01;
02470
02471 if (adist < tla && fdist < tlf) goto L800;
02472
02473 if (ipt >= 15) goto L950;
02474
02475 bmin = TMath_Min(alsb[0],alsb[1]) - 1;
02476
02477 if (aopt < bmin) aopt = bmin;
02478
02479 bmax = TMath_Max(alsb[0],alsb[1]) + 1;
02480
02481 if (aopt > bmax) aopt = bmax;
02482
02483
02484
02485 fLimset = kFALSE;
02486
02487 if (aopt > aulim) {
02488
02489 aopt = aulim;
02490
02491 fLimset = kTRUE;
02492
02493 }
02494
02495 mneval(aopt, fnext, ierev);
02496
02497
02498
02499 if (ldebug) {
02500
02501 fPrintf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
02502
02503 }
02504
02505 if (ierev > 0) goto L900;
02506
02507 if (fLimset && fnext <= aim) goto L930;
02508
02509 alsb[2] = aopt;
02510
02511 ++ipt;
02512
02513 fXpt[ipt-1] = alsb[2];
02514
02515 fYpt[ipt-1] = fnext;
02516
02517 fChpt[ipt-1] = charal(ipt-1,1);
02518
02519 flsb[2] = fnext;
02520
02521
02522
02523 ecarmn = TMath_Abs(fnext-aim);
02524
02525 ibest = 3;
02526
02527 ecarmx = 0;
02528
02529 noless = 0;
02530
02531 for (i = 1; i <= 3; ++i) {
02532
02533 ecart = TMath_Abs(flsb[i-1] - aim);
02534
02535 if (ecart > ecarmx) { ecarmx = ecart; iworst = i; }
02536
02537 if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
02538
02539 if (flsb[i-1] < aim) ++noless;
02540
02541 }
02542
02543
02544
02545 if (noless == 1 || noless == 2) goto L500;
02546
02547
02548
02549 if (noless == 0 && ibest != 3) goto L950;
02550
02551
02552
02553
02554
02555 if (noless == 3 && ibest != 3) {
02556
02557 alsb[1] = alsb[2];
02558
02559 flsb[1] = flsb[2];
02560
02561 goto L300;
02562
02563 }
02564
02565
02566
02567 alsb[iworst-1] = alsb[2];
02568
02569 flsb[iworst-1] = flsb[2];
02570
02571 dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
02572
02573 goto L460;
02574
02575
02576
02577 L500:
02578
02579 mnpfit(alsb, flsb, 3, coeff, sdev);
02580
02581 if (coeff[2] <= 0) {
02582
02583 mnwarn("D", "MNCROS ", "Curvature is negative near contour line.");
02584
02585 }
02586
02587 determ = coeff[1]*coeff[1] - coeff[2]*4*(coeff[0] - aim);
02588
02589 if (determ <= 0) {
02590
02591 mnwarn("D", "MNCROS ", "Problem 2, impossible determinant");
02592
02593 goto L950;
02594
02595 }
02596
02597
02598
02599 rt = TMath_Sqrt(determ);
02600
02601 x1 = (-coeff[1] + rt) / (coeff[2]*2);
02602
02603 x2 = (-coeff[1] - rt) / (coeff[2]*2);
02604
02605 s1 = coeff[1] + x1*2*coeff[2];
02606
02607 s2 = coeff[1] + x2*2*coeff[2];
02608
02609 if (s1*s2 > 0) {
02610
02611 fPrintf(" MNCONTour problem 1");
02612
02613 }
02614
02615 aopt = x1;
02616
02617 slope = s1;
02618
02619 if (s2 > 0) {
02620
02621 aopt = x2;
02622
02623 slope = s2;
02624
02625 }
02626
02627
02628
02629 tla = .01;
02630
02631 if (TMath_Abs(aopt) > 1) tla = TMath_Abs(aopt)*.01;
02632
02633 if (TMath_Abs(aopt - alsb[ibest-1]) < tla && TMath_Abs(flsb[ibest-1] - aim) < tlf) {
02634
02635 goto L800;
02636
02637 }
02638
02639 if (ipt >= 15) goto L950;
02640
02641
02642
02643
02644
02645
02646
02647 ileft = 0;
02648
02649 iright = 0;
02650
02651 ibest = 1;
02652
02653 ecarmx = 0;
02654
02655 ecarmn = TMath_Abs(aim - flsb[0]);
02656
02657 for (i = 1; i <= 3; ++i) {
02658
02659 ecart = TMath_Abs(flsb[i-1] - aim);
02660
02661 if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
02662
02663 if (ecart > ecarmx) { ecarmx = ecart; }
02664
02665 if (flsb[i-1] > aim) {
02666
02667 if (iright == 0) iright = i;
02668
02669 else if (flsb[i-1] > flsb[iright-1]) iout = i;
02670
02671 else { iout = iright; iright = i; }
02672
02673 }
02674
02675 else if (ileft == 0) ileft = i;
02676
02677 else if (flsb[i-1] < flsb[ileft-1]) iout = i;
02678
02679 else { iout = ileft; ileft = i; }
02680
02681 }
02682
02683
02684
02685 if (ecarmx > TMath_Abs(flsb[iout-1] - aim)*10) {
02686
02687 aopt = aopt*.5 + (alsb[iright-1] + alsb[ileft-1])*.25;
02688
02689 }
02690
02691
02692
02693 smalla = tla*.1;
02694
02695 if (slope*smalla > tlf) smalla = tlf / slope;
02696
02697 aleft = alsb[ileft-1] + smalla;
02698
02699 aright = alsb[iright-1] - smalla;
02700
02701
02702
02703 if (aopt < aleft) aopt = aleft;
02704
02705 if (aopt > aright) aopt = aright;
02706
02707 if (aleft > aright) aopt = (aleft + aright)*.5;
02708
02709
02710
02711
02712
02713 fLimset = kFALSE;
02714
02715 if (aopt > aulim) {
02716
02717 aopt = aulim;
02718
02719 fLimset = kTRUE;
02720
02721 }
02722
02723
02724
02725 mneval(aopt, fnext, ierev);
02726
02727
02728
02729 if (ldebug) {
02730
02731 fPrintf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
02732
02733 }
02734
02735 if (ierev > 0) goto L900;
02736
02737 if (fLimset && fnext <= aim) goto L930;
02738
02739 ++ipt;
02740
02741 fXpt[ipt-1] = aopt;
02742
02743 fYpt[ipt-1] = fnext;
02744
02745 fChpt[ipt-1] = charal(ipt-1,1);
02746
02747
02748
02749 alsb[iout-1] = aopt;
02750
02751 flsb[iout-1] = fnext;
02752
02753
02754
02755
02756
02757 ibest = iout;
02758
02759 goto L500;
02760
02761
02762
02763
02764
02765 L800:
02766
02767 iercr = 0;
02768
02769 goto L1000;
02770
02771
02772
02773 L900:
02774
02775 if (ierev == 1) goto L940;
02776
02777 goto L950;
02778
02779
02780
02781 L930:
02782
02783 iercr = 1;
02784
02785 goto L1000;
02786
02787
02788
02789 L940:
02790
02791 iercr = 2;
02792
02793 goto L1000;
02794
02795
02796
02797 L950:
02798
02799 iercr = 3;
02800
02801
02802
02803 L1000:
02804
02805 if (ldebug) {
02806
02807 itoohi = 0;
02808
02809 for (i = 1; i <= ipt; ++i) {
02810
02811 if (fYpt[i-1] > aim + fUp) {
02812
02813 fYpt[i-1] = aim + fUp;
02814
02815 fChpt[i-1] = '+';
02816
02817 itoohi = 1;
02818
02819 }
02820
02821 }
02822
02823 chsign = "POSI";
02824
02825 if (fXdircr < 0) chsign = "NEGA";
02826
02827 if (fKe2cr == 0) {
02828
02829 fPrintf(" %sTIVE MINOS ERROR, PARAMETER %3d",chsign,fKe1cr);
02830
02831 }
02832
02833 if (itoohi == 1) {
02834
02835 fPrintf("POINTS LABELLED '+' WERE TOO HIGH TO PLOT.");
02836
02837 }
02838
02839 if (iercr == 1) {
02840
02841 fPrintf("RIGHTMOST POINT IS UP AGAINST LIMIT.");
02842
02843 }
02844
02845 mnplot(fXpt, fYpt, fChpt, ipt, fNpagwd, fNpagln);
02846
02847 }
02848
02849 }
02850
02851
02852
02853
02854
02855 void Midnight::mncuve()
02856
02857 {
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875 static MDouble dxdi, wint;
02876
02877 static MInt ndex, iext, i, j;
02878
02879
02880
02881 if (fISW[3] < 1) {
02882
02883 fPrintf(" FUNCTION MUST BE MINIMIZED BEFORE CALLING %s",(const char*)fCfrom);
02884
02885 fApsi = fEpsi;
02886
02887 mnmigr();
02888
02889 }
02890
02891 if (fISW[1] < 3) {
02892
02893 mnhess();
02894
02895 if (fISW[1] < 1) {
02896
02897 mnwarn("W", fCfrom, "NO ERROR MATRIX. WILL IMPROVISE.");
02898
02899 for (i = 1; i <= fNpar; ++i) {
02900
02901 ndex = i*(i-1) / 2;
02902
02903 for (j = 1; j <= i-1; ++j) {
02904
02905 ++ndex;
02906
02907 fVhmat[ndex-1] = 0;
02908
02909 }
02910
02911 ++ndex;
02912
02913 if (fG2[i-1] <= 0) {
02914
02915 wint = fWerr[i-1];
02916
02917 iext = fNexofi[i-1];
02918
02919 if (fNvarl[iext-1] > 1) {
02920
02921 mndxdi(fX[i-1], i-1, dxdi);
02922
02923 if (TMath_Abs(dxdi) < .001) wint = .01;
02924
02925 else wint /= TMath_Abs(dxdi);
02926
02927 }
02928
02929 fG2[i-1] = fUp / (wint*wint);
02930
02931 }
02932
02933 fVhmat[ndex-1] = 2 / fG2[i-1];
02934
02935 }
02936
02937 fISW[1] = 1;
02938
02939 fDcovar = 1;
02940
02941 } else mnwerr();
02942
02943 }
02944
02945 }
02946
02947
02948
02949
02950
02951 void Midnight::mnderi()
02952
02953 {
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973 static MDouble step, dfmin, stepb4, dd, df, fs1;
02974
02975 static MDouble tlrstp, tlrgrd, epspri, optstp, stpmax, stpmin, fs2, grbfor, d1d2, xtf;
02976
02977 static MInt icyc, ncyc, iint, iext, i, nparx;
02978
02979 static MBool ldebug;
02980
02981
02982
02983 nparx = fNpar;
02984
02985 ldebug = fIdbg[2] >= 1;
02986
02987 if (fAmin == fUndefi) mnamin();
02988
02989 if (fISW[2] == 1) goto L100;
02990
02991
02992
02993 if (ldebug) {
02994
02995
02996
02997 mninex(fX);
02998
02999 nparx = fNpar;
03000
03001 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
03002
03003 if (fs1 != fAmin) {
03004
03005 df = fAmin - fs1;
03006
03007 mnwarn("D", "MNDERI", Form("function value differs from AMIN by %12.3g",df));
03008
03009 fAmin = fs1;
03010
03011 }
03012
03013 fPrintf(" FIRST DERIVATIVE DEBUG PRINTOUT. MNDERI");
03014
03015 fPrintf(" PAR DERIV STEP MINSTEP OPTSTEP D1-D2 2ND DRV");
03016
03017 }
03018
03019 dfmin = fEpsma2*8*(TMath_Abs(fAmin) + fUp);
03020
03021 if (fIstrat <= 0) {
03022
03023 ncyc = 2;
03024
03025 tlrstp = .5;
03026
03027 tlrgrd = .1;
03028
03029 } else if (fIstrat == 1) {
03030
03031 ncyc = 3;
03032
03033 tlrstp = .3;
03034
03035 tlrgrd = .05;
03036
03037 } else {
03038
03039 ncyc = 5;
03040
03041 tlrstp = .1;
03042
03043 tlrgrd = .02;
03044
03045 }
03046
03047
03048
03049 for (i = 1; i <= fNpar; ++i) {
03050
03051 epspri = fEpsma2 + TMath_Abs(fGrd[i-1]*fEpsma2);
03052
03053
03054
03055
03056
03057 xtf = fX[i-1];
03058
03059 stepb4 = 0;
03060
03061
03062
03063 for (icyc = 1; icyc <= ncyc; ++icyc) {
03064
03065
03066
03067 optstp = TMath_Sqrt(dfmin / (TMath_Abs(fG2[i-1]) + epspri));
03068
03069
03070
03071 step = TMath_Max(optstp,TMath_Abs(fGstep[i-1]*.1));
03072
03073
03074
03075 if (fGstep[i-1] < 0 && step > .5) step = .5;
03076
03077
03078
03079 stpmax = TMath_Abs(fGstep[i-1])*10;
03080
03081 if (step > stpmax) step = stpmax;
03082
03083
03084
03085 stpmin = TMath_Abs(fEpsma2*fX[i-1])*8;
03086
03087 if (step < stpmin) step = stpmin;
03088
03089
03090
03091 if (TMath_Abs((step - stepb4) / step) < tlrstp) goto L50;
03092
03093
03094
03095 stepb4 = step;
03096
03097 if (fGstep[i-1] > 0) fGstep[i-1] = TMath_Abs(step);
03098
03099 else fGstep[i-1] = -TMath_Abs(step);
03100
03101 stepb4 = step;
03102
03103 fX[i-1] = xtf + step;
03104
03105 mninex(fX);
03106
03107 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
03108
03109
03110
03111 fX[i-1] = xtf - step;
03112
03113 mninex(fX);
03114
03115 (*fFCN)(nparx, fGin, fs2, fU, 4); ++fNfcn;
03116
03117 grbfor = fGrd[i-1];
03118
03119 fGrd[i-1] = (fs1 - fs2) / (step*2);
03120
03121 fG2[i-1] = (fs1 + fs2 - fAmin*2) / (step*step);
03122
03123 fX[i-1] = xtf;
03124
03125 if (ldebug) {
03126
03127 d1d2 = (fs1 + fs2 - fAmin*2) / step;
03128
03129 fPrintf("%4d%11.3g%11.3g%10.2g%10.2g%10.2g%10.2g%10.2g",i,fGrd[i-1],step,stpmin,optstp,d1d2,fG2[i-1]);
03130
03131 }
03132
03133
03134
03135 if (TMath_Abs(grbfor - fGrd[i-1]) / (TMath_Abs(fGrd[i-1]) + dfmin/step) < tlrgrd)
03136
03137 goto L50;
03138
03139 }
03140
03141
03142
03143 if (ncyc == 1) goto L50;
03144
03145 mnwarn("D", "MNDERI", Form("First derivative not converged. %g%g",fGrd[i-1],grbfor));
03146
03147 L50:
03148
03149 ;
03150
03151 }
03152
03153 mninex(fX);
03154
03155 return;
03156
03157
03158
03159 L100:
03160
03161 for (iint = 1; iint <= fNpar; ++iint) {
03162
03163 iext = fNexofi[iint-1];
03164
03165 if (fNvarl[iext-1] <= 1) {
03166
03167 fGrd[iint-1] = fGin[iext-1];
03168
03169 } else {
03170
03171 dd = (fBlim[iext-1] - fAlim[iext-1])*.5*TMath_Cos(fX[iint-1]);
03172
03173 fGrd[iint-1] = fGin[iext-1]*dd;
03174
03175 }
03176
03177 }
03178
03179 }
03180
03181
03182
03183
03184
03185 void Midnight::mndxdi(MDouble pint, MInt ipar, MDouble &dxdi)
03186
03187 {
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203 MInt i = fNexofi[ipar];
03204
03205 dxdi = 1;
03206
03207 if (fNvarl[i-1] > 1) {
03208
03209 dxdi = TMath_Abs((fBlim[i-1] - fAlim[i-1])*TMath_Cos(pint))*.5;
03210
03211 }
03212
03213 }
03214
03215
03216
03217
03218
03219 void Midnight::mneig(MDouble *a, MInt ndima, MInt n, MInt mits, MDouble *work, MDouble precis, MInt &ifault)
03220
03221 {
03222
03223
03224
03225
03226
03227
03228
03229 MInt a_offset;
03230
03231 MDouble d__1;
03232
03233
03234
03235
03236
03237 static MDouble b, c, f, h, r, s, hh, gl, pr, pt;
03238
03239 static MInt i, j, k, l, m, i0, i1, j1, m1, n1;
03240
03241
03242
03243
03244
03245
03246
03247 a_offset = ndima + 1;
03248
03249 a -= a_offset;
03250
03251 --work;
03252
03253
03254
03255
03256
03257 ifault = 1;
03258
03259
03260
03261 i = n;
03262
03263 for (i1 = 2; i1 <= n; ++i1) {
03264
03265 l = i-2;
03266
03267 f = a[i + (i-1)*ndima];
03268
03269 gl = 0;
03270
03271
03272
03273 if (l < 1) goto L25;
03274
03275
03276
03277 for (k = 1; k <= l; ++k) {
03278
03279 d__1 = a[i + k*ndima];
03280
03281 gl += d__1*d__1;
03282
03283 }
03284
03285 L25:
03286
03287 h = gl + f*f;
03288
03289
03290
03291 if (gl > 1e-35) goto L30;
03292
03293
03294
03295 work[i] = 0;
03296
03297 work[n + i] = f;
03298
03299 goto L65;
03300
03301 L30:
03302
03303 ++l;
03304
03305 gl = TMath_Sqrt(h);
03306
03307 if (f >= 0) gl = -gl;
03308
03309 work[n + i] = gl;
03310
03311 h -= f*gl;
03312
03313 a[i + (i-1)*ndima] = f - gl;
03314
03315 f = 0;
03316
03317 for (j = 1; j <= l; ++j) {
03318
03319 a[j + i*ndima] = a[i + j*ndima] / h;
03320
03321 gl = 0;
03322
03323 for (k = 1; k <= j; ++k) { gl += a[j + k*ndima]*a[i + k*ndima]; }
03324
03325 if (j >= l) goto L47;
03326
03327 j1 = j + 1;
03328
03329 for (k = j1; k <= l; ++k) { gl += a[k + j*ndima]*a[i + k*ndima]; }
03330
03331 L47:
03332
03333 work[n + j] = gl / h;
03334
03335 f += gl*a[j + i*ndima];
03336
03337 }
03338
03339 hh = f / (h + h);
03340
03341 for (j = 1; j <= l; ++j) {
03342
03343 f = a[i + j*ndima];
03344
03345 gl = work[n + j] - hh*f;
03346
03347 work[n + j] = gl;
03348
03349 for (k = 1; k <= j; ++k) {
03350
03351 a[j + k*ndima] = a[j + k*ndima] - f*work[n + k] - gl*a[i + k*ndima];
03352
03353 }
03354
03355 }
03356
03357 work[i] = h;
03358
03359 L65:
03360
03361 --i;
03362
03363 }
03364
03365 work[1] = 0;
03366
03367 work[n + 1] = 0;
03368
03369 for (i = 1; i <= n; ++i) {
03370
03371 l = i-1;
03372
03373 if (work[i] == 0 || l == 0) goto L100;
03374
03375
03376
03377 for (j = 1; j <= l; ++j) {
03378
03379 gl = 0;
03380
03381 for (k = 1; k <= l; ++k) { gl += a[i + k*ndima]*a[k + j*ndima]; }
03382
03383 for (k = 1; k <= l; ++k) { a[k + j*ndima] -= gl*a[k + i*ndima]; }
03384
03385 }
03386
03387 L100:
03388
03389 work[i] = a[i + i*ndima];
03390
03391 a[i + i*ndima] = 1;
03392
03393 if (l == 0) continue;
03394
03395
03396
03397 for (j = 1; j <= l; ++j) {
03398
03399 a[i + j*ndima] = 0;
03400
03401 a[j + i*ndima] = 0;
03402
03403 }
03404
03405 }
03406
03407
03408
03409 n1 = n - 1;
03410
03411 for (i = 2; i <= n; ++i) {
03412
03413 i0 = n + i-1;
03414
03415 work[i0] = work[i0 + 1];
03416
03417 }
03418
03419 work[n + n] = 0;
03420
03421 b = 0;
03422
03423 f = 0;
03424
03425 for (l = 1; l <= n; ++l) {
03426
03427 j = 0;
03428
03429 h = precis*(TMath_Abs(work[l]) + TMath_Abs(work[n + l]));
03430
03431 if (b < h) b = h;
03432
03433 for (m1 = l; m1 <= n; ++m1) {
03434
03435 m = m1;
03436
03437 if (TMath_Abs(work[n + m]) <= b) goto L150;
03438
03439 }
03440
03441
03442
03443 L150:
03444
03445 if (m == l) goto L205;
03446
03447
03448
03449 L160:
03450
03451 if (j == mits) return;
03452
03453 ++j;
03454
03455 pt = (work[l + 1] - work[l]) / (work[n + l]*2);
03456
03457 r = TMath_Sqrt(pt*pt + 1);
03458
03459 pr = pt + r;
03460
03461 if (pt < 0) pr = pt - r;
03462
03463
03464
03465 h = work[l] - work[n + l] / pr;
03466
03467 for (i = l; i <= n; ++i) { work[i] -= h; }
03468
03469 f += h;
03470
03471 pt = work[m];
03472
03473 c = 1;
03474
03475 s = 0;
03476
03477 m1 = m - 1;
03478
03479 i = m;
03480
03481 for (i1 = l; i1 <= m1; ++i1) {
03482
03483 j = i;
03484
03485 --i;
03486
03487 gl = c*work[n + i];
03488
03489 h = c*pt;
03490
03491 if (TMath_Abs(pt) >= TMath_Abs(work[n + i])) goto L180;
03492
03493
03494
03495 c = pt / work[n + i];
03496
03497 r = TMath_Sqrt(c*c + 1);
03498
03499 work[n + j] = s*work[n + i]*r;
03500
03501 s = 1 / r;
03502
03503 c /= r;
03504
03505 goto L190;
03506
03507 L180:
03508
03509 c = work[n + i] / pt;
03510
03511 r = TMath_Sqrt(c*c + 1);
03512
03513 work[n + j] = s*pt*r;
03514
03515 s = c / r;
03516
03517 c = 1 / r;
03518
03519 L190:
03520
03521 pt = c*work[i] - s*gl;
03522
03523 work[j] = h + s*(c*gl + s*work[i]);
03524
03525 for (k = 1; k <= n; ++k) {
03526
03527 h = a[k + j*ndima];
03528
03529 a[k + j*ndima] = s*a[k + i*ndima] + c*h;
03530
03531 a[k + i*ndima] = c*a[k + i*ndima] - s*h;
03532
03533 }
03534
03535 }
03536
03537 work[n + l] = s*pt;
03538
03539 work[l] = c*pt;
03540
03541
03542
03543 if (TMath_Abs(work[n + l]) > b) goto L160;
03544
03545
03546
03547 L205:
03548
03549 work[l] += f;
03550
03551 }
03552
03553 for (i = 1; i <= n1; ++i) {
03554
03555 k = i;
03556
03557 pt = work[i];
03558
03559 i1 = i + 1;
03560
03561 for (j = i1; j <= n; ++j) {
03562
03563 if (work[j] >= pt) continue;
03564
03565 k = j;
03566
03567 pt = work[j];
03568
03569 }
03570
03571
03572
03573 if (k == i) continue;
03574
03575
03576
03577 work[k] = work[i];
03578
03579 work[i] = pt;
03580
03581 for (j = 1; j <= n; ++j) {
03582
03583 pt = a[j + i*ndima];
03584
03585 a[j + i*ndima] = a[j + k*ndima];
03586
03587 a[j + k*ndima] = pt;
03588
03589 }
03590
03591 }
03592
03593 ifault = 0;
03594
03595 }
03596
03597
03598
03599
03600
03601 void Midnight::mnemat(MDouble *emat, MInt ndim)
03602
03603 {
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619 MInt emat_dim1, emat_offset;
03620
03621
03622
03623
03624
03625 static MDouble dxdi, dxdj;
03626
03627 static MInt i, j, k, npard, k2, kk, iz, nperln, kga, kgb;
03628
03629 static MString ctemp;
03630
03631
03632
03633
03634
03635 emat_dim1 = ndim;
03636
03637 emat_offset = emat_dim1 + 1;
03638
03639 emat -= emat_offset;
03640
03641
03642
03643
03644
03645 if (fISW[1] < 1) return;
03646
03647 if (fISW[4] >= 2) {
03648
03649 fPrintf(" EXTERNAL ERROR MATRIX. NDIM=%4d NPAR=%3d ERR DEF=%g",ndim,fNpar,fUp);
03650
03651 }
03652
03653
03654
03655 npard = fNpar;
03656
03657 if (ndim < fNpar) {
03658
03659 npard = ndim;
03660
03661 if (fISW[4] >= 0) {
03662
03663 fPrintf(" USER-DIMENSIONED ARRAY EMAT NOT BIG ENOUGH. REDUCED MATRIX CALCULATED.");
03664
03665 }
03666
03667 }
03668
03669
03670
03671
03672
03673 nperln = (fNpagwd - 5) / 10;
03674
03675 nperln = TMath_Min(nperln,13);
03676
03677 if (fISW[4] >= 1 && npard > nperln) {
03678
03679 fPrintf(" ELEMENTS ABOVE DIAGONAL ARE NOT PRINTED.");
03680
03681 }
03682
03683
03684
03685 for (i = 1; i <= npard; ++i) {
03686
03687 mndxdi(fX[i-1], i-1, dxdi);
03688
03689 kga = i*(i-1) / 2;
03690
03691 for (j = 1; j <= i; ++j) {
03692
03693 mndxdi(fX[j-1], j-1, dxdj);
03694
03695 kgb = kga + j;
03696
03697 emat[i + j*emat_dim1] = dxdi*fVhmat[kgb-1]*dxdj*fUp;
03698
03699 emat[j + i*emat_dim1] = emat[i + j*emat_dim1];
03700
03701 }
03702
03703 }
03704
03705
03706
03707 if (fISW[4] >= 2) {
03708
03709 for (i = 1; i <= npard; ++i) {
03710
03711 iz = npard;
03712
03713 if (npard >= nperln) iz = i;
03714
03715 ctemp = " ";
03716
03717 for (k = 1; nperln < 0 ? k >= iz : k <= iz; k += nperln) {
03718
03719 k2 = k + nperln - 1;
03720
03721 if (k2 > iz) k2 = iz;
03722
03723 for (kk = k; kk <= k2; ++kk) {
03724
03725 ctemp += Form("%10.3e ",emat[i + kk*emat_dim1]);
03726
03727 }
03728
03729 fPrintf("%s",(const char*)ctemp);
03730
03731 }
03732
03733 }
03734
03735 }
03736
03737 }
03738
03739
03740
03741
03742
03743 void Midnight::mnerrs(MInt number, MDouble &eplus, MDouble &eminus, MDouble &eparab, MDouble &gcc)
03744
03745 {
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769 static MDouble dxdi;
03770
03771 static MInt ndiag, iin, iex;
03772
03773
03774
03775 iex = number+1;
03776
03777
03778
03779 if (iex > fNu || iex <= 0) goto L900;
03780
03781 iin = fNiofex[iex-1];
03782
03783 if (iin <= 0) goto L900;
03784
03785
03786
03787
03788
03789 eplus = fErp[iin-1];
03790
03791 if (eplus == fUndefi) eplus = 0;
03792
03793 eminus = fErn[iin-1];
03794
03795 if (eminus == fUndefi) eminus = 0;
03796
03797 mndxdi(fX[iin-1], iin-1, dxdi);
03798
03799 ndiag = iin*(iin + 1) / 2;
03800
03801 eparab = TMath_Abs(dxdi*TMath_Sqrt(TMath_Abs(fUp*fVhmat[ndiag- 1])));
03802
03803
03804
03805 gcc = 0;
03806
03807 if (fISW[1] < 2) return;
03808
03809 gcc = fGlobcc[iin-1];
03810
03811 return;
03812
03813
03814
03815 L900:
03816
03817 eplus = 0;
03818
03819 eminus = 0;
03820
03821 eparab = 0;
03822
03823 gcc = 0;
03824
03825 }
03826
03827
03828
03829
03830
03831 void Midnight::mneval(MDouble anext, MDouble &fnext, MInt &ierev)
03832
03833 {
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855 static MInt nparx;
03856
03857
03858
03859 fU[fKe1cr-1] = fXmidcr + anext*fXdircr;
03860
03861 if (fKe2cr != 0) fU[fKe2cr-1] = fYmidcr + anext*fYdircr;
03862
03863 mninex(fX);
03864
03865 nparx = fNpar;
03866
03867 (*fFCN)(nparx, fGin, fnext, fU, 4); ++fNfcn;
03868
03869 ierev = 0;
03870
03871 if (fNpar > 0) {
03872
03873 fItaur = 1;
03874
03875 fAmin = fnext;
03876
03877 fISW[0] = 0;
03878
03879 mnmigr();
03880
03881 fItaur = 0;
03882
03883 fnext = fAmin;
03884
03885 if (fISW[0] >= 1) ierev = 1;
03886
03887 if (fISW[3] < 1) ierev = 2;
03888
03889 }
03890
03891 }
03892
03893
03894
03895
03896
03897 void Midnight::mnexcm(MString comand, MDouble *plist, MInt llist, MInt &ierflg)
03898
03899 {
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943 static MString clower = "abcdefghijklmnopqrstuvwxyz";
03944
03945 static MString cupper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
03946
03947 static MString cname[40] = {
03948
03949 "MINImize ",
03950
03951 "SEEk ",
03952
03953 "SIMplex ",
03954
03955 "MIGrad ",
03956
03957 "MINOs ",
03958
03959 "SET xxx ",
03960
03961 "SHOw xxx ",
03962
03963 "TOP of pag",
03964
03965 "FIX ",
03966
03967 "REStore ",
03968
03969 "RELease ",
03970
03971 "SCAn ",
03972
03973 "CONtour ",
03974
03975 "HESse ",
03976
03977 "SAVe ",
03978
03979 "IMProve ",
03980
03981 "CALl fcn ",
03982
03983 "STAndard ",
03984
03985 "END ",
03986
03987 "EXIt ",
03988
03989 "RETurn ",
03990
03991 "CLEar ",
03992
03993 "HELP ",
03994
03995 "MNContour ",
03996
03997 "STOp ",
03998
03999 "JUMp ",
04000
04001 " ",
04002
04003 " ",
04004
04005 " ",
04006
04007 " ",
04008
04009 " ",
04010
04011 " ",
04012
04013 " ",
04014
04015 "COVARIANCE",
04016
04017 "PRINTOUT ",
04018
04019 "GRADIENT ",
04020
04021 "MATOUT ",
04022
04023 "ERROR DEF ",
04024
04025 "LIMITS ",
04026
04027 "PUNCH "};
04028
04029
04030
04031 static MInt nntot = 40;
04032
04033
04034
04035
04036
04037 static MDouble step, xptu[101], yptu[101], f, rno;
04038
04039 static MInt icol, kcol, ierr, iint, iext, lnow, nptu, i, iflag, ierrf;
04040
04041 static MInt ilist, nparx, izero, nf, lk, it, iw, inonde, nsuper;
04042
04043 static MInt it2, ke1, ke2, nowprt, kll, let, krl;
04044
04045 static MString chwhy, c26, cvblnk, cneway, comd;
04046
04047 static MString ctemp;
04048
04049 static MBool lfreed, ltofix, lfixed;
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061 lk = strlen((const char*)comand);
04062
04063 if (lk > 20) lk = 20;
04064
04065 fCword = comand;
04066
04067
04068
04069 for (icol = 1; icol <= lk; ++icol) {
04070
04071 for (let = 1; let <= 26; ++let) {
04072
04073 if (fCword[icol-1] == clower[let-1]) {
04074
04075 fCword[icol-1] = cupper[let-1];
04076
04077 }
04078
04079 }
04080
04081 }
04082
04083
04084
04085
04086
04087 for (iw = 1; iw <= 30; ++iw) {
04088
04089 fWord7[iw-1] = 0;
04090
04091 if (iw <= llist) fWord7[iw-1] = plist[iw-1];
04092
04093 }
04094
04095 ++fIcomnd;
04096
04097 fNfcnlc = fNfcn;
04098
04099 if (fCword(0,7) != "SET PRI" || fWord7[0] >= 0) {
04100
04101 if (fISW[4] >= 0) {
04102
04103 lnow = llist;
04104
04105 if (lnow > 4) lnow = 4;
04106
04107 fPrintf(" **********");
04108
04109 ctemp = Form(" **%5d **%s",fIcomnd,(const char*)fCword);
04110
04111 for (i = 1; i <= lnow; ++i) {
04112
04113 ctemp += Form("%12.4g",plist[i-1]);
04114
04115 }
04116
04117 fPrintf("%s",(const char*)ctemp);
04118
04119 inonde = 0;
04120
04121 if (llist > lnow) {
04122
04123 kll = llist;
04124
04125 if (llist > 30) {
04126
04127 inonde = 1;
04128
04129 kll = 30;
04130
04131 }
04132
04133 fPrintf(" ***********");
04134
04135 for (i = lnow + 1; i <= kll; ++i) {
04136
04137 fPrintf("%12.4g",plist[i-1]);
04138
04139 }
04140
04141 }
04142
04143 fPrintf(" **********");
04144
04145 if (inonde > 0) {
04146
04147 fPrintf(" ERROR: ABOVE CALL TO MNEXCM TRIED TO PASS MORE THAN 30 PARAMETERS.");
04148
04149 }
04150
04151 }
04152
04153 }
04154
04155 fNfcnmx = MInt(fWord7[0]);
04156
04157 if (fNfcnmx <= 0) {
04158
04159 fNfcnmx = fNpar*100 + 200 + fNpar*fNpar*5;
04160
04161 }
04162
04163 fEpsi = fWord7[1];
04164
04165 if (fEpsi <= 0) {
04166
04167 fEpsi = fUp*.1;
04168
04169 }
04170
04171 fLnewmn = kFALSE;
04172
04173 fLphead = kTRUE;
04174
04175 fISW[0] = 0;
04176
04177 ierflg = 0;
04178
04179
04180
04181 for (i = 1; i <= nntot; ++i) {
04182
04183 if (fCword(0,3) == cname[i-1](0,3)) goto L90;
04184
04185 }
04186
04187 fPrintf("UNKNOWN COMMAND IGNORED:%s", (const char*)comand);
04188
04189 ierflg = 3;
04190
04191 return;
04192
04193
04194
04195 L90:
04196
04197 if (fCword(0,4) == "MINO") i = 5;
04198
04199 if (i != 6 && i != 7 && i != 8 && i != 23) {
04200
04201 fCfrom = cname[i-1];
04202
04203 fNfcnfr = fNfcn;
04204
04205 }
04206
04207
04208
04209 switch (i) {
04210
04211 case 1: goto L400;
04212
04213 case 2: goto L200;
04214
04215 case 3: goto L300;
04216
04217 case 4: goto L400;
04218
04219 case 5: goto L500;
04220
04221 case 6: goto L700;
04222
04223 case 7: goto L700;
04224
04225 case 8: goto L800;
04226
04227 case 9: goto L900;
04228
04229 case 10: goto L1000;
04230
04231 case 11: goto L1100;
04232
04233 case 12: goto L1200;
04234
04235 case 13: goto L1300;
04236
04237 case 14: goto L1400;
04238
04239 case 15: goto L1500;
04240
04241 case 16: goto L1600;
04242
04243 case 17: goto L1700;
04244
04245 case 18: goto L1800;
04246
04247 case 19: goto L1900;
04248
04249 case 20: goto L1900;
04250
04251 case 21: goto L1900;
04252
04253 case 22: goto L2200;
04254
04255 case 23: goto L2300;
04256
04257 case 24: goto L2400;
04258
04259 case 25: goto L1900;
04260
04261 case 26: goto L2600;
04262
04263 case 27: goto L3300;
04264
04265 case 28: goto L3300;
04266
04267 case 29: goto L3300;
04268
04269 case 30: goto L3300;
04270
04271 case 31: goto L3300;
04272
04273 case 32: goto L3300;
04274
04275 case 33: goto L3300;
04276
04277 case 34: goto L3400;
04278
04279 case 35: goto L3500;
04280
04281 case 36: goto L3600;
04282
04283 case 37: goto L3700;
04284
04285 case 38: goto L3800;
04286
04287 case 39: goto L3900;
04288
04289 case 40: goto L4000;
04290
04291 }
04292
04293
04294
04295 L200:
04296
04297 mnseek();
04298
04299 return;
04300
04301
04302
04303 L300:
04304
04305 mnsimp();
04306
04307 if (fISW[3] < 1) ierflg = 4;
04308
04309 return;
04310
04311
04312
04313 L400:
04314
04315 nf = fNfcn;
04316
04317 fApsi = fEpsi;
04318
04319 mnmigr();
04320
04321 mnwerr();
04322
04323 if (fISW[3] >= 1) return;
04324
04325 ierflg = 4;
04326
04327 if (fISW[0] == 1) return;
04328
04329 if (fCword(0,3) == "MIG") return;
04330
04331
04332
04333 fNfcnmx = fNfcnmx + nf - fNfcn;
04334
04335 nf = fNfcn;
04336
04337 mnsimp();
04338
04339 if (fISW[0] == 1) return;
04340
04341 fNfcnmx = fNfcnmx + nf - fNfcn;
04342
04343 mnmigr();
04344
04345 if (fISW[3] >= 1) ierflg = 0;
04346
04347 mnwerr();
04348
04349 return;
04350
04351
04352
04353 L500:
04354
04355 nsuper = fNfcn + ((fNpar + 1) << 1)*fNfcnmx;
04356
04357
04358
04359 fEpsi = fUp*.1;
04360
04361 L510:
04362
04363 mncuve();
04364
04365 mnmnos();
04366
04367 if (! fLnewmn) return;
04368
04369 mnrset(0);
04370
04371 mnmigr();
04372
04373 mnwerr();
04374
04375 if (fNfcn < nsuper) goto L510;
04376
04377 fPrintf(" TOO MANY FUNCTION CALLS. MINOS GIVES UP");
04378
04379 ierflg = 4;
04380
04381 return;
04382
04383
04384
04385 L700:
04386
04387 mnset();
04388
04389 return;
04390
04391
04392
04393
04394
04395 L800:
04396
04397 fPrintf("1");
04398
04399 return;
04400
04401
04402
04403 L900:
04404
04405 ltofix = kTRUE;
04406
04407
04408
04409 L901:
04410
04411 lfreed = kFALSE;
04412
04413 lfixed = kFALSE;
04414
04415 if (llist == 0) {
04416
04417 fPrintf("%s: NO PARAMETERS REQUESTED ",(const char*)fCword);
04418
04419 return;
04420
04421 }
04422
04423 for (ilist = 1; ilist <= llist; ++ilist) {
04424
04425 iext = MInt(plist[ilist-1]);
04426
04427 chwhy = " IS UNDEFINED.";
04428
04429 if (iext <= 0) goto L930;
04430
04431 if (iext > fNu) goto L930;
04432
04433 if (fNvarl[iext-1] < 0) goto L930;
04434
04435 chwhy = " IS CONSTANT. ";
04436
04437 if (fNvarl[iext-1] == 0) goto L930;
04438
04439 iint = fNiofex[iext-1];
04440
04441 if (ltofix) {
04442
04443 chwhy = " ALREADY FIXED.";
04444
04445 if (iint == 0) goto L930;
04446
04447 mnfixp(iint-1, ierr);
04448
04449 if (ierr == 0) lfixed = kTRUE;
04450
04451 else ierflg = 4;
04452
04453 } else {
04454
04455 chwhy = " ALREADY VARIABLE.";
04456
04457 if (iint > 0) goto L930;
04458
04459 krl = -abs(iext);
04460
04461 mnfree(krl);
04462
04463 lfreed = kTRUE;
04464
04465 }
04466
04467 continue;
04468
04469 L930:
04470
04471 fPrintf(" PARAMETER%4d %s IGNORED.",iext,(const char*)chwhy);
04472
04473 }
04474
04475 if (lfreed || lfixed) mnrset(0);
04476
04477 if (lfreed) {
04478
04479 fISW[1] = 0;
04480
04481 fDcovar = 1;
04482
04483 fEDM = fBigedm;
04484
04485 fISW[3] = 0;
04486
04487 }
04488
04489 mnwerr();
04490
04491 if (fISW[4] > 1) mnprin(5, fAmin);
04492
04493 return;
04494
04495
04496
04497 L1000:
04498
04499 it = MInt(fWord7[0]);
04500
04501 if (it > 1 || it < 0) goto L1005;
04502
04503 lfreed = fNpfix > 0;
04504
04505 mnfree(it);
04506
04507 if (lfreed) {
04508
04509 mnrset(0);
04510
04511 fISW[1] = 0;
04512
04513 fDcovar = 1;
04514
04515 fEDM = fBigedm;
04516
04517 }
04518
04519 return;
04520
04521 L1005:
04522
04523 fPrintf(" IGNORED. UNKNOWN ARGUMENT:%4d",it);
04524
04525 ierflg = 3;
04526
04527 return;
04528
04529
04530
04531 L1100:
04532
04533 ltofix = kFALSE;
04534
04535 goto L901;
04536
04537
04538
04539 L1200:
04540
04541 iext = MInt(fWord7[0]);
04542
04543 if (iext <= 0) goto L1210;
04544
04545 it2 = 0;
04546
04547 if (iext <= fNu) it2 = fNiofex[iext-1];
04548
04549 if (it2 <= 0) goto L1250;
04550
04551
04552
04553 L1210:
04554
04555 mnscan();
04556
04557 return;
04558
04559 L1250:
04560
04561 fPrintf(" PARAMETER%4d NOT VARIABLE.",iext);
04562
04563 ierflg = 3;
04564
04565 return;
04566
04567
04568
04569 L1300:
04570
04571 ke1 = MInt(fWord7[0]);
04572
04573 ke2 = MInt(fWord7[1]);
04574
04575 if (ke1 == 0) {
04576
04577 if (fNpar == 2) {
04578
04579 ke1 = fNexofi[0];
04580
04581 ke2 = fNexofi[1];
04582
04583 } else {
04584
04585 fPrintf("%s: NO PARAMETERS REQUESTED ",(const char*)fCword);
04586
04587 ierflg = 3;
04588
04589 return;
04590
04591 }
04592
04593 }
04594
04595 fNfcnmx = 1000;
04596
04597 mncntr(ke1, ke2, ierrf);
04598
04599 if (ierrf > 0) ierflg = 3;
04600
04601 return;
04602
04603
04604
04605 L1400:
04606
04607 mnhess();
04608
04609 mnwerr();
04610
04611 if (fISW[4] >= 0) mnprin(2, fAmin);
04612
04613 if (fISW[4] >= 1) mnmatu(1);
04614
04615 return;
04616
04617
04618
04619 L1500:
04620
04621 mnsave();
04622
04623 return;
04624
04625
04626
04627 L1600:
04628
04629 mncuve();
04630
04631 mnimpr();
04632
04633 if (fLnewmn) goto L400;
04634
04635 ierflg = 4;
04636
04637 return;
04638
04639
04640
04641 L1700:
04642
04643 iflag = MInt(fWord7[0]);
04644
04645 nparx = fNpar;
04646
04647 f = fUndefi;
04648
04649 (*fFCN)(nparx, fGin, f, fU, iflag); ++fNfcn;
04650
04651 nowprt = 0;
04652
04653 if (f != fUndefi) {
04654
04655 if (fAmin == fUndefi) {
04656
04657 fAmin = f;
04658
04659 nowprt = 1;
04660
04661 } else if (f < fAmin) {
04662
04663 fAmin = f;
04664
04665 nowprt = 1;
04666
04667 }
04668
04669 if (fISW[4] >= 0 && iflag <= 5 && nowprt == 1) {
04670
04671 mnprin(5, fAmin);
04672
04673 }
04674
04675 if (iflag == 3) fFval3 = f;
04676
04677 }
04678
04679 if (iflag > 5) mnrset(1);
04680
04681 return;
04682
04683
04684
04685 L1800:
04686
04687
04688
04689 return;
04690
04691
04692
04693 L1900:
04694
04695 it = MInt(fWord7[0]);
04696
04697 if (fFval3 != fAmin && it == 0) {
04698
04699 iflag = 3;
04700
04701 fPrintf(" CALL TO USER FUNCTION WITH IFLAG = 3");
04702
04703 nparx = fNpar;
04704
04705 (*fFCN)(nparx, fGin, f, fU, iflag); ++fNfcn;
04706
04707 }
04708
04709 ierflg = 11;
04710
04711 if (fCword(0,3) == "END") ierflg = 10;
04712
04713 if (fCword(0,3) == "RET") ierflg = 12;
04714
04715 return;
04716
04717
04718
04719 L2200:
04720
04721 mncler();
04722
04723 if (fISW[4] >= 1) {
04724
04725 fPrintf(" MINUIT MEMORY CLEARED. NO PARAMETERS NOW DEFINED.");
04726
04727 }
04728
04729 return;
04730
04731
04732
04733 L2300:
04734
04735 kcol = 0;
04736
04737 for (icol = 5; icol <= lk; ++icol) {
04738
04739 if (fCword[icol-1] == ' ') continue;
04740
04741 kcol = icol;
04742
04743 goto L2320;
04744
04745 }
04746
04747 L2320:
04748
04749 if (kcol == 0) comd = "* ";
04750
04751 else comd = fCword[kcol-1];
04752
04753 mnhelp(comd);
04754
04755 return;
04756
04757
04758
04759 L2400:
04760
04761 fEpsi = fUp*.05;
04762
04763 ke1 = MInt(fWord7[0]);
04764
04765 ke2 = MInt(fWord7[1]);
04766
04767 if (ke1 == 0 && fNpar == 2) {
04768
04769 ke1 = fNexofi[0];
04770
04771 ke2 = fNexofi[1];
04772
04773 }
04774
04775 nptu = MInt(fWord7[2]);
04776
04777 if (nptu <= 0) nptu = 20;
04778
04779 if (nptu > 101) nptu = 101;
04780
04781 fNfcnmx = (nptu + 5)*100*(fNpar + 1);
04782
04783 mncont(ke1, ke2, nptu, xptu, yptu, ierrf);
04784
04785 if (ierrf < nptu) ierflg = 4;
04786
04787 if (ierrf == -1) ierflg = 3;
04788
04789 return;
04790
04791
04792
04793 L2600:
04794
04795 step = fWord7[0];
04796
04797 if (step <= 0) step = 2;
04798
04799 rno = 0;
04800
04801 izero = 0;
04802
04803 for (i = 1; i <= fNpar; ++i) {
04804
04805 mnrn15(rno, izero);
04806
04807 rno = rno*2 - 1;
04808
04809 fX[i-1] += rno*step*fWerr[i-1];
04810
04811 }
04812
04813 mninex(fX);
04814
04815 mnamin();
04816
04817 mnrset(0);
04818
04819 return;
04820
04821
04822
04823 L3300:
04824
04825 fPrintf(" BLANK COMMAND IGNORED.");
04826
04827 ierflg = 1;
04828
04829 return;
04830
04831
04832
04833
04834
04835 L3400:
04836
04837 fPrintf(" 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*");
04838
04839 ierflg = 3;
04840
04841 return;
04842
04843
04844
04845 L3500:
04846
04847 cneway = "SET PRInt ";
04848
04849 goto L3100;
04850
04851
04852
04853 L3600:
04854
04855 cneway = "SET GRAd ";
04856
04857 goto L3100;
04858
04859
04860
04861 L3700:
04862
04863 cneway = "SHOW COVar";
04864
04865 goto L3100;
04866
04867
04868
04869 L3800:
04870
04871 cneway = "SET ERRdef";
04872
04873 goto L3100;
04874
04875
04876
04877 L3900:
04878
04879 cneway = "SET LIMits";
04880
04881 goto L3100;
04882
04883
04884
04885 L4000:
04886
04887 cneway = "SAVE ";
04888
04889
04890
04891 L3100:
04892
04893 fPrintf(" OBSOLETE COMMAND:%s PLEASE USE: %s",(const char*)fCword
04894
04895 ,(const char*)cneway);
04896
04897 fCword = cneway;
04898
04899 if (fCword == "SAVE ") goto L1500;
04900
04901 goto L700;
04902
04903
04904
04905 }
04906
04907
04908
04909
04910
04911 void Midnight::mnexin(MDouble *pint)
04912
04913 {
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925
04926
04927 static MDouble pinti;
04928
04929 static MInt iint, iext;
04930
04931
04932
04933 fLimset = kFALSE;
04934
04935 for (iint = 1; iint <= fNpar; ++iint) {
04936
04937 iext = fNexofi[iint-1];
04938
04939 mnpint(fU[iext-1], iext-1, pinti);
04940
04941 pint[iint-1] = pinti;
04942
04943 }
04944
04945 }
04946
04947
04948
04949
04950
04951 void Midnight::mnfixp(MInt iint1, MInt &ierr)
04952
04953 {
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967 static MDouble yy[kMAXDIM], yyover;
04968
04969 static MInt kold, nold, ndex, knew, iext, i, j, m, n, lc, ik;
04970
04971
04972
04973
04974
04975 ierr = 0;
04976
04977 MInt iint = iint1+1;
04978
04979 if (iint > fNpar || iint <= 0) {
04980
04981 ierr = 1;
04982
04983 fPrintf(" MINUIT ERROR. ARGUMENT TO MNFIXP=%4d",iint);
04984
04985 return;
04986
04987 }
04988
04989 iext = fNexofi[iint-1];
04990
04991 if (fNpfix >= fMaxpar) {
04992
04993 ierr = 1;
04994
04995 fPrintf(" MINUIT CANNOT FIX PARAMETER%4d MAXIMUM NUMBER THAT CAN BE FIXED IS %d",iext,fMaxpar);
04996
04997 return;
04998
04999 }
05000
05001
05002
05003
05004
05005 fNiofex[iext-1] = 0;
05006
05007 nold = fNpar;
05008
05009 --fNpar;
05010
05011
05012
05013
05014
05015 ++fNpfix;
05016
05017 fIpfix[fNpfix-1] = iext;
05018
05019 lc = iint;
05020
05021 fXs[fNpfix-1] = fX[lc-1];
05022
05023 fXts[fNpfix-1] = fXt[lc-1];
05024
05025 fDirins[fNpfix-1] = fWerr[lc-1];
05026
05027 fGrds[fNpfix-1] = fGrd[lc-1];
05028
05029 fG2s[fNpfix-1] = fG2[lc-1];
05030
05031 fGsteps[fNpfix-1] = fGstep[lc-1];
05032
05033
05034
05035 for (ik = iext + 1; ik <= fNu; ++ik) {
05036
05037 if (fNiofex[ik-1] > 0) {
05038
05039 lc = fNiofex[ik-1] - 1;
05040
05041 fNiofex[ik-1] = lc;
05042
05043 fNexofi[lc-1] = ik;
05044
05045 fX[lc-1] = fX[lc];
05046
05047 fXt[lc-1] = fXt[lc];
05048
05049 fDirin[lc-1] = fDirin[lc];
05050
05051 fWerr[lc-1] = fWerr[lc];
05052
05053 fGrd[lc-1] = fGrd[lc];
05054
05055 fG2[lc-1] = fG2[lc];
05056
05057 fGstep[lc-1] = fGstep[lc];
05058
05059 }
05060
05061 }
05062
05063 if (fISW[1] <= 0) return;
05064
05065
05066
05067 if (fNpar <= 0) return;
05068
05069 for (i = 1; i <= nold; ++i) {
05070
05071 m = TMath_Max(i,iint);
05072
05073 n = TMath_Min(i,iint);
05074
05075 ndex = m*(m-1) / 2 + n;
05076
05077 yy[i-1] = fVhmat[ndex-1];
05078
05079 }
05080
05081 yyover = 1 / yy[iint-1];
05082
05083 knew = 0;
05084
05085 kold = 0;
05086
05087 for (i = 1; i <= nold; ++i) {
05088
05089 for (j = 1; j <= i; ++j) {
05090
05091 ++kold;
05092
05093 if (j == iint || i == iint) continue;
05094
05095 ++knew;
05096
05097 fVhmat[knew-1] = fVhmat[kold-1] - yy[j-1]*yy[i-1]*yyover;
05098
05099 }
05100
05101 }
05102
05103 }
05104
05105
05106
05107
05108
05109 void Midnight::mnfree(MInt k)
05110
05111 {
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143 static MDouble grdv, xv, dirinv, g2v, gstepv, xtv;
05144
05145 static MInt i, ipsav, ka, lc, ik, iq, ir, is;
05146
05147
05148
05149 if (k > 1) {
05150
05151 fPrintf(" CALL TO MNFREE IGNORED. ARGUMENT GREATER THAN ONE");
05152
05153 }
05154
05155 if (fNpfix < 1) {
05156
05157 fPrintf(" CALL TO MNFREE IGNORED. THERE ARE NO FIXED PARAMETERS");
05158
05159 }
05160
05161 if (k == 1 || k == 0) goto L40;
05162
05163
05164
05165
05166
05167 ka = abs(k);
05168
05169 if (fNiofex[ka-1] == 0) goto L15;
05170
05171 fPrintf(" IGNORED. PARAMETER SPECIFIED IS ALREADY VARIABLE.");
05172
05173 return;
05174
05175 L15:
05176
05177 if (fNpfix < 1) goto L21;
05178
05179 for (ik = 1; ik <= fNpfix; ++ik) { if (fIpfix[ik-1] == ka) goto L24; }
05180
05181 L21:
05182
05183 fPrintf(" PARAMETER%4d NOT FIXED. CANNOT BE RELEASED.",ka);
05184
05185 return;
05186
05187 L24:
05188
05189 if (ik == fNpfix) goto L40;
05190
05191
05192
05193
05194
05195 ipsav = ka;
05196
05197 xv = fXs[ik-1];
05198
05199 xtv = fXts[ik-1];
05200
05201 dirinv = fDirins[ik-1];
05202
05203 grdv = fGrds[ik-1];
05204
05205 g2v = fG2s[ik-1];
05206
05207 gstepv = fGsteps[ik-1];
05208
05209 for (i = ik + 1; i <= fNpfix; ++i) {
05210
05211 fIpfix[i-2] = fIpfix[i-1];
05212
05213 fXs[i-2] = fXs[i-1];
05214
05215 fXts[i-2] = fXts[i-1];
05216
05217 fDirins[i-2] = fDirins[i-1];
05218
05219 fGrds[i-2] = fGrds[i-1];
05220
05221 fG2s[i-2] = fG2s[i-1];
05222
05223 fGsteps[i-2] = fGsteps[i-1];
05224
05225 }
05226
05227 fIpfix[fNpfix-1] = ipsav;
05228
05229 fXs[fNpfix-1] = xv;
05230
05231 fXts[fNpfix-1] = xtv;
05232
05233 fDirins[fNpfix-1] = dirinv;
05234
05235 fGrds[fNpfix-1] = grdv;
05236
05237 fG2s[fNpfix-1] = g2v;
05238
05239 fGsteps[fNpfix-1] = gstepv;
05240
05241
05242
05243 L40:
05244
05245 if (fNpfix < 1) goto L300;
05246
05247 ir = fIpfix[fNpfix-1];
05248
05249 is = 0;
05250
05251 for (ik = fNu; ik >= ir; --ik) {
05252
05253 if (fNiofex[ik-1] > 0) {
05254
05255 lc = fNiofex[ik-1] + 1;
05256
05257 is = lc - 1;
05258
05259 fNiofex[ik-1] = lc;
05260
05261 fNexofi[lc-1] = ik;
05262
05263 fX[lc-1] = fX[lc-2];
05264
05265 fXt[lc-1] = fXt[lc-2];
05266
05267 fDirin[lc-1] = fDirin[lc-2];
05268
05269 fWerr[lc-1] = fWerr[lc-2];
05270
05271 fGrd[lc-1] = fGrd[lc-2];
05272
05273 fG2[lc-1] = fG2[lc-2];
05274
05275 fGstep[lc-1] = fGstep[lc-2];
05276
05277 }
05278
05279 }
05280
05281 ++fNpar;
05282
05283 if (is == 0) is = fNpar;
05284
05285 fNiofex[ir-1] = is;
05286
05287 fNexofi[is-1] = ir;
05288
05289 iq = fNpfix;
05290
05291 fX[is-1] = fXs[iq-1];
05292
05293 fXt[is-1] = fXts[iq-1];
05294
05295 fDirin[is-1] = fDirins[iq-1];
05296
05297 fWerr[is-1] = fDirins[iq-1];
05298
05299 fGrd[is-1] = fGrds[iq-1];
05300
05301 fG2[is-1] = fG2s[iq-1];
05302
05303 fGstep[is-1] = fGsteps[iq-1];
05304
05305 --fNpfix;
05306
05307 fISW[1] = 0;
05308
05309 fDcovar = 1;
05310
05311 if (fISW[4] - fItaur >= 1) {
05312
05313 fPrintf(" PARAMETER%4d %s RESTORED TO VARIABLE.",ir,
05314
05315 (const char*)fCpnam[ir-1]);
05316
05317 }
05318
05319 if (k == 0) goto L40;
05320
05321 L300:
05322
05323
05324
05325 mnexin(fX);
05326
05327 }
05328
05329
05330
05331
05332
05333 void Midnight::mngrad()
05334
05335 {
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357 static MDouble gf[kMAXDIM], fzero, err;
05358
05359 static MInt i, nparx, lc, istsav;
05360
05361 static MBool lnone;
05362
05363 static MString cwd = " ";
05364
05365
05366
05367 fISW[2] = 1;
05368
05369 nparx = fNpar;
05370
05371 if (fWord7[0] > 0) goto L2000;
05372
05373
05374
05375
05376
05377 for (i = 1; i <= fNu; ++i) { fGin[i-1] = fUndefi; }
05378
05379 mninex(fX);
05380
05381 (*fFCN)(nparx, fGin, fzero, fU, 2); ++fNfcn;
05382
05383 mnderi();
05384
05385 for (i = 1; i <= fNpar; ++i) { gf[i-1] = fGrd[i-1]; }
05386
05387
05388
05389 fISW[2] = 0;
05390
05391 istsav = fIstrat;
05392
05393 fIstrat = 2;
05394
05395 mnhes1();
05396
05397 fIstrat = istsav;
05398
05399 fPrintf(" CHECK OF GRADIENT CALCULATION IN FCN");
05400
05401 fPrintf(" PARAMETER G(IN FCN) G(MINUIT) DG(MINUIT) AGREEMENT");
05402
05403 fISW[2] = 1;
05404
05405 lnone = kFALSE;
05406
05407 for (lc = 1; lc <= fNpar; ++lc) {
05408
05409 i = fNexofi[lc-1];
05410
05411 cwd = "GOOD";
05412
05413 err = fDgrd[lc-1];
05414
05415 if (TMath_Abs(gf[lc-1] - fGrd[lc-1]) > err) cwd = " BAD";
05416
05417 if (fGin[i-1] == fUndefi) {
05418
05419 cwd = "NONE";
05420
05421 lnone = kTRUE;
05422
05423 gf[lc-1] = 0;
05424
05425 }
05426
05427 if (cwd != "GOOD") fISW[2] = 0;
05428
05429 fPrintf(" %5d %10s%12.4e%12.4e%12.4e %s",i
05430
05431 ,(const char*)fCpnam[i-1]
05432
05433 ,gf[lc-1],fGrd[lc-1],err,(const char*)cwd);
05434
05435 }
05436
05437 if (lnone) {
05438
05439 fPrintf(" AGREEMENT=NONE MEANS FCN DID NOT CALCULATE THE DERIVATIVE");
05440
05441 }
05442
05443 if (fISW[2] == 0) {
05444
05445 fPrintf(" MINUIT DOES NOT ACCEPT DERIVATIVE CALCULATIONS BY FCN");
05446
05447 fPrintf(" TO FORCE ACCEPTANCE, ENTER *SET GRAD 1*");
05448
05449 }
05450
05451
05452
05453 L2000:
05454
05455 return;
05456
05457 }
05458
05459
05460
05461
05462
05463 void Midnight::mnhelp(MString comd)
05464
05465 {
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497 static MString cmd3 = " ";
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511 if (comd[0] == '*') {
05512
05513 fPrintf(" ==>List of MINUIT Interactive commands:");
05514
05515 fPrintf(" CLEar Reset all parameter names and values undefined");
05516
05517 fPrintf(" CONtour Make contour map of the user function");
05518
05519 fPrintf(" EXIT Exit from Interactive Minuit");
05520
05521 fPrintf(" FIX Cause parameter(s) to remain constant");
05522
05523 fPrintf(" HESse Calculate the Hessian or error matrix.");
05524
05525 fPrintf(" IMPROVE Search for a new minimum around current minimum");
05526
05527 fPrintf(" MIGrad Minimize by the method of Migrad");
05528
05529 fPrintf(" MINImize MIGRAD + SIMPLEX method if Migrad fails");
05530
05531 fPrintf(" MINOs Exact (non-linear) parameter error analysis");
05532
05533 fPrintf(" MNContour Calculate one MINOS function contour");
05534
05535 fPrintf(" PARameter Define or redefine new parameters and values");
05536
05537 fPrintf(" RELease Make previously FIXed parameters variable again");
05538
05539 fPrintf(" REStore Release last parameter fixed");
05540
05541 fPrintf(" SAVe Save current parameter values on a file");
05542
05543 fPrintf(" SCAn Scan the user function by varying parameters");
05544
05545 fPrintf(" SEEk Minimize by the method of Monte Carlo");
05546
05547 fPrintf(" SET Set various MINUIT constants or conditions");
05548
05549 fPrintf(" SHOw Show values of current constants or conditions");
05550
05551 fPrintf(" SIMplex Minimize by the method of Simplex");
05552
05553 goto L99;
05554
05555 }
05556
05557
05558
05559 cmd3 = comd;
05560
05561
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571 if (cmd3 == "CLE") {
05572
05573 fPrintf(" ***>CLEAR");
05574
05575 fPrintf(" Resets all parameter names and values to undefined.");
05576
05577 fPrintf(" Must normally be followed by a PARameters command or ");
05578
05579 fPrintf(" equivalent, in order to define parameter values.");
05580
05581 goto L99;
05582
05583 }
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595 if (cmd3 == "CON") {
05596
05597 fPrintf(" ***>CONTOUR <par1> <par2> [devs] [ngrid]");
05598
05599 fPrintf(" Instructs Minuit to trace contour lines of the user function");
05600
05601 fPrintf(" with respect to the two parameters whose external numbers");
05602
05603 fPrintf(" are <par1> and <par2>.");
05604
05605 fPrintf(" Other variable parameters of the function, if any, will have");
05606
05607 fPrintf(" their values fixed at the current values during the contour");
05608
05609 fPrintf(" tracing. The optional parameter [devs] (default value 2.)");
05610
05611 fPrintf(" gives the number of standard deviations in each parameter");
05612
05613 fPrintf(" which should lie entirely within the plotting area.");
05614
05615 fPrintf(" Optional parameter [ngrid] (default value 25 unless page");
05616
05617 fPrintf(" size is too small) determines the resolution of the plot,");
05618
05619 fPrintf(" i.e. the number of rows and columns of the grid at which the");
05620
05621 fPrintf(" function will be evaluated. [See also MNContour.]");
05622
05623 goto L99;
05624
05625 }
05626
05627
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637 if (cmd3 == "END") {
05638
05639 fPrintf(" ***>END");
05640
05641 fPrintf(" Signals the end of a data block (i.e., the end of a fit),");
05642
05643 fPrintf(" and implies that execution should continue, because another");
05644
05645 fPrintf(" Data Block follows. A Data Block is a set of Minuit data");
05646
05647 fPrintf(" consisting of");
05648
05649 fPrintf(" (1) A Title,");
05650
05651 fPrintf(" (2) One or more Parameter Definitions,");
05652
05653 fPrintf(" (3) A blank line, and");
05654
05655 fPrintf(" (4) A set of Minuit Commands.");
05656
05657 fPrintf(" The END command is used when more than one Data Block is to");
05658
05659 fPrintf(" be used with the same FCN function. It first causes Minuit");
05660
05661 fPrintf(" to issue a CALL FCN with IFLAG=3, in order to allow FCN to");
05662
05663 fPrintf(" perform any calculations associated with the final fitted");
05664
05665 fPrintf(" parameter values, unless a CALL FCN 3 command has already");
05666
05667 fPrintf(" been executed at the current FCN value.");
05668
05669 goto L99;
05670
05671 }
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683 if (cmd3 == "EXI") {
05684
05685 fPrintf(" ***>EXIT");
05686
05687 fPrintf(" Signals the end of execution.");
05688
05689 fPrintf(" The EXIT command first causes Minuit to issue a CALL FCN");
05690
05691 fPrintf(" with IFLAG=3, to allow FCN to perform any calculations");
05692
05693 fPrintf(" associated with the final fitted parameter values, unless a");
05694
05695 fPrintf(" CALL FCN 3 command has already been executed.");
05696
05697 goto L99;
05698
05699 }
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711 if (cmd3 == "FIX") {
05712
05713 fPrintf(" ***>FIX} <parno> [parno] ... [parno]");
05714
05715 fPrintf(" Causes parameter(s) <parno> to be removed from the list of");
05716
05717 fPrintf(" variable parameters, and their value(s) will remain constant");
05718
05719 fPrintf(" during subsequent minimizations, etc., until another command");
05720
05721 fPrintf(" changes their value(s) or status.");
05722
05723 goto L99;
05724
05725 }
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737 if (cmd3 == "HES") {
05738
05739 fPrintf(" ***>HESse [maxcalls]");
05740
05741 fPrintf(" Calculate, by finite differences, the Hessian or error matrix.");
05742
05743 fPrintf(" That is, it calculates the full matrix of second derivatives");
05744
05745 fPrintf(" of the function with respect to the currently variable");
05746
05747 fPrintf(" parameters, and inverts it, printing out the resulting error");
05748
05749 fPrintf(" matrix. The optional argument [maxcalls] specifies the");
05750
05751 fPrintf(" (approximate) maximum number of function calls after which");
05752
05753 fPrintf(" the calculation will be stopped.");
05754
05755 goto L99;
05756
05757 }
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769 if (cmd3 == "IMP") {
05770
05771 fPrintf(" ***>IMPROVE [maxcalls]");
05772
05773 fPrintf(" If a previous minimization has converged, and the current");
05774
05775 fPrintf(" values of the parameters therefore correspond to a local");
05776
05777 fPrintf(" minimum of the function, this command requests a search for");
05778
05779 fPrintf(" additional distinct local minima.");
05780
05781 fPrintf(" The optional argument [maxcalls] specifies the (approximate");
05782
05783 fPrintf(" maximum number of function calls after which the calculation");
05784
05785 fPrintf(" will be stopped.");
05786
05787 goto L99;
05788
05789 }
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800
05801 if (cmd3 == "MIG") {
05802
05803 fPrintf(" ***>MIGrad [maxcalls] [tolerance]");
05804
05805 fPrintf(" Causes minimization of the function by the method of Migrad,");
05806
05807 fPrintf(" the most efficient and complete single method, recommended");
05808
05809 fPrintf(" for general functions (see also MINImize).");
05810
05811 fPrintf(" The minimization produces as a by-product the error matrix");
05812
05813 fPrintf(" of the parameters, which is usually reliable unless warning");
05814
05815 fPrintf(" messages are produced.");
05816
05817 fPrintf(" The optional argument [maxcalls] specifies the (approximate)");
05818
05819 fPrintf(" maximum number of function calls after which the calculation");
05820
05821 fPrintf(" will be stopped even if it has not yet converged.");
05822
05823 fPrintf(" The optional argument [tolerance] specifies required tolerance");
05824
05825 fPrintf(" on the function value at the minimum.");
05826
05827 fPrintf(" The default tolerance is 0.1, and the minimization will stop");
05828
05829 fPrintf(" when the estimated vertical distance to the minimum (EDM) is");
05830
05831 fPrintf(" less than 0.001*[tolerance]*UP (see [SET ERRordef]).");
05832
05833 goto L99;
05834
05835 }
05836
05837
05838
05839
05840
05841
05842
05843
05844
05845
05846
05847 if (comd == "MINI") {
05848
05849 fPrintf(" ***>MINImize [maxcalls] [tolerance]");
05850
05851 fPrintf(" Causes minimization of the function by the method of Migrad,");
05852
05853 fPrintf(" as does the MIGrad command, but switches to the SIMplex method");
05854
05855 fPrintf(" if Migrad fails to converge. Arguments are as for MIGrad.");
05856
05857 fPrintf(" Note that command requires four characters to be unambiguous.");
05858
05859 goto L99;
05860
05861 }
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873 if (comd == "MINO") {
05874
05875 fPrintf(" ***>MINOs [maxcalls] [parno] [parno] ...");
05876
05877 fPrintf(" Causes a Minos error analysis to be performed on the parameters");
05878
05879 fPrintf(" whose numbers [parno] are specified. If none are specified,");
05880
05881 fPrintf(" Minos errors are calculated for all variable parameters.");
05882
05883 fPrintf(" Minos errors may be expensive to calculate, but are very");
05884
05885 fPrintf(" reliable since they take account of non-linearities in the");
05886
05887 fPrintf(" problem as well as parameter correlations, and are in general");
05888
05889 fPrintf(" asymmetric.");
05890
05891 fPrintf(" The optional argument [maxcalls] specifies the (approximate)");
05892
05893 fPrintf(" maximum number of function calls per parameter requested,");
05894
05895 fPrintf(" after which the calculation will stop for that parameter.");
05896
05897 goto L99;
05898
05899 }
05900
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911 if (cmd3 == "MNC") {
05912
05913 fPrintf(" ***>MNContour <par1> <par2> [npts]");
05914
05915 fPrintf(" Calculates one function contour of FCN with respect to");
05916
05917 fPrintf(" parameters par1 and par2, with FCN minimized always with");
05918
05919 fPrintf(" respect to all other NPAR-2 variable parameters (if any).");
05920
05921 fPrintf(" Minuit will try to find npts points on the contour (default 20)");
05922
05923 fPrintf(" If only two parameters are variable at the time, it is not");
05924
05925 fPrintf(" necessary to specify their numbers. To calculate more than");
05926
05927 fPrintf(" one contour, it is necessary to SET ERRordef to the appropriate");
05928
05929 fPrintf(" value and issue the MNContour command for each contour.");
05930
05931 goto L99;
05932
05933 }
05934
05935
05936
05937
05938
05939
05940
05941
05942
05943
05944
05945 if (cmd3 == "PAR") {
05946
05947 fPrintf(" ***>PARameters");
05948
05949 fPrintf(" followed by one or more parameter definitions.");
05950
05951 fPrintf(" Parameter definitions are of the form:");
05952
05953 fPrintf(" <number> ''name'' <value> <step> [lolim] [uplim] ");
05954
05955 fPrintf(" for example:");
05956
05957 fPrintf(" 3 ''K width'' 1.2 0.1");
05958
05959 fPrintf(" the last definition is followed by a blank line or a zero.");
05960
05961 goto L99;
05962
05963 }
05964
05965
05966
05967
05968
05969
05970
05971
05972
05973
05974
05975 if (cmd3 == "REL") {
05976
05977 fPrintf(" ***>RELease <parno> [parno] ... [parno]");
05978
05979 fPrintf(" If <parno> is the number of a previously variable parameter");
05980
05981 fPrintf(" which has been fixed by a command: FIX <parno>, then that");
05982
05983 fPrintf(" parameter will return to variable status. Otherwise a warning");
05984
05985 fPrintf(" message is printed and the command is ignored.");
05986
05987 fPrintf(" Note that this command operates only on parameters which were");
05988
05989 fPrintf(" at one time variable and have been FIXed. It cannot make");
05990
05991 fPrintf(" constant parameters variable; that must be done by redefining");
05992
05993 fPrintf(" the parameter with a PARameters command.");
05994
05995 goto L99;
05996
05997 }
05998
05999
06000
06001
06002
06003
06004
06005
06006
06007
06008
06009 if (cmd3 == "RES") {
06010
06011 fPrintf(" ***>REStore [code]");
06012
06013 fPrintf(" If no [code] is specified, this command restores all previously");
06014
06015 fPrintf(" FIXed parameters to variable status. If [code]=1, then only");
06016
06017 fPrintf(" the last parameter FIXed is restored to variable status.");
06018
06019 fPrintf(" If code is neither zero nor one, the command is ignored.");
06020
06021 goto L99;
06022
06023 }
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035 if (cmd3 == "RET") {
06036
06037 fPrintf(" ***>RETURN");
06038
06039 fPrintf(" Signals the end of a data block, and instructs Minuit to return");
06040
06041 fPrintf(" to the program which called it. The RETurn command first");
06042
06043 fPrintf(" causes Minuit to CALL FCN with IFLAG=3, in order to allow FCN");
06044
06045 fPrintf(" to perform any calculations associated with the final fitted");
06046
06047 fPrintf(" parameter values, unless a CALL FCN 3 command has already been");
06048
06049 fPrintf(" executed at the current FCN value.");
06050
06051 goto L99;
06052
06053 }
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065 if (cmd3 == "SAV") {
06066
06067 fPrintf(" ***>SAVe");
06068
06069 fPrintf(" Causes the current parameter values to be saved on a file in");
06070
06071 fPrintf(" such a format that they can be read in again as Minuit");
06072
06073 fPrintf(" parameter definitions. If the covariance matrix exists, it is");
06074
06075 fPrintf(" also output in such a format. The unit number is by default 7,");
06076
06077 fPrintf(" or that specified by the user in his call to MINTIO or");
06078
06079 fPrintf(" MNINIT. The user is responsible for opening the file previous");
06080
06081 fPrintf(" to issuing the [SAVe] command (except where this can be done");
06082
06083 fPrintf(" interactively).");
06084
06085 goto L99;
06086
06087 }
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099 if (cmd3 == "SCA") {
06100
06101 fPrintf(" ***>SCAn [parno] [numpts] [from] [to]");
06102
06103 fPrintf(" Scans the value of the user function by varying parameter");
06104
06105 fPrintf(" number [parno], leaving all other parameters fixed at the");
06106
06107 fPrintf(" current value. If [parno] is not specified, all variable");
06108
06109 fPrintf(" parameters are scanned in sequence.");
06110
06111 fPrintf(" The number of points [numpts] in the scan is 40 by default,");
06112
06113 fPrintf(" and cannot exceed 100. The range of the scan is by default");
06114
06115 fPrintf(" 2 standard deviations on each side of the current best value,");
06116
06117 fPrintf(" but can be specified as from [from] to [to].");
06118
06119 fPrintf(" After each scan, if a new minimum is found, the best parameter");
06120
06121 fPrintf(" values are retained as start values for future scans or");
06122
06123 fPrintf(" minimizations. The curve resulting from each scan is plotted");
06124
06125 fPrintf(" on the output unit in order to show the approximate behaviour");
06126
06127 fPrintf(" of the function.");
06128
06129 fPrintf(" This command is not intended for minimization, but is sometimes");
06130
06131 fPrintf(" useful for debugging the user function or finding a");
06132
06133 fPrintf(" reasonable starting point.");
06134
06135 goto L99;
06136
06137 }
06138
06139
06140
06141
06142
06143
06144
06145
06146
06147
06148
06149 if (cmd3 == "SEE") {
06150
06151 fPrintf(" ***>SEEk [maxcalls] [devs]");
06152
06153 fPrintf(" Causes a Monte Carlo minimization of the function, by choosing");
06154
06155 fPrintf(" random values of the variable parameters, chosen uniformly");
06156
06157 fPrintf(" over a hypercube centered at the current best value.");
06158
06159 fPrintf(" The region size is by default 3 standard deviations on each");
06160
06161 fPrintf(" side, but can be changed by specifying the value of [devs].");
06162
06163 goto L99;
06164
06165 }
06166
06167
06168
06169
06170
06171
06172
06173
06174
06175
06176
06177 if (cmd3 == "SET") {
06178
06179 fPrintf(" ***>SET <option_name>");
06180
06181 fPrintf(" SET BATch");
06182
06183 fPrintf(" Informs Minuit that it is running in batch mode.");
06184
06185
06186
06187 fPrintf(" ");
06188
06189 fPrintf(" SET EPSmachine <accuracy>");
06190
06191 fPrintf(" Informs Minuit that the relative floating point arithmetic");
06192
06193 fPrintf(" precision is <accuracy>. Minuit determines the nominal");
06194
06195 fPrintf(" precision itself, but the SET EPSmachine command can be");
06196
06197 fPrintf(" used to override Minuit own determination, when the user");
06198
06199 fPrintf(" knows that the FCN function value is not calculated to");
06200
06201 fPrintf(" the nominal machine accuracy. Typical values of <accuracy>");
06202
06203 fPrintf(" are between 10**-5 and 10**-14.");
06204
06205
06206
06207 fPrintf(" ");
06208
06209 fPrintf(" SET ERRordef <up>");
06210
06211 fPrintf(" Sets the value of UP (default value= 1.), defining parameter");
06212
06213 fPrintf(" errors. Minuit defines parameter errors as the change");
06214
06215 fPrintf(" in parameter value required to change the function value");
06216
06217 fPrintf(" by UP. Normally, for chisquared fits UP=1, and for negative");
06218
06219 fPrintf(" log likelihood, UP=0.5.");
06220
06221
06222
06223 fPrintf(" ");
06224
06225 fPrintf(" SET GRAdient [force]");
06226
06227 fPrintf(" Informs Minuit that the user function is prepared to");
06228
06229 fPrintf(" calculate its own first derivatives and return their values");
06230
06231 fPrintf(" in the array GRAD when IFLAG=2 (see specs of FCN).");
06232
06233 fPrintf(" If [force] is not specified, Minuit will calculate");
06234
06235 fPrintf(" the FCN derivatives by finite differences at the current");
06236
06237 fPrintf(" point and compare with the user calculation at that point,");
06238
06239 fPrintf(" accepting the user values only if they agree.");
06240
06241 fPrintf(" If [force]=1, Minuit does not do its own derivative");
06242
06243 fPrintf(" calculation, and uses the derivatives calculated in FCN.");
06244
06245
06246
06247 fPrintf(" ");
06248
06249 fPrintf(" SET INPut [unitno] [filename]");
06250
06251 fPrintf(" Causes Minuit, in data-driven mode only, to read subsequent");
06252
06253 fPrintf(" commands (or parameter definitions) from a different input");
06254
06255 fPrintf(" file. If no [unitno] is specified, reading reverts to the");
06256
06257 fPrintf(" previous input file, assuming that there was one.");
06258
06259 fPrintf(" If [unitno] is specified, and that unit has not been opened,");
06260
06261 fPrintf(" then Minuit attempts to open the file [filename]} if a");
06262
06263 fPrintf(" name is specified. If running in interactive mode and");
06264
06265 fPrintf(" [filename] is not specified and [unitno] is not opened,");
06266
06267 fPrintf(" Minuit prompts the user to enter a file name.");
06268
06269 fPrintf(" If the word REWIND is added to the command (note:no blanks");
06270
06271 fPrintf(" between INPUT and REWIND), the file is rewound before");
06272
06273 fPrintf(" reading. Note that this command is implemented in standard");
06274
06275 fPrintf(" Fortran 77 and the results may depend on the system;");
06276
06277 fPrintf(" for example, if a filename is given under VM/CMS, it must");
06278
06279 fPrintf(" be preceeded by a slash.");
06280
06281
06282
06283 fPrintf(" ");
06284
06285 fPrintf(" SET INTeractive");
06286
06287 fPrintf(" Informs Minuit that it is running interactively.");
06288
06289
06290
06291 fPrintf(" ");
06292
06293 fPrintf(" SET LIMits [parno] [lolim] [uplim]");
06294
06295 fPrintf(" Allows the user to change the limits on one or all");
06296
06297 fPrintf(" parameters. If no arguments are specified, all limits are");
06298
06299 fPrintf(" removed from all parameters. If [parno] alone is specified,");
06300
06301 fPrintf(" limits are removed from parameter [parno].");
06302
06303 fPrintf(" If all arguments are specified, then parameter [parno] will");
06304
06305 fPrintf(" be bounded between [lolim] and [uplim].");
06306
06307 fPrintf(" Limits can be specified in either order, Minuit will take");
06308
06309 fPrintf(" the smaller as [lolim] and the larger as [uplim].");
06310
06311 fPrintf(" However, if [lolim] is equal to [uplim], an error condition");
06312
06313 fPrintf(" results.");
06314
06315
06316
06317 fPrintf(" ");
06318
06319 fPrintf(" SET LINesperpage");
06320
06321 fPrintf(" Sets the number of lines for one page of output.");
06322
06323 fPrintf(" Default value is 24 for interactive mode");
06324
06325
06326
06327 fPrintf(" ");
06328
06329 fPrintf(" SET NOGradient");
06330
06331 fPrintf(" The inverse of SET GRAdient, instructs Minuit not to");
06332
06333 fPrintf(" use the first derivatives calculated by the user in FCN.");
06334
06335
06336
06337 fPrintf(" ");
06338
06339 fPrintf(" SET NOWarnings");
06340
06341 fPrintf(" Supresses Minuit warning messages.");
06342
06343
06344
06345 fPrintf(" ");
06346
06347 fPrintf(" SET OUTputfile <unitno>");
06348
06349 fPrintf(" Instructs Minuit to write further output to unit <unitno>.");
06350
06351
06352
06353 fPrintf(" ");
06354
06355 fPrintf(" SET PAGethrow <integer>");
06356
06357 fPrintf(" Sets the carriage control character for ``new page'' to");
06358
06359 fPrintf(" <integer>. Thus the value 1 produces a new page, and 0");
06360
06361 fPrintf(" produces a blank line, on some devices (see TOPofpage)");
06362
06363
06364
06365
06366
06367 fPrintf(" ");
06368
06369 fPrintf(" SET PARameter <parno> <value>");
06370
06371 fPrintf(" Sets the value of parameter <parno> to <value>.");
06372
06373 fPrintf(" The parameter in question may be variable, fixed, or");
06374
06375 fPrintf(" constant, but must be defined.");
06376
06377
06378
06379 fPrintf(" ");
06380
06381 fPrintf(" SET PRIntout <level>");
06382
06383 fPrintf(" Sets the print level, determining how much output will be");
06384
06385 fPrintf(" produced. Allowed values and their meanings are displayed");
06386
06387 fPrintf(" after a SHOw PRInt command, and are currently <level>=:");
06388
06389 fPrintf(" [-1] no output except from SHOW commands");
06390
06391 fPrintf(" [0] minimum output");
06392
06393 fPrintf(" [1] default value, normal output");
06394
06395 fPrintf(" [2] additional output giving intermediate results.");
06396
06397 fPrintf(" [3] maximum output, showing progress of minimizations.");
06398
06399 fPrintf(" Note: See also the SET WARnings command.");
06400
06401
06402
06403 fPrintf(" ");
06404
06405 fPrintf(" SET RANdomgenerator <seed>");
06406
06407 fPrintf(" Sets the seed of the random number generator used in SEEk.");
06408
06409 fPrintf(" This can be any integer between 10000 and 900000000, for");
06410
06411 fPrintf(" example one which was output from a SHOw RANdom command of");
06412
06413 fPrintf(" a previous run.");
06414
06415
06416
06417 fPrintf(" ");
06418
06419 fPrintf(" SET STRategy <level>");
06420
06421 fPrintf(" Sets the strategy to be used in calculating first and second");
06422
06423 fPrintf(" derivatives and in certain minimization methods.");
06424
06425 fPrintf(" In general, low values of <level> mean fewer function calls");
06426
06427 fPrintf(" and high values mean more reliable minimization.");
06428
06429 fPrintf(" Currently allowed values are 0, 1 (default), and 2.");
06430
06431
06432
06433 fPrintf(" ");
06434
06435 fPrintf(" SET TITle");
06436
06437 fPrintf(" Informs Minuit that the next input line is to be considered");
06438
06439 fPrintf(" the (new) title for this task or sub-task. This is for");
06440
06441 fPrintf(" the convenience of the user in reading his output.");
06442
06443
06444
06445 fPrintf(" ");
06446
06447 fPrintf(" SET WARnings");
06448
06449 fPrintf(" Instructs Minuit to output warning messages when suspicious");
06450
06451 fPrintf(" conditions arise which may indicate unreliable results.");
06452
06453 fPrintf(" This is the default.");
06454
06455
06456
06457 fPrintf(" ");
06458
06459 fPrintf(" SET WIDthpage");
06460
06461 fPrintf(" Informs Minuit of the output page width.");
06462
06463 fPrintf(" Default values are 80 for interactive jobs");
06464
06465 goto L99;
06466
06467 }
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479 if (cmd3 == "SHO") {
06480
06481 fPrintf(" ***>SHOw <option_name>");
06482
06483 fPrintf(" All SET XXXX commands have a corresponding SHOw XXXX command.");
06484
06485 fPrintf(" In addition, the SHOw commands listed starting here have no");
06486
06487 fPrintf(" corresponding SET command for obvious reasons.");
06488
06489
06490
06491 fPrintf(" ");
06492
06493 fPrintf(" SHOw CORrelations");
06494
06495 fPrintf(" Calculates and prints the parameter correlations from the");
06496
06497 fPrintf(" error matrix.");
06498
06499
06500
06501 fPrintf(" ");
06502
06503 fPrintf(" SHOw COVariance");
06504
06505 fPrintf(" Prints the (external) covariance (error) matrix.");
06506
06507
06508
06509 fPrintf(" ");
06510
06511 fPrintf(" SHOw EIGenvalues");
06512
06513 fPrintf(" Calculates and prints the eigenvalues of the covariance");
06514
06515 fPrintf(" matrix.");
06516
06517
06518
06519 fPrintf(" ");
06520
06521 fPrintf(" SHOw FCNvalue");
06522
06523 fPrintf(" Prints the current value of FCN.");
06524
06525 goto L99;
06526
06527 }
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539 if (cmd3 == "SIM") {
06540
06541 fPrintf(" ***>SIMplex [maxcalls] [tolerance]");
06542
06543 fPrintf(" Performs a function minimization using the simplex method of");
06544
06545 fPrintf(" Nelder and Mead. Minimization terminates either when the");
06546
06547 fPrintf(" function has been called (approximately) [maxcalls] times,");
06548
06549 fPrintf(" or when the estimated vertical distance to minimum (EDM) is");
06550
06551 fPrintf(" less than [tolerance].");
06552
06553 fPrintf(" The default value of [tolerance] is 0.1*UP(see SET ERRordef).");
06554
06555 goto L99;
06556
06557 }
06558
06559
06560
06561
06562
06563
06564
06565
06566
06567
06568
06569 if (cmd3 == "STA") {
06570
06571 fPrintf(" ***>STAndard");
06572
06573 goto L99;
06574
06575 }
06576
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586
06587 if (cmd3 == "STO") {
06588
06589 fPrintf(" ***>STOP");
06590
06591 fPrintf(" Same as EXIT.");
06592
06593 goto L99;
06594
06595 }
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605
06606
06607 if (cmd3 == "TOP") {
06608
06609 fPrintf(" ***>TOPofpage");
06610
06611 fPrintf(" Causes Minuit to write the character specified in a");
06612
06613 fPrintf(" SET PAGethrow command (default = 1) to column 1 of the output");
06614
06615 fPrintf(" file, which may or may not position your output medium to");
06616
06617 fPrintf(" the top of a page depending on the device and system.");
06618
06619 goto L99;
06620
06621 }
06622
06623
06624
06625 fPrintf(" Unknown MINUIT command. Type HELP for list of commands.");
06626
06627
06628
06629 L99:
06630
06631 return;
06632
06633 }
06634
06635
06636
06637
06638
06639 void Midnight::mnhess()
06640
06641 {
06642
06643
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654
06655
06656
06657
06658
06659
06660
06661
06662
06663 static MDouble dmin_, dxdi, elem, wint, tlrg2, d, dlast, ztemp, g2bfor;
06664
06665 static MDouble yy[kMAXDIM], df, aimsag, fs1, tlrstp, fs2, stpinm, g2i, sag, xtf, xti, xtj;
06666
06667 static MInt icyc, ncyc, ndex, idrv, iext, npar2, i, j, ifail, npard, nparx, id, multpy;
06668
06669 static MBool ldebug;
06670
06671
06672
06673 ldebug = fIdbg[3] >= 1;
06674
06675 if (fAmin == fUndefi) {
06676
06677 mnamin();
06678
06679 }
06680
06681 if (fIstrat <= 0) {
06682
06683 ncyc = 3;
06684
06685 tlrstp = .5;
06686
06687 tlrg2 = .1;
06688
06689 } else if (fIstrat == 1) {
06690
06691 ncyc = 5;
06692
06693 tlrstp = .3;
06694
06695 tlrg2 = .05;
06696
06697 } else {
06698
06699 ncyc = 7;
06700
06701 tlrstp = .1;
06702
06703 tlrg2 = .02;
06704
06705 }
06706
06707 if (fISW[4] >= 2 || ldebug) {
06708
06709 fPrintf(" START COVARIANCE MATRIX CALCULATION.");
06710
06711 }
06712
06713 fCfrom = "HESSE ";
06714
06715 fNfcnfr = fNfcn;
06716
06717 fCstatu = "OK ";
06718
06719 npard = fNpar;
06720
06721
06722
06723 mninex(fX);
06724
06725 nparx = fNpar;
06726
06727 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
06728
06729 if (fs1 != fAmin) {
06730
06731 df = fAmin - fs1;
06732
06733 mnwarn("D", "MNHESS", Form("function value differs from AMIN by %g",df));
06734
06735 }
06736
06737 fAmin = fs1;
06738
06739 if (ldebug) {
06740
06741 fPrintf(" PAR D GSTEP D G2 GRD SAG ");
06742
06743 }
06744
06745
06746
06747
06748
06749
06750
06751
06752
06753
06754
06755 aimsag = TMath_Sqrt(fEpsma2)*(TMath_Abs(fAmin) + fUp);
06756
06757
06758
06759 npar2 = fNpar*(fNpar + 1) / 2;
06760
06761 for (i = 1; i <= npar2; ++i) { fVhmat[i-1] = 0; }
06762
06763
06764
06765
06766
06767 idrv = 2;
06768
06769 for (id = 1; id <= npard; ++id) {
06770
06771 i = id + fNpar - npard;
06772
06773 iext = fNexofi[i-1];
06774
06775 if (fG2[i-1] == 0) {
06776
06777 mnwarn("W", "HESSE", Form("Second derivative enters zero, param %d",iext));
06778
06779 wint = fWerr[i-1];
06780
06781 if (fNvarl[iext-1] > 1) {
06782
06783 mndxdi(fX[i-1], i-1, dxdi);
06784
06785 if (TMath_Abs(dxdi) < .001) wint = .01;
06786
06787 else wint /= TMath_Abs(dxdi);
06788
06789 }
06790
06791 fG2[i-1] = fUp / (wint*wint);
06792
06793 }
06794
06795 xtf = fX[i-1];
06796
06797 dmin_ = fEpsma2*8*TMath_Abs(xtf);
06798
06799
06800
06801
06802
06803 d = TMath_Abs(fGstep[i-1]);
06804
06805 int skip50 = 0;
06806
06807 for (icyc = 1; icyc <= ncyc; ++icyc) {
06808
06809
06810
06811 for (multpy = 1; multpy <= 5; ++multpy) {
06812
06813
06814
06815 fX[i-1] = xtf + d;
06816
06817 mninex(fX);
06818
06819 nparx = fNpar;
06820
06821 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
06822
06823 fX[i-1] = xtf - d;
06824
06825 mninex(fX);
06826
06827 (*fFCN)(nparx, fGin, fs2, fU, 4); ++fNfcn;
06828
06829 fX[i-1] = xtf;
06830
06831 sag = (fs1 + fs2 - fAmin*2)*.5;
06832
06833 if (sag != 0) goto L30;
06834
06835 if (fGstep[i-1] < 0) {
06836
06837 if (d >= .5) goto L26;
06838
06839 d *= 10;
06840
06841 if (d > .5) d = .51;
06842
06843 continue;
06844
06845 }
06846
06847 d *= 10;
06848
06849 }
06850
06851 L26:
06852
06853 mnwarn("W", "HESSE", Form("Second derivative zero for parameter%d",iext));
06854
06855 goto L390;
06856
06857
06858
06859 L30:
06860
06861 g2bfor = fG2[i-1];
06862
06863 fG2[i-1] = sag*2 / (d*d);
06864
06865 fGrd[i-1] = (fs1 - fs2) / (d*2);
06866
06867 if (ldebug) {
06868
06869 fPrintf("%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],fG2[i-1],fGrd[i-1],sag);
06870
06871 }
06872
06873 if (fGstep[i-1] > 0) fGstep[i-1] = TMath_Abs(d);
06874
06875 else fGstep[i-1] = -TMath_Abs(d);
06876
06877 fDirin[i-1] = d;
06878
06879 yy[i-1] = fs1;
06880
06881 dlast = d;
06882
06883 d = TMath_Sqrt(aimsag*2 / TMath_Abs(fG2[i-1]));
06884
06885
06886
06887 stpinm = .5;
06888
06889 if (fGstep[i-1] < 0) d = TMath_Min(d,stpinm);
06890
06891 if (d < dmin_) d = dmin_;
06892
06893
06894
06895 if (TMath_Abs((d - dlast) / d) < tlrstp ||
06896
06897 TMath_Abs((fG2[i-1] - g2bfor) / fG2[i-1]) < tlrg2) {
06898
06899 skip50 = 1;
06900
06901 break;
06902
06903 }
06904
06905 d = TMath_Min(d,dlast*102);
06906
06907 d = TMath_Max(d,dlast*.1);
06908
06909 }
06910
06911
06912
06913 if (!skip50)
06914
06915 mnwarn("D", "MNHESS", Form("Second Deriv. SAG,AIM= %d%g%g",iext,sag,aimsag));
06916
06917
06918
06919 ndex = i*(i + 1) / 2;
06920
06921 fVhmat[ndex-1] = fG2[i-1];
06922
06923 }
06924
06925
06926
06927 mninex(fX);
06928
06929
06930
06931 if (fIstrat > 0) mnhes1();
06932
06933 fISW[1] = 3;
06934
06935 fDcovar = 0;
06936
06937
06938
06939
06940
06941 if (fNpar == 1) goto L214;
06942
06943 for (i = 1; i <= fNpar; ++i) {
06944
06945 for (j = 1; j <= i-1; ++j) {
06946
06947 xti = fX[i-1];
06948
06949 xtj = fX[j-1];
06950
06951 fX[i-1] = xti + fDirin[i-1];
06952
06953 fX[j-1] = xtj + fDirin[j-1];
06954
06955 mninex(fX);
06956
06957 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
06958
06959 fX[i-1] = xti;
06960
06961 fX[j-1] = xtj;
06962
06963 elem = (fs1 + fAmin - yy[i-1] - yy[j-1]) / (
06964
06965 fDirin[i-1]*fDirin[j-1]);
06966
06967 ndex = i*(i-1) / 2 + j;
06968
06969 fVhmat[ndex-1] = elem;
06970
06971 }
06972
06973 }
06974
06975 L214:
06976
06977 mninex(fX);
06978
06979
06980
06981 mnpsdf();
06982
06983 for (i = 1; i <= fNpar; ++i) {
06984
06985 for (j = 1; j <= i; ++j) {
06986
06987 ndex = i*(i-1) / 2 + j;
06988
06989 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
06990
06991 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
06992
06993 }
06994
06995 }
06996
06997 mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
06998
06999 if (ifail > 0) {
07000
07001 mnwarn("W", "HESSE", "Matrix inversion fails.");
07002
07003 goto L390;
07004
07005 }
07006
07007
07008
07009 fEDM = 0;
07010
07011
07012
07013 for (i = 1; i <= fNpar; ++i) {
07014
07015
07016
07017 ndex = i*(i-1) / 2;
07018
07019 for (j = 1; j <= i-1; ++j) {
07020
07021 ++ndex;
07022
07023 ztemp = fP[i + j*fMaxpar - fMaxpar-1]*2;
07024
07025 fEDM += fGrd[i-1]*ztemp*fGrd[j-1];
07026
07027 fVhmat[ndex-1] = ztemp;
07028
07029 }
07030
07031
07032
07033 ++ndex;
07034
07035 fVhmat[ndex-1] = fP[i + i*fMaxpar - fMaxpar-1]*2;
07036
07037 fEDM += fP[i + i*fMaxpar - fMaxpar-1]*(fGrd[i-1]*fGrd[i-1]);
07038
07039 }
07040
07041 if (fISW[4] >= 1 && fISW[1] == 3 && fItaur == 0) {
07042
07043 fPrintf(" COVARIANCE MATRIX CALCULATED SUCCESSFULLY");
07044
07045 }
07046
07047 goto L900;
07048
07049
07050
07051 L390:
07052
07053 fISW[1] = 1;
07054
07055 fDcovar = 1;
07056
07057 fCstatu = "FAILED ";
07058
07059 if (fISW[4] >= 0) {
07060
07061 fPrintf(" MNHESS FAILS AND WILL RETURN DIAGONAL MATRIX. ");
07062
07063 }
07064
07065 for (i = 1; i <= fNpar; ++i) {
07066
07067 ndex = i*(i-1) / 2;
07068
07069 for (j = 1; j <= i-1; ++j) {
07070
07071 ++ndex;
07072
07073 fVhmat[ndex-1] = 0;
07074
07075 }
07076
07077 ++ndex;
07078
07079 g2i = fG2[i-1];
07080
07081 if (g2i <= 0) g2i = 1;
07082
07083 fVhmat[ndex-1] = 2 / g2i;
07084
07085 }
07086
07087 L900:
07088
07089 return;
07090
07091 }
07092
07093
07094
07095
07096
07097 void Midnight::mnhes1()
07098
07099 {
07100
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115 static MDouble dmin_, d, dfmin, dgmin, change, chgold, grdold, epspri;
07116
07117 static MDouble fs1, optstp, fs2, grdnew, sag, xtf;
07118
07119 static MInt icyc, ncyc, idrv, i, nparx;
07120
07121 static MBool ldebug;
07122
07123
07124
07125 ldebug = fIdbg[5] >= 1;
07126
07127 if (fIstrat <= 0) ncyc = 1;
07128
07129 if (fIstrat == 1) ncyc = 2;
07130
07131 if (fIstrat > 1) ncyc = 6;
07132
07133 idrv = 1;
07134
07135 nparx = fNpar;
07136
07137 dfmin = fEpsma2*4*(TMath_Abs(fAmin) + fUp);
07138
07139
07140
07141 for (i = 1; i <= fNpar; ++i) {
07142
07143 xtf = fX[i-1];
07144
07145 dmin_ = fEpsma2*4*TMath_Abs(xtf);
07146
07147 epspri = fEpsma2 + TMath_Abs(fGrd[i-1]*fEpsma2);
07148
07149 optstp = TMath_Sqrt(dfmin / (TMath_Abs(fG2[i-1]) + epspri));
07150
07151 d = TMath_Abs(fGstep[i-1])*.2;
07152
07153 if (d > optstp) d = optstp;
07154
07155 if (d < dmin_) d = dmin_;
07156
07157 chgold = 1e4;
07158
07159
07160
07161 for (icyc = 1; icyc <= ncyc; ++icyc) {
07162
07163 fX[i-1] = xtf + d;
07164
07165 mninex(fX);
07166
07167 (*fFCN)(nparx, fGin, fs1, fU, 4); ++fNfcn;
07168
07169 fX[i-1] = xtf - d;
07170
07171 mninex(fX);
07172
07173 (*fFCN)(nparx, fGin, fs2, fU, 4); ++fNfcn;
07174
07175 fX[i-1] = xtf;
07176
07177
07178
07179 sag = (fs1 + fs2 - fAmin*2)*.5;
07180
07181 grdold = fGrd[i-1];
07182
07183 grdnew = (fs1 - fs2) / (d*2);
07184
07185 dgmin = fEpsmac*(TMath_Abs(fs1) + TMath_Abs(fs2)) / d;
07186
07187 if (ldebug) {
07188
07189 fPrintf("%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],d,fG2[i-1],grdnew,sag);
07190
07191 }
07192
07193 if (grdnew == 0) goto L60;
07194
07195 change = TMath_Abs((grdold - grdnew) / grdnew);
07196
07197 if (change > chgold && icyc > 1) goto L60;
07198
07199 chgold = change;
07200
07201 fGrd[i-1] = grdnew;
07202
07203 if (fGstep[i-1] > 0) fGstep[i-1] = TMath_Abs(d);
07204
07205 else fGstep[i-1] = -TMath_Abs(d);
07206
07207
07208
07209 if (change < .05) goto L60;
07210
07211 if (TMath_Abs(grdold - grdnew) < dgmin) goto L60;
07212
07213 if (d < dmin_) {
07214
07215 mnwarn("D", "MNHES1", "Step size too small for 1st drv.");
07216
07217 goto L60;
07218
07219 }
07220
07221 d *= .2;
07222
07223 }
07224
07225
07226
07227 mnwarn("D", "MNHES1", Form("Too many iterations on D1.%g%g",grdold,grdnew));
07228
07229 L60:
07230
07231 fDgrd[i-1] = TMath_Max(dgmin,TMath_Abs(grdold - grdnew));
07232
07233 }
07234
07235
07236
07237 mninex(fX);
07238
07239 }
07240
07241
07242
07243
07244
07245 void Midnight::mnimpr()
07246
07247 {
07248
07249
07250
07251
07252
07253
07254
07255
07256
07257
07258
07259
07260
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271 static MDouble rnum = 0;
07272
07273
07274
07275
07276
07277 static MDouble amax, dsav[kMAXDIM], y[kMAXDIM+1], ycalf, ystar, ystst;
07278
07279 static MDouble pb, ep, wg, xi, sigsav, reg, sig2;
07280
07281 static MInt npfn, ndex, loop, i, j, ifail, iseed;
07282
07283 static MInt jhold, nloop, nparx, nparp1, jh, jl;
07284
07285
07286
07287 if (fNpar <= 0) return;
07288
07289 if (fAmin == fUndefi) mnamin();
07290
07291 fCstatu = "UNCHANGED ";
07292
07293 fItaur = 1;
07294
07295 fEpsi = fUp*.1;
07296
07297 npfn = fNfcn;
07298
07299 nloop = MInt(fWord7[1]);
07300
07301 if (nloop <= 0) nloop = fNpar + 4;
07302
07303 nparx = fNpar;
07304
07305 nparp1 = fNpar + 1;
07306
07307 wg = 1 / MDouble(fNpar);
07308
07309 sigsav = fEDM;
07310
07311 fApsi = fAmin;
07312
07313 for (i = 1; i <= fNpar; ++i) {
07314
07315 fXt[i-1] = fX[i-1];
07316
07317 dsav[i-1] = fWerr[i-1];
07318
07319 for (j = 1; j <= i; ++j) {
07320
07321 ndex = i*(i-1) / 2 + j;
07322
07323 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
07324
07325 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
07326
07327 }
07328
07329 }
07330
07331 mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
07332
07333 if (ifail >= 1) goto L280;
07334
07335
07336
07337 for (i = 1; i <= fNpar; ++i) {
07338
07339 ndex = i*(i-1) / 2;
07340
07341 for (j = 1; j <= i; ++j) {
07342
07343 ++ndex;
07344
07345 fVthmat[ndex-1] = fP[i + j*fMaxpar - fMaxpar-1];
07346
07347 }
07348
07349 }
07350
07351 loop = 0;
07352
07353
07354
07355 L20:
07356
07357 for (i = 1; i <= fNpar; ++i) {
07358
07359 fDirin[i-1] = dsav[i-1]*2;
07360
07361 mnrn15(rnum, iseed);
07362
07363 fX[i-1] = fXt[i-1] + fDirin[i-1]*2*(rnum - .5);
07364
07365 }
07366
07367 ++loop;
07368
07369 reg = 2;
07370
07371 if (fISW[4] >= 0) {
07372
07373 fPrintf("START ATTEMPT NO.%2d TO FIND NEW MINIMUM",loop);
07374
07375 }
07376
07377 L30:
07378
07379 mncalf(fX, ycalf);
07380
07381 fAmin = ycalf;
07382
07383
07384
07385 jl = nparp1;
07386
07387 jh = nparp1;
07388
07389 y[nparp1-1] = fAmin;
07390
07391 amax = fAmin;
07392
07393 for (i = 1; i <= fNpar; ++i) {
07394
07395 xi = fX[i-1];
07396
07397 mnrn15(rnum, iseed);
07398
07399 fX[i-1] = xi - fDirin[i-1]*(rnum - .5);
07400
07401 mncalf(fX, ycalf);
07402
07403 y[i-1] = ycalf;
07404
07405 if (y[i-1] < fAmin) {
07406
07407 fAmin = y[i-1];
07408
07409 jl = i;
07410
07411 } else if (y[i-1] > amax) {
07412
07413 amax = y[i-1];
07414
07415 jh = i;
07416
07417 }
07418
07419 for (j = 1; j <= fNpar; ++j) { fP[j + i*fMaxpar - fMaxpar-1] = fX[j-1]; }
07420
07421 fP[i + nparp1*fMaxpar - fMaxpar-1] = xi;
07422
07423 fX[i-1] = xi;
07424
07425 }
07426
07427
07428
07429 fEDM = fAmin;
07430
07431 sig2 = fEDM;
07432
07433
07434
07435 L50:
07436
07437 if (fAmin < 0) goto L95;
07438
07439 if (fISW[1] <= 2) goto L280;
07440
07441 ep = fAmin*.1;
07442
07443 if (sig2 < ep && fEDM < ep) goto L100;
07444
07445 sig2 = fEDM;
07446
07447 if (fNfcn - npfn > fNfcnmx) goto L300;
07448
07449
07450
07451 for (i = 1; i <= fNpar; ++i) {
07452
07453 pb = 0;
07454
07455 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
07456
07457 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
07458
07459 fPstar[i-1] = fPbar[i-1]*2 - fP[i + jh*fMaxpar - fMaxpar-1]*1;
07460
07461 }
07462
07463 mncalf(fPstar, ycalf);
07464
07465 ystar = ycalf;
07466
07467 if (ystar >= fAmin) goto L70;
07468
07469
07470
07471 for (i = 1; i <= fNpar; ++i) {
07472
07473 fPstst[i-1] = fPstar[i-1]*2 + fPbar[i- 1]*-1;
07474
07475 }
07476
07477 mncalf(fPstst, ycalf);
07478
07479 ystst = ycalf;
07480
07481 if (ystst < y[jl-1]) goto L67;
07482
07483 mnrazz(ystar, fPstar, y, jh, jl);
07484
07485 goto L50;
07486
07487 L67:
07488
07489 mnrazz(ystst, fPstst, y, jh, jl);
07490
07491 goto L50;
07492
07493
07494
07495 L70:
07496
07497 if (ystar >= y[jh-1]) goto L73;
07498
07499 jhold = jh;
07500
07501 mnrazz(ystar, fPstar, y, jh, jl);
07502
07503 if (jhold != jh) goto L50;
07504
07505
07506
07507 L73:
07508
07509 for (i = 1; i <= fNpar; ++i) {
07510
07511 fPstst[i-1] = fP[i + jh*fMaxpar - fMaxpar-1]*.5 + fPbar[i-1]*.5;
07512
07513 }
07514
07515 mncalf(fPstst, ycalf);
07516
07517 ystst = ycalf;
07518
07519 if (ystst > y[jh-1]) goto L30;
07520
07521
07522
07523 if (ystst < fAmin) goto L67;
07524
07525 mnrazz(ystst, fPstst, y, jh, jl);
07526
07527 goto L50;
07528
07529
07530
07531 L95:
07532
07533 if (fISW[4] >= 0) {
07534
07535 fPrintf(" AN IMPROVEMENT ON THE PREVIOUS MINIMUM HAS BEEN FOUND");
07536
07537 }
07538
07539 reg = .1;
07540
07541
07542
07543 L100:
07544
07545 mninex(fX);
07546
07547 (*fFCN)(nparx, fGin, fAmin, fU, 4); ++fNfcn;
07548
07549 for (i = 1; i <= fNpar; ++i) {
07550
07551 fDirin[i-1] = reg*dsav[i-1];
07552
07553 if (TMath_Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L150;
07554
07555 }
07556
07557 goto L230;
07558
07559 L150:
07560
07561 fNfcnmx = fNfcnmx + npfn - fNfcn;
07562
07563 npfn = fNfcn;
07564
07565 mnsimp();
07566
07567 if (fAmin >= fApsi) goto L325;
07568
07569 for (i = 1; i <= fNpar; ++i) {
07570
07571 fDirin[i-1] = dsav[i-1]*.1;
07572
07573 if (TMath_Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L250;
07574
07575 }
07576
07577 L230:
07578
07579 if (fAmin < fApsi) goto L350;
07580
07581 goto L325;
07582
07583
07584
07585 L250:
07586
07587 fLnewmn = kTRUE;
07588
07589 if (fISW[1] >= 1) {
07590
07591 fISW[1] = 1;
07592
07593 fDcovar = TMath_Max(fDcovar,.5);
07594
07595 } else fDcovar = 1;
07596
07597 fItaur = 0;
07598
07599 fNfcnmx = fNfcnmx + npfn - fNfcn;
07600
07601 fCstatu = "NEW MINIMU";
07602
07603 if (fISW[4] >= 0) {
07604
07605 fPrintf(" IMPROVE HAS FOUND A TRULY NEW MINIMUM");
07606
07607 fPrintf(" *************************************");
07608
07609 }
07610
07611 return;
07612
07613
07614
07615 L280:
07616
07617 if (fISW[4] > 0) {
07618
07619 fPrintf(" COVARIANCE MATRIX WAS NOT POSITIVE-DEFINITE");
07620
07621 }
07622
07623 goto L325;
07624
07625 L300:
07626
07627 fISW[0] = 1;
07628
07629 L325:
07630
07631 for (i = 1; i <= fNpar; ++i) {
07632
07633 fDirin[i-1] = dsav[i-1]*.01;
07634
07635 fX[i-1] = fXt[i-1];
07636
07637 }
07638
07639 fAmin = fApsi;
07640
07641 fEDM = sigsav;
07642
07643 L350:
07644
07645 mninex(fX);
07646
07647 if (fISW[4] > 0) {
07648
07649 fPrintf(" IMPROVE HAS RETURNED TO REGION OF ORIGINAL MINIMUM");
07650
07651 }
07652
07653 fCstatu = "UNCHANGED ";
07654
07655 mnrset(0);
07656
07657 if (fISW[1] < 2) goto L380;
07658
07659 if (loop < nloop && fISW[0] < 1) goto L20;
07660
07661 L380:
07662
07663 mnprin(5, fAmin);
07664
07665 fItaur = 0;
07666
07667 }
07668
07669
07670
07671
07672
07673 void Midnight::mninex(MDouble *pint)
07674
07675 {
07676
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689 MInt i, j;
07690
07691
07692
07693 for (j = 1; j <= fNpar; ++j) {
07694
07695 i = fNexofi[j-1];
07696
07697 if (fNvarl[i-1] == 1) {
07698
07699 fU[i-1] = pint[j-1];
07700
07701 } else {
07702
07703 fU[i-1] = fAlim[i-1] + (TMath_Sin(pint[j-1]) + 1)*.5*(fBlim[i-1] - fAlim[i-1]);
07704
07705 }
07706
07707 }
07708
07709 }
07710
07711
07712
07713
07714
07715 void Midnight::mninit(MInt i1, MInt i2, MInt i3)
07716
07717 {
07718
07719
07720
07721
07722
07723
07724
07725
07726
07727
07728
07729
07730
07731
07732
07733 static MDouble piby2, epsp1, epsbak, epstry, distnn;
07734
07735 static MInt i, idb;
07736
07737
07738
07739
07740
07741 fIsysrd = i1;
07742
07743 fIsyswr = i2;
07744
07745 fIstkwr[0] = fIsyswr;
07746
07747 fNstkwr = 1;
07748
07749 fIsyssa = i3;
07750
07751 fNstkrd = 0;
07752
07753
07754
07755 fCvrsn = "95.03++ ";
07756
07757
07758
07759 fMaxint = fMaxpar;
07760
07761 fMaxext = 2*fMaxpar;
07762
07763 fUndefi = -54321;
07764
07765 fBigedm = 123456;
07766
07767 fCundef = ")UNDEFINED";
07768
07769 fCovmes[0] = "NO ERROR MATRIX ";
07770
07771 fCovmes[1] = "ERR MATRIX APPROXIMATE";
07772
07773 fCovmes[2] = "ERR MATRIX NOT POS-DEF";
07774
07775 fCovmes[3] = "ERROR MATRIX ACCURATE ";
07776
07777
07778
07779 fNblock = 0;
07780
07781 fIcomnd = 0;
07782
07783 fCtitl = fCundef;
07784
07785 fCfrom = "INPUT ";
07786
07787 fNfcn = 0;
07788
07789 fNfcnfr = fNfcn;
07790
07791 fCstatu = "INITIALIZE";
07792
07793 fISW[2] = 0;
07794
07795 fISW[3] = 0;
07796
07797 fISW[4] = 1;
07798
07799
07800
07801
07802
07803
07804
07805 fISW[5] = 0;
07806
07807
07808
07809
07810
07811 for (idb = 0; idb <= 10; ++idb) { fIdbg[idb] = 0; }
07812
07813 fLrepor = kFALSE;
07814
07815 fLwarn = kTRUE;
07816
07817 fLimset = kFALSE;
07818
07819 fLnewmn = kFALSE;
07820
07821 fIstrat = 1;
07822
07823 fItaur = 0;
07824
07825
07826
07827 fNpagwd = 120;
07828
07829 fNpagln = 56;
07830
07831 fNewpag = 1;
07832
07833 if (fISW[5] > 0) {
07834
07835 fNpagwd = 80;
07836
07837 fNpagln = 30;
07838
07839 fNewpag = 0;
07840
07841 }
07842
07843 fUp = 1;
07844
07845 fUpdflt = fUp;
07846
07847
07848
07849 epstry = .5;
07850
07851 for (i = 1; i <= 100; ++i) {
07852
07853 epstry *= .5;
07854
07855 epsp1 = epstry + 1;
07856
07857 mntiny(epsp1, epsbak);
07858
07859 if (epsbak < epstry) goto L35;
07860
07861 }
07862
07863 epstry = 1e-7;
07864
07865 fEpsmac = epstry*4;
07866
07867 fPrintf(" MNINIT UNABLE TO DETERMINE ARITHMETIC PRECISION. WILL ASSUME:%g",fEpsmac);
07868
07869 L35:
07870
07871 fEpsmac = epstry*8;
07872
07873 fEpsma2 = TMath_Sqrt(fEpsmac)*2;
07874
07875
07876
07877
07878
07879 piby2 = TMath_ATan(1.)*2;
07880
07881 distnn = TMath_Sqrt(fEpsma2)*8;
07882
07883 fVlimhi = piby2 - distnn;
07884
07885 fVlimlo = -piby2 + distnn;
07886
07887 mncler();
07888
07889
07890
07891 }
07892
07893
07894
07895
07896
07897 void Midnight::mnlims()
07898
07899 {
07900
07901
07902
07903
07904
07905
07906
07907
07908
07909
07910
07911
07912
07913 static MDouble dxdi, snew;
07914
07915 static MInt kint, i2, newcod, ifx, inu;
07916
07917
07918
07919 fCfrom = "SET LIM ";
07920
07921 fNfcnfr = fNfcn;
07922
07923 fCstatu = "NO CHANGE ";
07924
07925 i2 = MInt(fWord7[0]);
07926
07927 if (i2 > fMaxext || i2 < 0) goto L900;
07928
07929 if (i2 > 0) goto L30;
07930
07931
07932
07933 newcod = 4;
07934
07935 if (fWord7[1] == fWord7[2]) newcod = 1;
07936
07937 for (inu = 1; inu <= fNu; ++inu) {
07938
07939 if (fNvarl[inu-1] <= 0) continue;
07940
07941 if (fNvarl[inu-1] == 1 && newcod == 1) continue;
07942
07943 kint = fNiofex[inu-1];
07944
07945
07946
07947 if (kint <= 0) {
07948
07949 if (fISW[4] >= 0) {
07950
07951 fPrintf(" LIMITS NOT CHANGED FOR FIXED PARAMETER:%4d",inu);
07952
07953 }
07954
07955 continue;
07956
07957 }
07958
07959 if (newcod == 1) {
07960
07961
07962
07963 if (fISW[4] > 0) {
07964
07965 fPrintf(" LIMITS REMOVED FROM PARAMETER :%3d",inu);
07966
07967 }
07968
07969 fCstatu = "NEW LIMITS";
07970
07971 mndxdi(fX[kint-1], kint-1, dxdi);
07972
07973 snew = fGstep[kint-1]*dxdi;
07974
07975 fGstep[kint-1] = TMath_Abs(snew);
07976
07977 fNvarl[inu-1] = 1;
07978
07979 } else {
07980
07981
07982
07983 fAlim[inu-1] = TMath_Min(fWord7[1],fWord7[2]);
07984
07985 fBlim[inu-1] = TMath_Max(fWord7[1],fWord7[2]);
07986
07987 if (fISW[4] > 0) {
07988
07989 fPrintf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",inu,fAlim[inu-1],fBlim[inu-1]);
07990
07991 }
07992
07993 fNvarl[inu-1] = 4;
07994
07995 fCstatu = "NEW LIMITS";
07996
07997 fGstep[kint-1] = -.1;
07998
07999 }
08000
08001 }
08002
08003 goto L900;
08004
08005
08006
08007 L30:
08008
08009 if (fNvarl[i2-1] <= 0) {
08010
08011 fPrintf(" PARAMETER %3d IS NOT VARIABLE.", i2);
08012
08013 goto L900;
08014
08015 }
08016
08017 kint = fNiofex[i2-1];
08018
08019
08020
08021 if (kint == 0) {
08022
08023 fPrintf(" REQUEST TO CHANGE LIMITS ON FIXED PARAMETER:%3d",i2);
08024
08025 for (ifx = 1; ifx <= fNpfix; ++ifx) {
08026
08027 if (i2 == fIpfix[ifx-1]) goto L92;
08028
08029 }
08030
08031 fPrintf(" MINUIT BUG IN MNLIMS. SEE F. JAMES");
08032
08033 L92:
08034
08035 ;
08036
08037 }
08038
08039 if (fWord7[1] != fWord7[2]) goto L235;
08040
08041
08042
08043 if (fNvarl[i2-1] != 1) {
08044
08045 if (fISW[4] > 0) {
08046
08047 fPrintf(" LIMITS REMOVED FROM PARAMETER %2d",i2);
08048
08049 }
08050
08051 fCstatu = "NEW LIMITS";
08052
08053 if (kint <= 0) {
08054
08055 fGsteps[ifx-1] = TMath_Abs(fGsteps[ifx-1]);
08056
08057 } else {
08058
08059 mndxdi(fX[kint-1], kint-1, dxdi);
08060
08061 if (TMath_Abs(dxdi) < .01) dxdi = .01;
08062
08063 fGstep[kint-1] = TMath_Abs(fGstep[kint-1]*dxdi);
08064
08065 fGrd[kint-1] *= dxdi;
08066
08067 }
08068
08069 fNvarl[i2-1] = 1;
08070
08071 } else {
08072
08073 fPrintf(" NO LIMITS SPECIFIED. PARAMETER %3d IS ALREADY UNLIMITED. NO CHANGE.",i2);
08074
08075 }
08076
08077 goto L900;
08078
08079
08080
08081 L235:
08082
08083 fAlim[i2-1] = TMath_Min(fWord7[1],fWord7[2]);
08084
08085 fBlim[i2-1] = TMath_Max(fWord7[1],fWord7[2]);
08086
08087 fNvarl[i2-1] = 4;
08088
08089 if (fISW[4] > 0) {
08090
08091 fPrintf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",i2,fAlim[i2-1],fBlim[i2-1]);
08092
08093 }
08094
08095 fCstatu = "NEW LIMITS";
08096
08097 if (kint <= 0) fGsteps[ifx-1] = -.1;
08098
08099 else fGstep[kint-1] = -.1;
08100
08101
08102
08103 L900:
08104
08105 if (fCstatu != "NO CHANGE ") {
08106
08107 mnexin(fX);
08108
08109 mnrset(1);
08110
08111 }
08112
08113 }
08114
08115
08116
08117
08118
08119 void Midnight::mnline(MDouble *start, MDouble fstart, MDouble *step, MDouble slope, MDouble toler)
08120
08121 {
08122
08123
08124
08125
08126
08127
08128
08129
08130
08131
08132
08133
08134
08135
08136
08137
08138
08139
08140
08141
08142
08143
08144
08145
08146
08147
08148
08149
08150
08151
08152
08153 const MString charal = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
08154
08155
08156
08157
08158
08159 static MDouble xpq[12], ypq[12], slam, sdev, coeff[3], denom, flast;
08160
08161 static MDouble fvals[3], xvals[3], f1, fvmin, xvmin, ratio, f2, f3, fvmax;
08162
08163 static MDouble toler8, toler9, overal, undral, slamin, slamax, slopem;
08164
08165 static MInt i, nparx, nvmax, nxypt, kk, ipt;
08166
08167 static MBool ldebug;
08168
08169 MString cmess, chpq[12];
08170
08171 int l65, l70, l80;
08172
08173
08174
08175
08176
08177 l65 = 0; l70 = 0; l80 = 0;
08178
08179 ldebug = fIdbg[1] >= 1;
08180
08181
08182
08183 overal = 1e3;
08184
08185 undral = -100;
08186
08187
08188
08189 if (ldebug) {
08190
08191 mninex(&start[0]);
08192
08193 (*fFCN)(nparx, fGin, f1, fU, 4); ++fNfcn;
08194
08195 if (f1 != fstart) {
08196
08197 fPrintf(" MNLINE start point not consistent, F values, parameters=");
08198
08199 for (kk = 1; kk <= fNpar; ++kk) {
08200
08201 fPrintf(" %14.5e",fX[kk-1]);
08202
08203 }
08204
08205 }
08206
08207 }
08208
08209
08210
08211 fvmin = fstart;
08212
08213 xvmin = 0;
08214
08215 nxypt = 1;
08216
08217 chpq[0] = charal[0];
08218
08219 xpq[0] = 0;
08220
08221 ypq[0] = fstart;
08222
08223
08224
08225 slamin = 0;
08226
08227 for (i = 1; i <= fNpar; ++i) {
08228
08229 if (step[i-1] != 0) {
08230
08231 ratio = TMath_Abs(start[i-1] / step[i-1]);
08232
08233 if (slamin == 0) slamin = ratio;
08234
08235 if (ratio < slamin) slamin = ratio;
08236
08237 }
08238
08239 fX[i-1] = start[i-1] + step[i-1];
08240
08241 }
08242
08243 if (slamin == 0) slamin = fEpsmac;
08244
08245 slamin *= fEpsma2;
08246
08247 nparx = fNpar;
08248
08249
08250
08251 mninex(fX);
08252
08253 (*fFCN)(nparx, fGin, f1, fU, 4); ++fNfcn;
08254
08255 ++nxypt;
08256
08257 chpq[nxypt-1] = charal[nxypt-1];
08258
08259 xpq[nxypt-1] = 1;
08260
08261 ypq[nxypt-1] = f1;
08262
08263 if (f1 < fstart) {
08264
08265 fvmin = f1;
08266
08267 xvmin = 1;
08268
08269 }
08270
08271
08272
08273 slam = 1;
08274
08275 toler8 = toler;
08276
08277 slamax = 5;
08278
08279 flast = f1;
08280
08281
08282
08283
08284
08285 do {
08286
08287 denom = (flast - fstart - slope*slam)*2 / (slam*slam);
08288
08289 slam = 1;
08290
08291 if (denom != 0) slam = -slope / denom;
08292
08293 if (slam < 0) slam = slamax;
08294
08295 if (slam > slamax) slam = slamax;
08296
08297 if (slam < toler8) slam = toler8;
08298
08299 if (slam < slamin) {
08300
08301 l80 = 1;
08302
08303 break;
08304
08305 }
08306
08307 if (TMath_Abs(slam - 1) < toler8 && f1 < fstart) {
08308
08309 l70 = 1;
08310
08311 break;
08312
08313 }
08314
08315 if (TMath_Abs(slam - 1) < toler8) slam = toler8 + 1;
08316
08317 if (nxypt >= 12) {
08318
08319 l65 = 1;
08320
08321 break;
08322
08323 }
08324
08325 for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
08326
08327 mninex(fX);
08328
08329 (*fFCN)(fNpar, fGin, f2, fU, 4); ++fNfcn;
08330
08331 ++nxypt;
08332
08333 chpq[nxypt-1] = charal[nxypt-1];
08334
08335 xpq[nxypt-1] = slam;
08336
08337 ypq[nxypt-1] = f2;
08338
08339 if (f2 < fvmin) {
08340
08341 fvmin = f2;
08342
08343 xvmin = slam;
08344
08345 }
08346
08347 if (fstart == fvmin) {
08348
08349 flast = f2;
08350
08351 toler8 = toler*slam;
08352
08353 overal = slam - toler8;
08354
08355 slamax = overal;
08356
08357 }
08358
08359 } while (fstart == fvmin);
08360
08361
08362
08363 if (!l65 && !l70 && !l80) {
08364
08365
08366
08367 xvals[0] = xpq[0];
08368
08369 fvals[0] = ypq[0];
08370
08371 xvals[1] = xpq[nxypt-2];
08372
08373 fvals[1] = ypq[nxypt-2];
08374
08375 xvals[2] = xpq[nxypt-1];
08376
08377 fvals[2] = ypq[nxypt-1];
08378
08379
08380
08381 do {
08382
08383 slamax = TMath_Max(slamax,TMath_Abs(xvmin)*2);
08384
08385 mnpfit(xvals, fvals, 3, coeff, sdev);
08386
08387 if (coeff[2] <= 0) {
08388
08389 slopem = coeff[2]*2*xvmin + coeff[1];
08390
08391 if (slopem <= 0) slam = xvmin + slamax;
08392
08393 else slam = xvmin - slamax;
08394
08395 } else {
08396
08397 slam = -coeff[1] / (coeff[2]*2);
08398
08399 if (slam > xvmin + slamax) slam = xvmin + slamax;
08400
08401 if (slam < xvmin - slamax) slam = xvmin - slamax;
08402
08403 }
08404
08405 if (slam > 0) if (slam > overal) slam = overal;
08406
08407 else if (slam < undral) slam = undral;
08408
08409
08410
08411
08412
08413 do {
08414
08415 toler9 = TMath_Max(toler8,TMath_Abs(toler8*slam));
08416
08417 for (ipt = 1; ipt <= 3; ++ipt) {
08418
08419 if (TMath_Abs(slam - xvals[ipt-1]) < toler9) {
08420
08421 l70 = 1;
08422
08423 break;
08424
08425 }
08426
08427 }
08428
08429 if (l70) break;
08430
08431
08432
08433 if (nxypt >= 12) {
08434
08435 l65 = 1;
08436
08437 break;
08438
08439 }
08440
08441 for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
08442
08443 mninex(fX);
08444
08445 (*fFCN)(nparx, fGin, f3, fU, 4); ++fNfcn;
08446
08447 ++nxypt;
08448
08449 chpq[nxypt-1] = charal[nxypt-1];
08450
08451 xpq[nxypt-1] = slam;
08452
08453 ypq[nxypt-1] = f3;
08454
08455
08456
08457 fvmax = fvals[0];
08458
08459 nvmax = 1;
08460
08461 if (fvals[1] > fvmax) {
08462
08463 fvmax = fvals[1];
08464
08465 nvmax = 2;
08466
08467 }
08468
08469 if (fvals[2] > fvmax) {
08470
08471 fvmax = fvals[2];
08472
08473 nvmax = 3;
08474
08475 }
08476
08477
08478
08479 if (f3 >= fvmax) {
08480
08481 if (nxypt >= 12) {
08482
08483 l65 = 1;
08484
08485 break;
08486
08487 }
08488
08489 if (slam > xvmin) overal = TMath_Min(overal,slam - toler8);
08490
08491 if (slam < xvmin) undral = TMath_Max(undral,slam + toler8);
08492
08493 slam = (slam + xvmin)*.5;
08494
08495 }
08496
08497 } while (f3 >= fvmax);
08498
08499
08500
08501
08502
08503 if (l65 || l70) break;
08504
08505
08506
08507 xvals[nvmax-1] = slam;
08508
08509 fvals[nvmax-1] = f3;
08510
08511 if (f3 < fvmin) {
08512
08513 fvmin = f3;
08514
08515 xvmin = slam;
08516
08517 } else {
08518
08519 if (slam > xvmin) overal = TMath_Min(overal,slam - toler8);
08520
08521 if (slam < xvmin) undral = TMath_Max(undral,slam + toler8);
08522
08523 }
08524
08525 } while (nxypt < 12);
08526
08527 }
08528
08529
08530
08531
08532
08533
08534
08535 if (!l70 && !l80) {
08536
08537 cmess = " LINE SEARCH HAS EXHAUSTED THE LIMIT OF FUNCTION CALLS ";
08538
08539 if (ldebug) {
08540
08541 fPrintf(" MNLINE DEBUG: steps=");
08542
08543 for (kk = 1; kk <= fNpar; ++kk) {
08544
08545 fPrintf(" %12.4g",step[kk-1]);
08546
08547 }
08548
08549 }
08550
08551 }
08552
08553
08554
08555 if (l70) cmess = " LINE SEARCH HAS ATTAINED TOLERANCE ";
08556
08557 if (l80) cmess = " STEP SIZE AT ARITHMETICALLY ALLOWED MINIMUM";
08558
08559
08560
08561 fAmin = fvmin;
08562
08563 for (i = 1; i <= fNpar; ++i) {
08564
08565 fDirin[i-1] = step[i-1]*xvmin;
08566
08567 fX[i-1] = start[i-1] + fDirin[i-1];
08568
08569 }
08570
08571 mninex(fX);
08572
08573 if (xvmin < 0) {
08574
08575 mnwarn("D", "MNLINE", " LINE MINIMUM IN BACKWARDS DIRECTION");
08576
08577 }
08578
08579 if (fvmin == fstart) {
08580
08581 mnwarn("D", "MNLINE", " LINE SEARCH FINDS NO IMPROVEMENT ");
08582
08583 }
08584
08585 if (ldebug) {
08586
08587 fPrintf(" AFTER%3d POINTS,%s",nxypt,(const char*)cmess);
08588
08589 mnplot(xpq, ypq, chpq, nxypt, fNpagwd, fNpagln);
08590
08591 }
08592
08593 }
08594
08595
08596
08597
08598
08599 void Midnight::mnmatu(MInt kode)
08600
08601 {
08602
08603
08604
08605
08606
08607
08608
08609
08610
08611
08612
08613
08614
08615
08616
08617 static MDouble vline[kMAXDIM];
08618
08619 static MInt ndex, i, j, m, n, ncoef, nparm, id, it, ix;
08620
08621 static MInt nsofar, ndi, ndj, iso, isw2, isw5;
08622
08623 static MString ctemp;
08624
08625
08626
08627 isw2 = fISW[1];
08628
08629 if (isw2 < 1) {
08630
08631 fPrintf("%s",(const char*)fCovmes[isw2]);
08632
08633 return;
08634
08635 }
08636
08637 if (fNpar == 0) {
08638
08639 fPrintf(" MNMATU: NPAR=0");
08640
08641 return;
08642
08643 }
08644
08645
08646
08647 if (kode == 1) {
08648
08649 isw5 = fISW[4];
08650
08651 fISW[4] = 2;
08652
08653 mnemat(fP, fMaxint);
08654
08655 if (isw2 < 3) {
08656
08657 fPrintf("%s",(const char*)fCovmes[isw2]);
08658
08659 }
08660
08661 fISW[4] = isw5;
08662
08663 }
08664
08665
08666
08667 if (fNpar <= 1) return;
08668
08669 mnwerr();
08670
08671
08672
08673 ncoef = (fNpagwd - 19) / 6;
08674
08675 ncoef = TMath_Min(ncoef,20);
08676
08677 nparm = TMath_Min(fNpar,ncoef);
08678
08679 fPrintf(" PARAMETER CORRELATION COEFFICIENTS ");
08680
08681 ctemp = " NO. GLOBAL";
08682
08683 for (id = 1; id <= nparm; ++id) {
08684
08685 ctemp += Form(" %6d",fNexofi[id-1]);
08686
08687 }
08688
08689 fPrintf("%s",(const char*)ctemp);
08690
08691 for (i = 1; i <= fNpar; ++i) {
08692
08693 ix = fNexofi[i-1];
08694
08695 ndi = i*(i + 1) / 2;
08696
08697 for (j = 1; j <= fNpar; ++j) {
08698
08699 m = TMath_Max(i,j);
08700
08701 n = TMath_Min(i,j);
08702
08703 ndex = m*(m-1) / 2 + n;
08704
08705 ndj = j*(j + 1) / 2;
08706
08707 vline[j-1] = fVhmat[ndex-1] / TMath_Sqrt(TMath_Abs(fVhmat[ndi-1]*fVhmat[ndj-1]));
08708
08709 }
08710
08711 nparm = TMath_Min(fNpar,ncoef);
08712
08713 ctemp = Form(" %3d %7.5f ",ix);
08714
08715 for (it = 1; it <= nparm; ++it) {
08716
08717 ctemp += Form(" %6.3f",vline[it-1]);
08718
08719 }
08720
08721 fPrintf("%s",(const char*)ctemp);
08722
08723 if (i <= nparm) continue;
08724
08725 ctemp = " ";
08726
08727 for (iso = 1; iso <= 10; ++iso) {
08728
08729 nsofar = nparm;
08730
08731 nparm = TMath_Min(fNpar,nsofar + ncoef);
08732
08733 for (it = nsofar + 1; it <= nparm; ++it) {
08734
08735 ctemp += Form(" %6.3f",vline[it-1]);
08736
08737 }
08738
08739 fPrintf("%s",(const char*)ctemp);
08740
08741 if (i <= nparm) break;
08742
08743 }
08744
08745 }
08746
08747 if (isw2 < 3) {
08748
08749 fPrintf(" %s",(const char*)fCovmes[isw2]);
08750
08751 }
08752
08753 }
08754
08755
08756
08757
08758
08759 void Midnight::mnmigr()
08760
08761 {
08762
08763
08764
08765
08766
08767
08768
08769
08770
08771
08772
08773
08774
08775
08776
08777
08778
08779 static MDouble gdel, gami, flnu[kMAXDIM], vlen, step[kMAXDIM], dsum, gssq, vsum, d;
08780
08781 static MDouble fzero, gs[kMAXDIM], fs, ri, vg[kMAXDIM], delgam, rhotol;
08782
08783 static MDouble gdgssq, gvg, vgi, xxs[kMAXDIM];
08784
08785 static MInt npfn, ndex, iext, i, j, m, n, npsdf, nparx;
08786
08787 static MInt iswtr, lined2, kk, nfcnmg, nrstrt,iter;
08788
08789 static MBool ldebug;
08790
08791 static MDouble toler = 0.05;
08792
08793
08794
08795 if (fNpar <= 0) return;
08796
08797 if (fAmin == fUndefi) mnamin();
08798
08799 ldebug = kFALSE; if ( fIdbg[4] >= 1) ldebug = kTRUE;
08800
08801 fCfrom = "MIGRAD ";
08802
08803 fNfcnfr = fNfcn;
08804
08805 nfcnmg = fNfcn;
08806
08807 fCstatu = "INITIATE ";
08808
08809 iswtr = fISW[4] - 2*fItaur;
08810
08811 npfn = fNfcn;
08812
08813 nparx = fNpar;
08814
08815 vlen = (MDouble) (fNpar*(fNpar + 1) / 2);
08816
08817 nrstrt = 0;
08818
08819 npsdf = 0;
08820
08821 lined2 = 0;
08822
08823 fISW[3] = -1;
08824
08825 rhotol = fApsi*.001;
08826
08827 if (iswtr >= 1) {
08828
08829 fPrintf(" START MIGRAD MINIMIZATION. STRATEGY%2d. CONVERGENCE WHEN EDM .LT.%9.2e",fIstrat,rhotol);
08830
08831 }
08832
08833
08834
08835 if (fIstrat < 2 || fISW[1] >= 3) goto L2;
08836
08837
08838
08839 L1:
08840
08841 if (nrstrt > fIstrat) {
08842
08843 fCstatu = "FAILED ";
08844
08845 fISW[3] = -1;
08846
08847 goto L230;
08848
08849 }
08850
08851
08852
08853 mnhess();
08854
08855 mnwerr();
08856
08857 npsdf = 0;
08858
08859 if (fISW[1] >= 1) goto L10;
08860
08861
08862
08863 L2:
08864
08865 mninex(fX);
08866
08867 if (fISW[2] == 1) {
08868
08869 (*fFCN)(nparx, fGin, fzero, fU, 2); ++fNfcn;
08870
08871 }
08872
08873 mnderi();
08874
08875 if (fISW[1] >= 1) goto L10;
08876
08877
08878
08879 for (i = 1; i <= fNpar; ++i) {
08880
08881 xxs[i-1] = fX[i-1];
08882
08883 step[i-1] = 0;
08884
08885 }
08886
08887
08888
08889 ++lined2;
08890
08891 if (lined2 < (fIstrat + 1)*fNpar) {
08892
08893 for (i = 1; i <= fNpar; ++i) {
08894
08895 if (fG2[i-1] > 0) continue;
08896
08897 if (fGrd[i-1] > 0) step[i-1] = -TMath_Abs(fGstep[i-1]);
08898
08899 else step[i-1] = TMath_Abs(fGstep[i-1]);
08900
08901 gdel = step[i-1]*fGrd[i-1];
08902
08903 fs = fAmin;
08904
08905 mnline(xxs, fs, step, gdel, toler);
08906
08907 mnwarn("D", "MNMIGR", "Negative G2 line search");
08908
08909 iext = fNexofi[i-1];
08910
08911 if (ldebug) {
08912
08913 fPrintf(" Negative G2 line search, param %3d %13.3g%13.3g",iext,fs,fAmin);
08914
08915 }
08916
08917 goto L2;
08918
08919 }
08920
08921 }
08922
08923
08924
08925 for (i = 1; i <= fNpar; ++i) {
08926
08927 ndex = i*(i-1) / 2;
08928
08929 for (j = 1; j <= i-1; ++j) {
08930
08931 ++ndex;
08932
08933 fVhmat[ndex-1] = 0;
08934
08935 }
08936
08937 ++ndex;
08938
08939 if (fG2[i-1] <= 0) fG2[i-1] = 1;
08940
08941 fVhmat[ndex-1] = 2 / fG2[i-1];
08942
08943 }
08944
08945 fDcovar = 1;
08946
08947 if (ldebug) {
08948
08949 fPrintf(" DEBUG MNMIGR, STARTING MATRIX DIAGONAL, VHMAT=");
08950
08951 for (kk = 1; kk <= MInt(vlen); ++kk) {
08952
08953 fPrintf(" %10.2g",fVhmat[kk-1]);
08954
08955 }
08956
08957 }
08958
08959
08960
08961 L10:
08962
08963 ++nrstrt;
08964
08965 if (nrstrt > fIstrat + 1) {
08966
08967 fCstatu = "FAILED ";
08968
08969 goto L230;
08970
08971 }
08972
08973 fs = fAmin;
08974
08975
08976
08977 fEDM = 0;
08978
08979 for (i = 1; i <= fNpar; ++i) {
08980
08981 gs[i-1] = fGrd[i-1];
08982
08983 xxs[i-1] = fX[i-1];
08984
08985 ndex = i*(i-1) / 2;
08986
08987 for (j = 1; j <= i-1; ++j) {
08988
08989 ++ndex;
08990
08991 fEDM += gs[i-1]*fVhmat[ndex-1]*gs[j-1];
08992
08993 }
08994
08995 ++ndex;
08996
08997 fEDM += gs[i-1]*gs[i-1]*.5*fVhmat[ndex-1];
08998
08999 }
09000
09001 fEDM = fEDM*.5*(fDcovar*3 + 1);
09002
09003 if (fEDM < 0) {
09004
09005 mnwarn("W", "MIGRAD", "STARTING MATRIX NOT POS-DEFINITE.");
09006
09007 fISW[1] = 0;
09008
09009 fDcovar = 1;
09010
09011 goto L2;
09012
09013 }
09014
09015 if (fISW[1] == 0) fEDM = fBigedm;
09016
09017 iter = 0;
09018
09019 mninex(fX);
09020
09021 mnwerr();
09022
09023 if (iswtr >= 1) mnprin(3, fAmin);
09024
09025 if (iswtr >= 2) mnmatu(0);
09026
09027
09028
09029 L24:
09030
09031 if (fNfcn - npfn >= fNfcnmx) goto L190;
09032
09033 gdel = 0;
09034
09035 gssq = 0;
09036
09037 for (i = 1; i <= fNpar; ++i) {
09038
09039 ri = 0;
09040
09041 gssq += gs[i-1]*gs[i-1];
09042
09043 for (j = 1; j <= fNpar; ++j) {
09044
09045 m = TMath_Max(i,j);
09046
09047 n = TMath_Min(i,j);
09048
09049 ndex = m*(m-1) / 2 + n;
09050
09051 ri += fVhmat[ndex-1]*gs[j-1];
09052
09053 }
09054
09055 step[i-1] = ri*-.5;
09056
09057 gdel += step[i-1]*gs[i-1];
09058
09059 }
09060
09061 if (gssq == 0) {
09062
09063 mnwarn("D", "MIGRAD", " FIRST DERIVATIVES OF FCN ARE ALL ZERO");
09064
09065 goto L300;
09066
09067 }
09068
09069
09070
09071 if (gdel >= 0) {
09072
09073 mnwarn("D", "MIGRAD", " NEWTON STEP NOT DESCENT.");
09074
09075 if (npsdf == 1) goto L1;
09076
09077 mnpsdf();
09078
09079 npsdf = 1;
09080
09081 goto L24;
09082
09083 }
09084
09085
09086
09087 mnline(xxs, fs, step, gdel, toler);
09088
09089 if (fAmin == fs) goto L200;
09090
09091 fCfrom = "MIGRAD ";
09092
09093 fNfcnfr = nfcnmg;
09094
09095 fCstatu = "PROGRESS ";
09096
09097
09098
09099 mninex(fX);
09100
09101 if (fISW[2] == 1) {
09102
09103 (*fFCN)(nparx, fGin, fzero, fU, 2); ++fNfcn;
09104
09105 }
09106
09107 mnderi();
09108
09109
09110
09111 npsdf = 0;
09112
09113 L81:
09114
09115 fEDM = 0;
09116
09117 gvg = 0;
09118
09119 delgam = 0;
09120
09121 gdgssq = 0;
09122
09123 for (i = 1; i <= fNpar; ++i) {
09124
09125 ri = 0;
09126
09127 vgi = 0;
09128
09129 for (j = 1; j <= fNpar; ++j) {
09130
09131 m = TMath_Max(i,j);
09132
09133 n = TMath_Min(i,j);
09134
09135 ndex = m*(m-1) / 2 + n;
09136
09137 vgi += fVhmat[ndex-1]*(fGrd[j-1] - gs[j-1]);
09138
09139 ri += fVhmat[ndex-1]*fGrd[j-1];
09140
09141 }
09142
09143 vg[i-1] = vgi*.5;
09144
09145 gami = fGrd[i-1] - gs[i-1];
09146
09147 gdgssq += gami*gami;
09148
09149 gvg += gami*vg[i-1];
09150
09151 delgam += fDirin[i-1]*gami;
09152
09153 fEDM += fGrd[i-1]*ri*.5;
09154
09155 }
09156
09157 fEDM = fEDM*.5*(fDcovar*3 + 1);
09158
09159
09160
09161 if (fEDM < 0 || gvg <= 0) {
09162
09163 mnwarn("D", "MIGRAD", "NOT POS-DEF. EDM OR GVG NEGATIVE.");
09164
09165 fCstatu = "NOT POSDEF";
09166
09167 if (npsdf == 1) goto L230;
09168
09169 mnpsdf();
09170
09171 npsdf = 1;
09172
09173 goto L81;
09174
09175 }
09176
09177
09178
09179 ++iter;
09180
09181 if (iswtr >= 3 || iswtr == 2 && iter % 10 == 1) {
09182
09183 mnwerr();
09184
09185 mnprin(3, fAmin);
09186
09187 }
09188
09189 if (gdgssq == 0) {
09190
09191 mnwarn("D", "MIGRAD", "NO CHANGE IN FIRST DERIVATIVES OVER LAST STEP");
09192
09193 }
09194
09195 if (delgam < 0) {
09196
09197 mnwarn("D", "MIGRAD", "FIRST DERIVATIVES INCREASING ALONG SEARCH LINE");
09198
09199 }
09200
09201
09202
09203 fCstatu = "IMPROVEMNT";
09204
09205 if (ldebug) {
09206
09207 fPrintf(" VHMAT 1 =");
09208
09209 for (kk = 1; kk <= 10; ++kk) {
09210
09211 fPrintf(" %10.2g",fVhmat[kk-1]);
09212
09213 }
09214
09215 }
09216
09217 dsum = 0;
09218
09219 vsum = 0;
09220
09221 for (i = 1; i <= fNpar; ++i) {
09222
09223 for (j = 1; j <= i; ++j) {
09224
09225 d = fDirin[i-1]*fDirin[j-1] / delgam - vg[i-1]*vg[j-1] / gvg;
09226
09227 dsum += TMath_Abs(d);
09228
09229 ndex = i*(i-1) / 2 + j;
09230
09231 fVhmat[ndex-1] += d*2;
09232
09233 vsum += TMath_Abs(fVhmat[ndex-1]);
09234
09235 }
09236
09237 }
09238
09239
09240
09241 fDcovar = (fDcovar + dsum / vsum)*.5;
09242
09243 if (iswtr >= 3 || ldebug) {
09244
09245 fPrintf(" RELATIVE CHANGE IN COV. MATRIX=%5.1f per cent",fDcovar*100);
09246
09247 }
09248
09249 if (ldebug) {
09250
09251 fPrintf(" VHMAT 2 =");
09252
09253 for (kk = 1; kk <= 10; ++kk) {
09254
09255 fPrintf(" %10.3g",fVhmat[kk-1]);
09256
09257 }
09258
09259 }
09260
09261 if (delgam <= gvg) goto L135;
09262
09263 for (i = 1; i <= fNpar; ++i) {
09264
09265 flnu[i-1] = fDirin[i-1] / delgam - vg[i-1] / gvg;
09266
09267 }
09268
09269 for (i = 1; i <= fNpar; ++i) {
09270
09271 for (j = 1; j <= i; ++j) {
09272
09273 ndex = i*(i-1) / 2 + j;
09274
09275 fVhmat[ndex-1] += gvg*2*flnu[i-1]*flnu[j-1];
09276
09277 }
09278
09279 }
09280
09281 L135:
09282
09283
09284
09285 if (fEDM < rhotol*.1) goto L300;
09286
09287
09288
09289 for (i = 1; i <= fNpar; ++i) {
09290
09291 xxs[i-1] = fX[i-1];
09292
09293 gs[i-1] = fGrd[i-1];
09294
09295 }
09296
09297 fs = fAmin;
09298
09299 if (fISW[1] == 0 && fDcovar < .5) fISW[1] = 1;
09300
09301 if (fISW[1] == 3 && fDcovar > .1) fISW[1] = 1;
09302
09303 if (fISW[1] == 1 && fDcovar < .05) fISW[1] = 3;
09304
09305 goto L24;
09306
09307
09308
09309
09310
09311 L190:
09312
09313 fISW[0] = 1;
09314
09315 if (fISW[4] >= 0) {
09316
09317 fPrintf(" CALL LIMIT EXCEEDED IN MIGRAD.");
09318
09319 }
09320
09321 fCstatu = "CALL LIMIT";
09322
09323 goto L230;
09324
09325
09326
09327 L200:
09328
09329 if (iswtr >= 1) {
09330
09331 fPrintf(" MIGRAD FAILS TO FIND IMPROVEMENT");
09332
09333 }
09334
09335 for (i = 1; i <= fNpar; ++i) { fX[i-1] = xxs[i-1]; }
09336
09337 if (fEDM < rhotol) goto L300;
09338
09339 if (fEDM < TMath_Abs(fEpsma2*fAmin)) {
09340
09341 if (iswtr >= 0) {
09342
09343 fPrintf(" MACHINE ACCURACY LIMITS FURTHER IMPROVEMENT.");
09344
09345 }
09346
09347 goto L300;
09348
09349 }
09350
09351 if (fIstrat < 1) {
09352
09353 if (fISW[4] >= 0) {
09354
09355 fPrintf(" MIGRAD FAILS WITH STRATEGY=0. WILL TRY WITH STRATEGY=1.");
09356
09357 }
09358
09359 fIstrat = 1;
09360
09361 }
09362
09363 goto L1;
09364
09365
09366
09367 L230:
09368
09369 if (iswtr >= 0) {
09370
09371 fPrintf(" MIGRAD TERMINATED WITHOUT CONVERGENCE.");
09372
09373 }
09374
09375 if (fISW[1] == 3) fISW[1] = 1;
09376
09377 fISW[3] = -1;
09378
09379 goto L400;
09380
09381
09382
09383 L300:
09384
09385 if (iswtr >= 0) {
09386
09387 fPrintf(" MIGRAD MINIMIZATION HAS CONVERGED.");
09388
09389 }
09390
09391 if (fItaur == 0) {
09392
09393 if (fIstrat >= 2 || (fIstrat == 1 && fISW[1] < 3)) {
09394
09395 if (fISW[4] >= 0) {
09396
09397 fPrintf(" MIGRAD WILL VERIFY CONVERGENCE AND ERROR MATRIX.");
09398
09399 }
09400
09401 mnhess();
09402
09403 mnwerr();
09404
09405 npsdf = 0;
09406
09407 if (fEDM > rhotol) goto L10;
09408
09409 }
09410
09411 }
09412
09413 fCstatu = "CONVERGED ";
09414
09415 fISW[3] = 1;
09416
09417
09418
09419 L400:
09420
09421 fCfrom = "MIGRAD ";
09422
09423 fNfcnfr = nfcnmg;
09424
09425 mninex(fX);
09426
09427 mnwerr();
09428
09429 if (iswtr >= 0) mnprin(3, fAmin);
09430
09431 if (iswtr >= 1) mnmatu(1);
09432
09433 }
09434
09435
09436
09437
09438
09439 void Midnight::mnmnos()
09440
09441 {
09442
09443
09444
09445
09446
09447
09448
09449
09450
09451
09452
09453
09454
09455
09456
09457
09458
09459 static MDouble val2mi, val2pl;
09460
09461 static MInt nbad, ilax, ilax2, ngood, nfcnmi, iin, knt;
09462
09463
09464
09465 if (fNpar <= 0) goto L700;
09466
09467 ngood = 0;
09468
09469 nbad = 0;
09470
09471 nfcnmi = fNfcn;
09472
09473
09474
09475 for (knt = 1; knt <= fNpar; ++knt) {
09476
09477 if (MInt(fWord7[1]) == 0) {
09478
09479 ilax = fNexofi[knt-1];
09480
09481 } else {
09482
09483 if (knt >= 7) break;
09484
09485 ilax = MInt(fWord7[knt]);
09486
09487 if (ilax == 0) break;
09488
09489 if (ilax > 0 && ilax <= fNu) {
09490
09491 if (fNiofex[ilax-1] > 0) goto L565;
09492
09493 }
09494
09495 fPrintf(" PARAMETER NUMBER %3d NOT VARIABLE. IGNORED.",ilax);
09496
09497 continue;
09498
09499 }
09500
09501 L565:
09502
09503
09504
09505 ilax2 = 0;
09506
09507 mnmnot(ilax, ilax2, val2pl, val2mi);
09508
09509 if (fLnewmn) goto L650;
09510
09511
09512
09513 iin = fNiofex[ilax-1];
09514
09515 if (fErp[iin-1] > 0) ++ngood;
09516
09517 else ++nbad;
09518
09519 if (fErn[iin-1] < 0) ++ngood;
09520
09521 else ++nbad;
09522
09523 }
09524
09525
09526
09527
09528
09529 fCfrom = "MINOS ";
09530
09531 fNfcnfr = nfcnmi;
09532
09533 fCstatu = "UNCHANGED ";
09534
09535 if (ngood == 0 && nbad == 0) goto L700;
09536
09537 if (ngood > 0 && nbad == 0) fCstatu = "SUCCESSFUL";
09538
09539 if (ngood == 0 && nbad > 0) fCstatu = "FAILURE ";
09540
09541 if (ngood > 0 && nbad > 0) fCstatu = "PROBLEMS ";
09542
09543 if (fISW[4] >= 0) mnprin(4, fAmin);
09544
09545 if (fISW[4] >= 2) mnmatu(0);
09546
09547 return;
09548
09549
09550
09551 L650:
09552
09553 fCfrom = "MINOS ";
09554
09555 fNfcnfr = nfcnmi;
09556
09557 fCstatu = "NEW MINIMU";
09558
09559 if (fISW[4] >= 0) mnprin(4, fAmin);
09560
09561 fPrintf(" NEW MINIMUM FOUND. GO BACK TO MINIMIZATION STEP.");
09562
09563 fPrintf(" =================================================");
09564
09565 fPrintf(" V");
09566
09567 fPrintf(" V");
09568
09569 fPrintf(" V");
09570
09571 fPrintf(" VVVVVVV");
09572
09573 fPrintf(" VVVVV");
09574
09575 fPrintf(" VVV");
09576
09577 fPrintf(" V");
09578
09579 fPrintf("");
09580
09581 return;
09582
09583 L700:
09584
09585 fPrintf(" THERE ARE NO MINOS ERRORS TO CALCULATE.");
09586
09587 }
09588
09589
09590
09591
09592
09593 void Midnight::mnmnot(MInt ilax, MInt ilax2, MDouble &val2pl, MDouble &val2mi)
09594
09595 {
09596
09597
09598
09599
09600
09601
09602
09603
09604
09605
09606
09607
09608
09609
09610
09611
09612
09613 MInt i__1;
09614
09615
09616
09617
09618
09619 static MDouble xdev[kMAXDIM], delu, aopt, eros;
09620
09621 static MDouble w[kMAXDIM], abest, xunit, dc, ut, sigsav, du1;
09622
09623 static MDouble fac, gcc[kMAXDIM], sig, sav;
09624
09625 static MInt marc, isig, mpar, ndex, imax, indx, ierr, i, j;
09626
09627 static MInt iercr, it, istrav, nfmxin, nlimit, isw2, isw4;
09628
09629 static MString csig;
09630
09631
09632
09633
09634
09635 isw2 = fISW[1];
09636
09637 isw4 = fISW[3];
09638
09639 sigsav = fEDM;
09640
09641 istrav = fIstrat;
09642
09643 dc = fDcovar;
09644
09645 fLnewmn = kFALSE;
09646
09647 fApsi = fEpsi*.5;
09648
09649 abest = fAmin;
09650
09651 mpar = fNpar;
09652
09653 nfmxin = fNfcnmx;
09654
09655 for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
09656
09657 i__1 = mpar*(mpar + 1) / 2;
09658
09659 for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
09660
09661 for (i = 1; i <= mpar; ++i) {
09662
09663 gcc[i-1] = fGlobcc[i-1];
09664
09665 w[i-1] = fWerr[i-1];
09666
09667 }
09668
09669 it = fNiofex[ilax-1];
09670
09671 fErp[it-1] = 0;
09672
09673 fErn[it-1] = 0;
09674
09675 mninex(fXt);
09676
09677 ut = fU[ilax-1];
09678
09679 if (fNvarl[ilax-1] == 1) {
09680
09681 fAlim[ilax-1] = ut - w[it-1]*100;
09682
09683 fBlim[ilax-1] = ut + w[it-1]*100;
09684
09685 }
09686
09687 ndex = it*(it + 1) / 2;
09688
09689 xunit = TMath_Sqrt(fUp / fVthmat[ndex-1]);
09690
09691 marc = 0;
09692
09693 for (i = 1; i <= mpar; ++i) {
09694
09695 if (i == it) continue;
09696
09697 ++marc;
09698
09699 imax = TMath_Max(it,i);
09700
09701 indx = imax*(imax-1) / 2 + TMath_Min(it,i);
09702
09703 xdev[marc-1] = xunit*fVthmat[indx-1];
09704
09705 }
09706
09707
09708
09709 mnfixp(it-1, ierr);
09710
09711 if (ierr > 0) {
09712
09713 fPrintf(" MINUIT ERROR. CANNOT FIX PARAMETER%4d INTERNAL%3d",ilax,it);
09714
09715 goto L700;
09716
09717 }
09718
09719
09720
09721
09722
09723
09724
09725 for (isig = 1; isig <= 2; ++isig) {
09726
09727 if (isig == 1) {
09728
09729 sig = 1;
09730
09731 csig = "POSI";
09732
09733 } else {
09734
09735 sig = -1;
09736
09737 csig = "NEGA";
09738
09739 }
09740
09741
09742
09743 if (fISW[4] > 1) {
09744
09745 fPrintf(" DETERMINATION OF %sTIVE MINOS ERROR FOR PARAMETER%d"
09746
09747 ,(const char*)csig,ilax
09748
09749 ,(const char*)fCpnam[ilax-1]);
09750
09751 }
09752
09753 if (fISW[1] <= 0) {
09754
09755 mnwarn("D", "MINOS", "NO COVARIANCE MATRIX.");
09756
09757 }
09758
09759 nlimit = fNfcn + nfmxin;
09760
09761 fIstrat = TMath_Max(istrav-1,0);
09762
09763 du1 = w[it-1];
09764
09765 fU[ilax-1] = ut + sig*du1;
09766
09767 fU[ilax-1] = TMath_Min(fU[ilax-1],fBlim[ilax-1]);
09768
09769 fU[ilax-1] = TMath_Max(fU[ilax-1],fAlim[ilax-1]);
09770
09771 delu = fU[ilax-1] - ut;
09772
09773
09774
09775 if (TMath_Abs(delu) / (TMath_Abs(ut) + TMath_Abs(fU[ilax-1])) < fEpsmac) goto L440;
09776
09777 fac = delu / w[it-1];
09778
09779 for (i = 1; i <= fNpar; ++i) {
09780
09781 fX[i-1] = fXt[i-1] + fac*xdev[i-1];
09782
09783 }
09784
09785 if (fISW[4] > 1) {
09786
09787 fPrintf(" PARAMETER%4d SET TO%11.3e + %10.3e = %12.3e",ilax,ut,delu,fU[ilax-1]);
09788
09789 }
09790
09791
09792
09793 fKe1cr = ilax;
09794
09795 fKe2cr = 0;
09796
09797 fXmidcr = fU[ilax-1];
09798
09799 fXdircr = delu;
09800
09801
09802
09803 fAmin = abest;
09804
09805 fNfcnmx = nlimit - fNfcn;
09806
09807 mncros(aopt, iercr);
09808
09809 if (abest - fAmin > fUp*.01) goto L650;
09810
09811 if (iercr == 1) goto L440;
09812
09813 if (iercr == 2) goto L450;
09814
09815 if (iercr == 3) goto L460;
09816
09817
09818
09819 eros = fXmidcr - ut + aopt*fXdircr;
09820
09821 if (fISW[4] > 1) {
09822
09823 fPrintf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d %10s, IS %12.4e"
09824
09825 ,(const char*)csig,ilax
09826
09827 ,(const char*)fCpnam[ilax-1],eros);
09828
09829 }
09830
09831 goto L480;
09832
09833
09834
09835 L440:
09836
09837 if (fISW[4] >= 1) {
09838
09839 fPrintf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d, %s EXCEEDS ITS LIMIT."
09840
09841 ,(const char*)csig,ilax
09842
09843 ,(const char*)fCpnam[ilax-1]);
09844
09845 }
09846
09847 eros = fUndefi;
09848
09849 goto L480;
09850
09851 L450:
09852
09853 if (fISW[4] >= 1) {
09854
09855 fPrintf(" THE %4sTIVE MINOS ERROR%4d REQUIRES MORE THAN%5d FUNCTION CALLS."
09856
09857 ,(const char*)csig,ilax,nfmxin);
09858
09859 }
09860
09861 eros = 0;
09862
09863 goto L480;
09864
09865 L460:
09866
09867 if (fISW[4] >= 1) {
09868
09869 fPrintf(" %4sTIVE MINOS ERROR NOT CALCULATED FOR PARAMETER%d"
09870
09871 ,(const char*)csig,ilax);
09872
09873 }
09874
09875 eros = 0;
09876
09877
09878
09879 L480:
09880
09881 if (fISW[4] > 1) {
09882
09883 fPrintf(" **************************************************************************");
09884
09885 }
09886
09887 if (sig < 0) {
09888
09889 fErn[it-1] = eros;
09890
09891 if (ilax2 > 0 && ilax2 <= fNu) val2mi = fU[ilax2-1];
09892
09893 } else {
09894
09895 fErp[it-1] = eros;
09896
09897 if (ilax2 > 0 && ilax2 <= fNu) val2pl = fU[ilax2-1];
09898
09899 }
09900
09901 }
09902
09903
09904
09905
09906
09907 fItaur = 1;
09908
09909 mnfree(1);
09910
09911 i__1 = mpar*(mpar + 1) / 2;
09912
09913 for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
09914
09915 for (i = 1; i <= mpar; ++i) {
09916
09917 fWerr[i-1] = w[i-1];
09918
09919 fGlobcc[i-1] = gcc[i-1];
09920
09921 fX[i-1] = fXt[i-1];
09922
09923 }
09924
09925 mninex(fX);
09926
09927 fEDM = sigsav;
09928
09929 fAmin = abest;
09930
09931 fISW[1] = isw2;
09932
09933 fISW[3] = isw4;
09934
09935 fDcovar = dc;
09936
09937 goto L700;
09938
09939
09940
09941 L650:
09942
09943 fLnewmn = kTRUE;
09944
09945 fISW[1] = 0;
09946
09947 fDcovar = 1;
09948
09949 fISW[3] = 0;
09950
09951 sav = fU[ilax-1];
09952
09953 fItaur = 1;
09954
09955 mnfree(1);
09956
09957 fU[ilax-1] = sav;
09958
09959 mnexin(fX);
09960
09961 fEDM = fBigedm;
09962
09963
09964
09965 L700:
09966
09967 fItaur = 0;
09968
09969 fNfcnmx = nfmxin;
09970
09971 fIstrat = istrav;
09972
09973 }
09974
09975
09976
09977
09978
09979 void Midnight::mnparm(MInt k1, MString cnamj, MDouble uk, MDouble wk, MDouble a, MDouble b, MInt &ierflg)
09980
09981 {
09982
09983
09984
09985
09986
09987
09988
09989
09990
09991
09992
09993
09994
09995
09996
09997
09998
09999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013 static MDouble vplu, a_small, gsmin, pinti, vminu, danger, sav, sav2;
10014
10015 static MInt ierr, kint, in, ix, ktofix, lastin, kinfix, nvl;
10016
10017 static MString cnamk, chbufi;
10018
10019
10020
10021 MInt k = k1+1;
10022
10023 cnamk = cnamj;
10024
10025 kint = fNpar;
10026
10027 if (k < 1 || k > fMaxext) {
10028
10029
10030
10031 fPrintf(" MINUIT USER ERROR. PARAMETER NUMBER IS %3d ALLOWED RANGE IS ONE TO %4d",k,fMaxext);
10032
10033 goto L800;
10034
10035 }
10036
10037
10038
10039 ktofix = 0;
10040
10041 if (fNvarl[k-1] < 0) goto L50;
10042
10043
10044
10045
10046
10047 for (ix = 1; ix <= fNpfix; ++ix) {
10048
10049 if (fIpfix[ix-1] == k) ktofix = k;
10050
10051 }
10052
10053 if (ktofix > 0) {
10054
10055 mnwarn("W", "PARAM DEF", "REDEFINING A FIXED PARAMETER.");
10056
10057 if (kint >= fMaxint) {
10058
10059 fPrintf(" CANNOT RELEASE. MAX NPAR EXCEEDED.");
10060
10061 goto L800;
10062
10063 }
10064
10065 mnfree(1);
10066
10067 }
10068
10069
10070
10071 if (fNiofex[k-1] > 0) kint = fNpar - 1;
10072
10073 L50:
10074
10075
10076
10077
10078
10079 if (fLphead && fISW[4] >= 0) {
10080
10081 fPrintf(" PARAMETER DEFINITIONS:");
10082
10083 fPrintf(" NO. NAME VALUE STEP SIZE LIMITS");
10084
10085 fLphead = kFALSE;
10086
10087 }
10088
10089 if (wk > 0) goto L122;
10090
10091
10092
10093 if (fISW[4] >= 0) {
10094
10095 fPrintf(" %5d %-10s %13.5e constant",k,(const char*)cnamk,uk);
10096
10097 }
10098
10099 nvl = 0;
10100
10101 goto L200;
10102
10103 L122:
10104
10105 if (a == 0 && b == 0) {
10106
10107
10108
10109 nvl = 1;
10110
10111 if (fISW[4] >= 0) {
10112
10113 fPrintf(" %5d %-10s %13.5e%13.5e no limits",k,(const char*)cnamk,uk,wk);
10114
10115 }
10116
10117 } else {
10118
10119
10120
10121 nvl = 4;
10122
10123 fLnolim = kFALSE;
10124
10125 if (fISW[4] >= 0) {
10126
10127 fPrintf(" %5d '%-10s' %13.5e%13.5e %13.5e%13.5e",k,(const char*)cnamk,uk,wk,a,b);
10128
10129 }
10130
10131 }
10132
10133
10134
10135 ++kint;
10136
10137 if (kint > fMaxint) {
10138
10139 fPrintf(" MINUIT USER ERROR. TOO MANY VARIABLE PARAMETERS.");
10140
10141 goto L800;
10142
10143 }
10144
10145 if (nvl == 1) goto L200;
10146
10147 if (a == b) {
10148
10149 fPrintf(" USER ERROR IN MINUIT PARAMETER");
10150
10151 fPrintf(" DEFINITION");
10152
10153 fPrintf(" UPPER AND LOWER LIMITS EQUAL.");
10154
10155 goto L800;
10156
10157 }
10158
10159 if (b < a) {
10160
10161 sav = b;
10162
10163 b = a;
10164
10165 a = sav;
10166
10167 mnwarn("W", "PARAM DEF", "PARAMETER LIMITS WERE REVERSED.");
10168
10169 if (fLwarn) fLphead = kTRUE;
10170
10171 }
10172
10173 if (b - a > 1e7) {
10174
10175 mnwarn("W", "PARAM DEF", Form("LIMITS ON PARAM%d TOO FAR APART.",k));
10176
10177 if (fLwarn) fLphead = kTRUE;
10178
10179 }
10180
10181 danger = (b - uk)*(uk - a);
10182
10183 if (danger < 0) {
10184
10185 mnwarn("W", "PARAM DEF", "STARTING VALUE OUTSIDE LIMITS.");
10186
10187 }
10188
10189 if (danger == 0) {
10190
10191 mnwarn("W", "PARAM DEF", "STARTING VALUE IS AT LIMIT.");
10192
10193 }
10194
10195 L200:
10196
10197
10198
10199
10200
10201 fCfrom = "PARAMETR";
10202
10203 fNfcnfr = fNfcn;
10204
10205 fCstatu = "NEW VALUES";
10206
10207 fNu = TMath_Max(fNu,k);
10208
10209 fCpnam[k-1] = cnamk;
10210
10211 fU[k-1] = uk;
10212
10213 fAlim[k-1] = a;
10214
10215 fBlim[k-1] = b;
10216
10217 fNvarl[k-1] = nvl;
10218
10219 mnrset(1);
10220
10221
10222
10223
10224
10225 lastin = 0;
10226
10227 for (ix = 1; ix <= k-1; ++ix) { if (fNiofex[ix-1] > 0) ++lastin; }
10228
10229
10230
10231 if (kint == fNpar) goto L280;
10232
10233 if (kint > fNpar) {
10234
10235
10236
10237 for (in = fNpar; in >= lastin + 1; --in) {
10238
10239 ix = fNexofi[in-1];
10240
10241 fNiofex[ix-1] = in + 1;
10242
10243 fNexofi[in] = ix;
10244
10245 fX[in] = fX[in-1];
10246
10247 fXt[in] = fXt[in-1];
10248
10249 fDirin[in] = fDirin[in-1];
10250
10251 fG2[in] = fG2[in-1];
10252
10253 fGstep[in] = fGstep[in-1];
10254
10255 }
10256
10257 } else {
10258
10259
10260
10261 for (in = lastin + 1; in <= kint; ++in) {
10262
10263 ix = fNexofi[in];
10264
10265 fNiofex[ix-1] = in;
10266
10267 fNexofi[in-1] = ix;
10268
10269 fX[in-1] = fX[in];
10270
10271 fXt[in-1] = fXt[in];
10272
10273 fDirin[in-1] = fDirin[in];
10274
10275 fG2[in-1] = fG2[in];
10276
10277 fGstep[in-1] = fGstep[in];
10278
10279 }
10280
10281 }
10282
10283 L280:
10284
10285 ix = k;
10286
10287 fNiofex[ix-1] = 0;
10288
10289 fNpar = kint;
10290
10291
10292
10293 if (nvl > 0) {
10294
10295 in = lastin + 1;
10296
10297 fNexofi[in-1] = ix;
10298
10299 fNiofex[ix-1] = in;
10300
10301 sav = fU[ix-1];
10302
10303 mnpint(sav, ix-1, pinti);
10304
10305 fX[in-1] = pinti;
10306
10307 fXt[in-1] = fX[in-1];
10308
10309 fWerr[in-1] = wk;
10310
10311 sav2 = sav + wk;
10312
10313 mnpint(sav2, ix-1, pinti);
10314
10315 vplu = pinti - fX[in-1];
10316
10317 sav2 = sav - wk;
10318
10319 mnpint(sav2, ix-1, pinti);
10320
10321 vminu = pinti - fX[in-1];
10322
10323 fDirin[in-1] = (TMath_Abs(vplu) + TMath_Abs(vminu))*.5;
10324
10325 fG2[in-1] = fUp*2 / (fDirin[in-1]*fDirin[in-1]);
10326
10327 gsmin = fEpsma2*8*TMath_Abs(fX[in-1]);
10328
10329 fGstep[in-1] = TMath_Max(gsmin,fDirin[in-1]*.1);
10330
10331 if (fAmin != fUndefi) {
10332
10333 a_small = TMath_Sqrt(fEpsma2*(fAmin + fUp) / fUp);
10334
10335 fGstep[in-1] = TMath_Max(gsmin,a_small*fDirin[in-1]);
10336
10337 }
10338
10339 fGrd[in-1] = fG2[in-1]*fDirin[in-1];
10340
10341
10342
10343 if (fNvarl[k-1] > 1) {
10344
10345 if (fGstep[in-1] > .5) fGstep[in-1] = .5;
10346
10347 fGstep[in-1] = -fGstep[in-1];
10348
10349 }
10350
10351 }
10352
10353 if (ktofix > 0) {
10354
10355 kinfix = fNiofex[ktofix-1];
10356
10357 if (kinfix > 0) mnfixp(kinfix-1, ierr);
10358
10359 if (ierr > 0) goto L800;
10360
10361 }
10362
10363 ierflg = 0;
10364
10365 return;
10366
10367
10368
10369 L800:
10370
10371 ierflg = 1;
10372
10373 }
10374
10375
10376
10377
10378
10379 void Midnight::mnpars(MString &crdbuf, MInt &icondn)
10380
10381 {
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409 static MDouble a, b, plist[30], fk, uk, wk, xk;
10410
10411 static MInt ierr, kapo1, kapo2;
10412
10413 static MInt k, llist, ibegin, lenbuf, istart, lnc, icy;
10414
10415 static MString cnamk, comand, celmnt, ctemp;
10416
10417 char stmp[128];
10418
10419
10420
10421 lenbuf = strlen((const char*)crdbuf);
10422
10423
10424
10425 kapo1 = strspn((const char*)crdbuf, "'");
10426
10427 if (kapo1 == 0) goto L150;
10428
10429 kapo2 = strspn((const char*)crdbuf + kapo1, "'");
10430
10431 if (kapo2 == 0) goto L150;
10432
10433
10434
10435 kapo2 += kapo1;
10436
10437
10438
10439 for (istart = 1; istart <= kapo1-1; ++istart) {
10440
10441 if (crdbuf[istart-1] != ' ') goto L120;
10442
10443 }
10444
10445 goto L210;
10446
10447 L120:
10448
10449
10450
10451 celmnt = crdbuf(istart-1, kapo1-istart);
10452
10453 scanf((const char*)celmnt,fk);
10454
10455 k = MInt(fk);
10456
10457 if (k <= 0) goto L210;
10458
10459 cnamk = "PARAM ";
10460
10461 cnamk += celmnt;
10462
10463 if (kapo2 - kapo1 > 1) {
10464
10465 cnamk = crdbuf(kapo1, kapo2-1-kapo1);
10466
10467 }
10468
10469
10470
10471 for (icy = kapo2 + 1; icy <= lenbuf; ++icy) {
10472
10473 if (crdbuf[icy-1] == ',') goto L139;
10474
10475 if (crdbuf[icy-1] != ' ') goto L140;
10476
10477 }
10478
10479 uk = 0;
10480
10481 wk = 0;
10482
10483 a = 0;
10484
10485 b = 0;
10486
10487 goto L170;
10488
10489 L139:
10490
10491 ++icy;
10492
10493 L140:
10494
10495 ibegin = icy;
10496
10497 ctemp = crdbuf(ibegin-1,lenbuf-ibegin);
10498
10499 mncrck(ctemp, 20, comand, lnc, 30, plist, llist, ierr, fIsyswr);
10500
10501 if (ierr > 0) goto L180;
10502
10503 uk = plist[0];
10504
10505 wk = 0;
10506
10507 if (llist >= 2) wk = plist[1];
10508
10509 a = 0;
10510
10511 if (llist >= 3) a = plist[2];
10512
10513 b = 0;
10514
10515 if (llist >= 4) b = plist[3];
10516
10517 goto L170;
10518
10519
10520
10521 L150:
10522
10523 scanf((const char*)crdbuf,xk,stmp,uk,wk,a,b);
10524
10525 cnamk = stmp;
10526
10527 k = MInt(xk);
10528
10529 if (k == 0) goto L210;
10530
10531
10532
10533 L170:
10534
10535 mnparm(k-1, cnamk, uk, wk, a, b, ierr);
10536
10537 icondn = ierr;
10538
10539 return;
10540
10541
10542
10543 L180:
10544
10545 icondn = 1;
10546
10547 return;
10548
10549
10550
10551 L210:
10552
10553 icondn = 2;
10554
10555 }
10556
10557
10558
10559
10560
10561 void Midnight::mnpfit(MDouble *parx2p, MDouble *pary2p, MInt npar2p, MDouble *coef2p, MDouble &sdev2p)
10562
10563 {
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591 static MDouble a, f, s, t, y, s2, x2, x3, x4, y2, cz[3], xm, xy, x2y;
10592
10593 x2 = x3 = 0;
10594
10595 MInt i;
10596
10597
10598
10599
10600
10601 --coef2p;
10602
10603 --pary2p;
10604
10605 --parx2p;
10606
10607
10608
10609
10610
10611 for (i = 1; i <= 3; ++i) { cz[i-1] = 0; }
10612
10613 sdev2p = 0;
10614
10615 if (npar2p < 3) goto L10;
10616
10617 f = (MDouble) (npar2p);
10618
10619
10620
10621 xm = 0;
10622
10623 for (i = 1; i <= npar2p; ++i) { xm += parx2p[i]; }
10624
10625 xm /= f;
10626
10627 x2 = 0;
10628
10629 x3 = 0;
10630
10631 x4 = 0;
10632
10633 y = 0;
10634
10635 y2 = 0;
10636
10637 xy = 0;
10638
10639 x2y = 0;
10640
10641 for (i = 1; i <= npar2p; ++i) {
10642
10643 s = parx2p[i] - xm;
10644
10645 t = pary2p[i];
10646
10647 s2 = s*s;
10648
10649 x2 += s2;
10650
10651 x3 += s*s2;
10652
10653 x4 += s2*s2;
10654
10655 y += t;
10656
10657 y2 += t*t;
10658
10659 xy += s*t;
10660
10661 x2y += s2*t;
10662
10663 }
10664
10665 a = (f*x4 - x2*x2)*x2 - f*(x3*x3);
10666
10667 if (a == 0) goto L10;
10668
10669 cz[2] = (x2*(f*x2y - x2*y) - f*x3*xy) / a;
10670
10671 cz[1] = (xy - x3*cz[2]) / x2;
10672
10673 cz[0] = (y - x2*cz[2]) / f;
10674
10675 if (npar2p == 3) goto L6;
10676
10677 sdev2p = y2 - (cz[0]*y + cz[1]*xy + cz[2]*x2y);
10678
10679 if (sdev2p < 0) sdev2p = 0;
10680
10681 sdev2p /= f - 3;
10682
10683 L6:
10684
10685 cz[0] += xm*(xm*cz[2] - cz[1]);
10686
10687 cz[1] -= xm*2*cz[2];
10688
10689 L10:
10690
10691 for (i = 1; i <= 3; ++i) { coef2p[i] = cz[i-1]; }
10692
10693 }
10694
10695
10696
10697
10698
10699 void Midnight::mnpint(MDouble &pexti, MInt i1, MDouble &pinti)
10700
10701 {
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715 static MDouble a, alimi, blimi, yy, yy2;
10716
10717 static MInt igo;
10718
10719 static MString chbuf2, chbufi;
10720
10721
10722
10723 MInt i = i1+1;
10724
10725 pinti = pexti;
10726
10727 igo = fNvarl[i-1];
10728
10729 if (igo == 4) {
10730
10731
10732
10733 alimi = fAlim[i-1];
10734
10735 blimi = fBlim[i-1];
10736
10737 yy = (pexti - alimi)*2 / (blimi - alimi) - 1;
10738
10739 yy2 = yy*yy;
10740
10741 if (yy2 >= 1 - fEpsma2) {
10742
10743 if (yy < 0) {
10744
10745 a = fVlimlo;
10746
10747 chbuf2 = " IS AT ITS LOWER ALLOWED LIMIT.";
10748
10749 } else {
10750
10751 a = fVlimhi;
10752
10753 chbuf2 = " IS AT ITS UPPER ALLOWED LIMIT.";
10754
10755 }
10756
10757 pinti = a;
10758
10759 pexti = alimi + (blimi - alimi)*.5*(TMath_Sin(a) + 1);
10760
10761 fLimset = kTRUE;
10762
10763 if (yy2 > 1) chbuf2 = " BROUGHT BACK INSIDE LIMITS.";
10764
10765 mnwarn("W", fCfrom, Form("VARIABLE%d%s",i,(const char*)chbuf2));
10766
10767 } else {
10768
10769 pinti = TMath_ASin(yy);
10770
10771 }
10772
10773 }
10774
10775 }
10776
10777
10778
10779
10780
10781 void Midnight::mnplot(MDouble *xpt, MDouble *ypt, MString *chpt, MInt nxypt, MInt npagwd, MInt npagln)
10782
10783 {
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809 static MString cdot = ".";
10810
10811 static MString cslash = "/";
10812
10813 static MString cblank = " ";
10814
10815
10816
10817
10818
10819 static MDouble xmin, ymin, xmax, ymax, savx, savy, yprt;
10820
10821 static MDouble bwidx, bwidy, xbest, ybest, ax, ay, bx, by;
10822
10823 static MDouble xvalus[12], any, dxx, dyy;
10824
10825 static MInt iten, i, j, k, maxnx, maxny, iquit, ni, linodd;
10826
10827 static MInt nxbest, nybest, km1, ibk, isp1, nx, ny, ks, ix;
10828
10829 static MString cline, chsav, chmess, chbest, ctemp;
10830
10831 static MBool overpr;
10832
10833
10834
10835
10836
10837
10838
10839 maxnx = TMath_Min(npagwd-20,100);
10840
10841 if (maxnx < 10) maxnx = 10;
10842
10843 maxny = npagln;
10844
10845 if (maxny < 10) maxny = 10;
10846
10847 if (nxypt <= 1) return;
10848
10849 xbest = xpt[0];
10850
10851 ybest = ypt[0];
10852
10853 chbest = chpt[0];
10854
10855
10856
10857 km1 = nxypt - 1;
10858
10859 for (i = 1; i <= km1; ++i) {
10860
10861 iquit = 0;
10862
10863 ni = nxypt - i;
10864
10865 for (j = 1; j <= ni; ++j) {
10866
10867 if (ypt[j-1] > ypt[j]) continue;
10868
10869 savx = xpt[j-1];
10870
10871 xpt[j-1] = xpt[j];
10872
10873 xpt[j] = savx;
10874
10875 savy = ypt[j-1];
10876
10877 ypt[j-1] = ypt[j];
10878
10879 ypt[j] = savy;
10880
10881 chsav = chpt[j-1];
10882
10883 chpt[j-1]= chpt[j];
10884
10885 chpt[j] = chsav;
10886
10887 iquit = 1;
10888
10889 }
10890
10891 if (iquit == 0) break;
10892
10893 }
10894
10895
10896
10897 xmax = xpt[0];
10898
10899 xmin = xmax;
10900
10901 for (i = 1; i <= nxypt; ++i) {
10902
10903 if (xpt[i-1] > xmax) xmax = xpt[i-1];
10904
10905 if (xpt[i-1] < xmin) xmin = xpt[i-1];
10906
10907 }
10908
10909 dxx = (xmax - xmin)*.001;
10910
10911 xmax += dxx;
10912
10913 xmin -= dxx;
10914
10915 mnbins(xmin, xmax, maxnx, xmin, xmax, nx, bwidx);
10916
10917 ymax = ypt[0];
10918
10919 ymin = ypt[nxypt-1];
10920
10921 if (ymax == ymin) ymax = ymin + 1;
10922
10923 dyy = (ymax - ymin)*.001;
10924
10925 ymax += dyy;
10926
10927 ymin -= dyy;
10928
10929 mnbins(ymin, ymax, maxny, ymin, ymax, ny, bwidy);
10930
10931 any = (MDouble) ny;
10932
10933
10934
10935 if (chbest == cblank) goto L50;
10936
10937 xbest = (xmax + xmin)*.5;
10938
10939 ybest = (ymax + ymin)*.5;
10940
10941 L50:
10942
10943
10944
10945 ax = 1 / bwidx;
10946
10947 ay = 1 / bwidy;
10948
10949 bx = -ax*xmin + 2;
10950
10951 by = -ay*ymin - 2;
10952
10953
10954
10955 for (i = 1; i <= nxypt; ++i) {
10956
10957 xpt[i-1] = ax*xpt[i-1] + bx;
10958
10959 ypt[i-1] = any - ay*ypt[i-1] - by;
10960
10961 }
10962
10963 nxbest = MInt((ax*xbest + bx));
10964
10965 nybest = MInt((any - ay*ybest - by));
10966
10967
10968
10969 ny += 2;
10970
10971 nx += 2;
10972
10973 isp1 = 1;
10974
10975 linodd = 1;
10976
10977 overpr = kFALSE;
10978
10979
10980
10981 for (i = 1; i <= ny; ++i) {
10982
10983 cline.resize(nx+2);
10984
10985 for (ibk = 1; ibk <= nx; ++ibk) { cline[ibk-1] = ' '; }
10986
10987
10988
10989 cline(nx+1) = '\0';
10990
10991 cline(0) = '.';
10992
10993 cline(nx-1) = '.';
10994
10995 cline(nxbest-1) = '.';
10996
10997 if (i != 1 && i != nybest && i != ny) goto L320;
10998
10999 for (j = 1; j <= nx; ++j) { cline(j-1) = '.'; }
11000
11001 L320:
11002
11003 yprt = ymax - MDouble(i-1)*bwidy;
11004
11005 if (isp1 > nxypt) goto L350;
11006
11007
11008
11009 for (k = isp1; k <= nxypt; ++k) {
11010
11011 ks = MInt(ypt[k-1]);
11012
11013 if (ks > i) goto L345;
11014
11015 ix = MInt(xpt[k-1]);
11016
11017 if (cline(ix-1) == '.') goto L340;
11018
11019 if (cline(ix-1) == ' ') goto L340;
11020
11021 if (cline(ix-1) == chpt[k-1](0)) continue;
11022
11023 overpr = kTRUE;
11024
11025
11026
11027
11028
11029 cline(ix-1) = '&';
11030
11031 continue;
11032
11033 L340:
11034
11035 cline(ix-1) = chpt[k-1](0);
11036
11037 }
11038
11039 isp1 = nxypt + 1;
11040
11041 goto L350;
11042
11043 L345:
11044
11045 isp1 = k;
11046
11047 L350:
11048
11049 if (linodd == 1 || i == ny) goto L380;
11050
11051 linodd = 1;
11052
11053 ctemp = cline(0,nx);
11054
11055 fPrintf(" %s",(const char*)ctemp);
11056
11057 goto L400;
11058
11059 L380:
11060
11061 ctemp = cline(0,nx);
11062
11063 fPrintf(" %14.7g ..%s",yprt,(const char*)ctemp);
11064
11065 linodd = 0;
11066
11067 L400:
11068
11069 ;
11070
11071 }
11072
11073
11074
11075 for (ibk = 1; ibk <= nx; ++ibk) {
11076
11077 cline[ibk-1] = ' ';
11078
11079 if (ibk % 10 == 1) cline[ibk-1] = '/';
11080
11081 }
11082
11083 fPrintf(" %s",(const char*)cline);
11084
11085
11086
11087 for (ibk = 1; ibk <= 12; ++ibk) {
11088
11089 xvalus[ibk-1] = xmin + MDouble(ibk-1)*10*bwidx;
11090
11091 }
11092
11093 fPrintf(" ");
11094
11095 iten = (nx + 9) / 10;
11096
11097
11098
11099
11100
11101 for (ibk = 1; ibk <= iten; ++ibk) {
11102
11103 fPrintf(" %9.4g", xvalus[ibk-1]);
11104
11105 }
11106
11107
11108
11109
11110
11111 chmess = " ";
11112
11113 if (overpr) chmess = " Overprint character is &";
11114
11115 fPrintf(" ONE COLUMN=%13.7g%s",bwidx,(const char*)chmess);
11116
11117 }
11118
11119
11120
11121
11122
11123 void Midnight::mnpout(MInt iuext1, MString& chnam, MDouble &val, MDouble &err, MDouble &xlolim, MDouble &xuplim, MInt &iuint)
11124
11125 {
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161 static MInt iint, iext, nvl;
11162
11163
11164
11165 MInt iuext = iuext1 + 1;
11166
11167 xlolim = 0;
11168
11169 xuplim = 0;
11170
11171 err = 0;
11172
11173 if (iuext == 0) goto L100;
11174
11175 if (iuext < 0) {
11176
11177
11178
11179 iint = -(iuext);
11180
11181 if (iint > fNpar) goto L100;
11182
11183 iext = fNexofi[iint-1];
11184
11185 iuint = iext;
11186
11187 } else {
11188
11189
11190
11191 iext = iuext;
11192
11193 if (iext == 0) goto L100;
11194
11195 if (iext > fNu) goto L100;
11196
11197 iint = fNiofex[iext-1];
11198
11199 iuint = iint;
11200
11201 }
11202
11203
11204
11205 nvl = fNvarl[iext-1];
11206
11207 if (nvl < 0) goto L100;
11208
11209 chnam = fCpnam[iext-1];
11210
11211 val = fU[iext-1];
11212
11213 if (iint > 0) err = fWerr[iint-1];
11214
11215 if (nvl == 4) {
11216
11217 xlolim = fAlim[iext-1];
11218
11219 xuplim = fBlim[iext-1];
11220
11221 }
11222
11223 return;
11224
11225
11226
11227 L100:
11228
11229 iuint = -1;
11230
11231 chnam = "undefined";
11232
11233 val = 0;
11234
11235 }
11236
11237
11238
11239
11240
11241 void Midnight::mnprin(MInt inkode, MDouble fval)
11242
11243 {
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277 static MString cblank = " ";
11278
11279 static MString cnambf = " ";
11280
11281
11282
11283
11284
11285 MDouble dcmax, x1, x2, x3, dc;
11286
11287 x2 = x3 = 0;
11288
11289 static MInt nadd, i, k, l, m, ikode, ic, nc, ntrail, lbl;
11290
11291 static MString chedm;
11292
11293 static MString colhdl[6], colhdu[6], cx2, cx3, cheval;
11294
11295
11296
11297 if (fNu == 0) {
11298
11299 fPrintf(" THERE ARE CURRENTLY NO PARAMETERS DEFINED");
11300
11301 return;
11302
11303 }
11304
11305
11306
11307 ikode = inkode;
11308
11309 if (inkode == 5) {
11310
11311 ikode = fISW[1] + 1;
11312
11313 if (ikode > 3) ikode = 3;
11314
11315 }
11316
11317
11318
11319 for (k = 1; k <= 6; ++k) {
11320
11321 colhdu[k-1] = "UNDEFINED";
11322
11323 colhdl[k-1] = "COLUMN HEAD";
11324
11325 }
11326
11327
11328
11329 if (ikode == 4 && fCtitl != fCundef) {
11330
11331 fPrintf(" MINUIT TASK: %s",(const char*)fCtitl);
11332
11333 }
11334
11335
11336
11337 if (fval == fUndefi) cheval = " unknown ";
11338
11339 else cheval = Form("%g",fval);
11340
11341
11342
11343 if (fEDM == fBigedm) chedm = " unknown ";
11344
11345 else chedm = Form("%g",fEDM);
11346
11347
11348
11349 nc = fNfcn - fNfcnfr;
11350
11351 fPrintf(" FCN=%s FROM %8s STATUS=%10s %6d CALLS %9d TOTAL"
11352
11353 ,(const char*)cheval
11354
11355 ,(const char*)fCfrom
11356
11357 ,(const char*)fCstatu,nc,fNfcn);
11358
11359 m = fISW[1];
11360
11361 if (m == 0 || m == 2 || fDcovar == 0) {
11362
11363 fPrintf(" EDM=%s STRATEGY=%2d %s"
11364
11365 ,(const char*)chedm,fIstrat
11366
11367 ,(const char*)fCovmes[m]);
11368
11369 } else {
11370
11371 dcmax = 1;
11372
11373 dc = TMath_Min(fDcovar,dcmax)*100;
11374
11375 fPrintf(" EDM=%s STRATEGY=%2d ERROR MATRIX UNCERTAINTY %5.1f per cent"
11376
11377 ,(const char*)chedm,fIstrat,dc);
11378
11379 }
11380
11381
11382
11383 if (ikode == 0) return;
11384
11385
11386
11387 ntrail = 10;
11388
11389 for (i = 1; i <= fNu; ++i) {
11390
11391 if (fNvarl[i-1] < 0) continue;
11392
11393 for (ic = 10; ic >= 1; --ic) {
11394
11395 if (fCpnam[i-1](ic-1,1) != " ") goto L16;
11396
11397 }
11398
11399 ic = 1;
11400
11401 L16:
11402
11403 lbl = 10 - ic;
11404
11405 if (lbl < ntrail) ntrail = lbl;
11406
11407 }
11408
11409 nadd = ntrail / 2 + 1;
11410
11411 if (ikode == 1) {
11412
11413 colhdu[0] = " ";
11414
11415 colhdl[0] = " ERROR ";
11416
11417 colhdu[1] = " PHYSICAL";
11418
11419 colhdu[2] = " LIMITS ";
11420
11421 colhdl[1] = " NEGATIVE ";
11422
11423 colhdl[2] = " POSITIVE ";
11424
11425 }
11426
11427 if (ikode == 2) {
11428
11429 colhdu[0] = " ";
11430
11431 colhdl[0] = " ERROR ";
11432
11433 colhdu[1] = " INTERNAL ";
11434
11435 colhdl[1] = " STEP SIZE ";
11436
11437 colhdu[2] = " INTERNAL ";
11438
11439 colhdl[2] = " VALUE ";
11440
11441 }
11442
11443 if (ikode == 3) {
11444
11445 colhdu[0] = " ";
11446
11447 colhdl[0] = " ERROR ";
11448
11449 colhdu[1] = " STEP ";
11450
11451 colhdl[1] = " SIZE ";
11452
11453 colhdu[2] = " FIRST ";
11454
11455 colhdl[2] = " DERIVATIVE ";
11456
11457 }
11458
11459 if (ikode == 4) {
11460
11461 colhdu[0] = " PARABOLIC ";
11462
11463 colhdl[0] = " ERROR ";
11464
11465 colhdu[1] = " MINOS ";
11466
11467 colhdu[2] = "ERRORS ";
11468
11469 colhdl[1] = " NEGATIVE ";
11470
11471 colhdl[2] = " POSITIVE ";
11472
11473 }
11474
11475
11476
11477 if (ikode != 4) {
11478
11479 if (fISW[1] < 3) colhdu[0] = " APPROXIMATE ";
11480
11481 if (fISW[1] < 1) colhdu[0] = " CURRENT GUESS";
11482
11483 }
11484
11485 fPrintf(" EXT PARAMETER %-14s%-14s%-14s",(const char*)colhdu[0]
11486
11487 ,(const char*)colhdu[1]
11488
11489 ,(const char*)colhdu[2]);
11490
11491 fPrintf(" NO. NAME VALUE %-14s%-14s%-14s",(const char*)colhdl[0]
11492
11493 ,(const char*)colhdl[1]
11494
11495 ,(const char*)colhdl[2]);
11496
11497
11498
11499 for (i = 1; i <= fNu; ++i) {
11500
11501 if (fNvarl[i-1] < 0) continue;
11502
11503 l = fNiofex[i-1];
11504
11505 cnambf = cblank(0,nadd);
11506
11507 cnambf += fCpnam[i-1];
11508
11509 if (l == 0) goto L55;
11510
11511
11512
11513 x1 = fWerr[l-1];
11514
11515 cx2 = "PLEASE GET X..";
11516
11517 cx3 = "PLEASE GET X..";
11518
11519 if (ikode == 1) {
11520
11521 if (fNvarl[i-1] <= 1) {
11522
11523 fPrintf("%4d %-11s%14.5e%14.5e",i,(const char*)cnambf,fU[i-1],x1);
11524
11525 continue;
11526
11527 } else {
11528
11529 x2 = fAlim[i-1];
11530
11531 x3 = fBlim[i-1];
11532
11533 }
11534
11535 }
11536
11537 if (ikode == 2) {
11538
11539 x2 = fDirin[l-1];
11540
11541 x3 = fX[l-1];
11542
11543 }
11544
11545 if (ikode == 3) {
11546
11547 x2 = fDirin[l-1];
11548
11549 x3 = fGrd[l-1];
11550
11551 if (fNvarl[i-1] > 1 && TMath_Abs(TMath_Cos(fX[l-1])) < .001) {
11552
11553 cx3 = "** at limit **";
11554
11555 }
11556
11557 }
11558
11559 if (ikode == 4) {
11560
11561 x2 = fErn[l-1];
11562
11563 if (x2 == 0) cx2 = " ";
11564
11565 if (x2 == fUndefi) cx2 = " at limit ";
11566
11567 x3 = fErp[l-1];
11568
11569 if (x3 == 0) cx3 = " ";
11570
11571 if (x3 == fUndefi) cx3 = " at limit ";
11572
11573 }
11574
11575 if (cx2 == "PLEASE GET X..") cx2 = Form("%14.5e",x2);
11576
11577 if (cx3 == "PLEASE GET X..") cx3 = Form("%14.5e",x3);
11578
11579 fPrintf("%4d %-11s%14.5e%14.5e%-14s%-14s",i
11580
11581 ,(const char*)cnambf,fU[i-1],x1
11582
11583 ,(const char*)cx2,(const char*)cx3);
11584
11585
11586
11587
11588
11589 if (fNvarl[i-1] <= 1 || ikode == 3) continue;
11590
11591 if (TMath_Abs(TMath_Cos(fX[l-1])) < .001) {
11592
11593 fPrintf(" WARNING - - ABOVE PARAMETER IS AT LIMIT.");
11594
11595 }
11596
11597 continue;
11598
11599
11600
11601
11602
11603 L55:
11604
11605 colhdu[0] = " constant ";
11606
11607 if (fNvarl[i-1] > 0) colhdu[0] = " fixed ";
11608
11609 if (fNvarl[i-1] == 4 && ikode == 1) {
11610
11611 fPrintf("%4d %-11s%14.5e%-14s%14.5e%14.5e",i
11612
11613 ,(const char*)cnambf,fU[i-1]
11614
11615 ,(const char*)colhdu[0],fAlim[i-1],fBlim[i-1]);
11616
11617 } else {
11618
11619 fPrintf("%4d %-11s%14.5e%s",i
11620
11621 ,(const char*)cnambf,fU[i-1],(const char*)colhdu[0]);
11622
11623 }
11624
11625 }
11626
11627
11628
11629 if (fUp != fUpdflt) {
11630
11631 fPrintf(" ERR DEF= %g",fUp);
11632
11633 }
11634
11635 return;
11636
11637 }
11638
11639
11640
11641
11642
11643 void Midnight::mnpsdf()
11644
11645 {
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659 static MDouble s[kMAXDIM], dgmin, padd, pmin, pmax, dg, epspdf, epsmin;
11660
11661 static MInt ndex, i, j, ndexd, ip, ifault;
11662
11663 static MString chbuff, ctemp;
11664
11665
11666
11667 epsmin = 1e-6;
11668
11669 epspdf = TMath_Max(epsmin,fEpsma2);
11670
11671 dgmin = fVhmat[0];
11672
11673
11674
11675 for (i = 1; i <= fNpar; ++i) {
11676
11677 ndex = i*(i + 1) / 2;
11678
11679 if (fVhmat[ndex-1] <= 0) {
11680
11681 mnwarn("W", fCfrom, Form("Negative diagonal element %d in Error Matrix",i));
11682
11683 }
11684
11685 if (fVhmat[ndex-1] < dgmin) dgmin = fVhmat[ndex-1];
11686
11687 }
11688
11689 if (dgmin <= 0) {
11690
11691 dg = epspdf + 1 - dgmin;
11692
11693 mnwarn("W", fCfrom, Form("%g added to diagonal of error matrix",dg));
11694
11695 } else {
11696
11697 dg = 0;
11698
11699 }
11700
11701
11702
11703 for (i = 1; i <= fNpar; ++i) {
11704
11705 ndex = i*(i-1) / 2;
11706
11707 ndexd = ndex + i;
11708
11709 fVhmat[ndexd-1] += dg;
11710
11711 s[i-1] = 1 / TMath_Sqrt(fVhmat[ndexd-1]);
11712
11713 for (j = 1; j <= i; ++j) {
11714
11715 ++ndex;
11716
11717 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1]*s[i-1]*s[j-1];
11718
11719 }
11720
11721 }
11722
11723
11724
11725 mneig(fP, fMaxint, fNpar, fMaxint, fPstar, epspdf, ifault);
11726
11727 pmin = fPstar[0];
11728
11729 pmax = fPstar[0];
11730
11731 for (ip = 2; ip <= fNpar; ++ip) {
11732
11733 if (fPstar[ip-1] < pmin) pmin = fPstar[ip-1];
11734
11735 if (fPstar[ip-1] > pmax) pmax = fPstar[ip-1];
11736
11737 }
11738
11739 pmax = TMath_Max(TMath_Abs(pmax),MDouble(1));
11740
11741 if (pmin <= 0 && fLwarn || fISW[4] >= 2) {
11742
11743 fPrintf(" EIGENVALUES OF SECOND-DERIVATIVE MATRIX:");
11744
11745 ctemp = " ";
11746
11747 for (ip = 1; ip <= fNpar; ++ip) {
11748
11749 ctemp += Form(" %11.4e",fPstar[ip-1]);
11750
11751 }
11752
11753 fPrintf((const char*)ctemp);
11754
11755 }
11756
11757 if (pmin > epspdf*pmax) return;
11758
11759 if (fISW[1] == 3) fISW[1] = 2;
11760
11761 padd = pmax*.001 - pmin;
11762
11763 for (ip = 1; ip <= fNpar; ++ip) {
11764
11765 ndex = ip*(ip + 1) / 2;
11766
11767 fVhmat[ndex-1] *= padd + 1;
11768
11769 }
11770
11771 fCstatu = "NOT POSDEF";
11772
11773 mnwarn("W", fCfrom, Form("MATRIX FORCED POS-DEF BY ADDING %f TO DIAGONAL.",padd));
11774
11775
11776
11777 }
11778
11779
11780
11781
11782
11783 void Midnight::mnrazz(MDouble ynew, MDouble *pnew, MDouble *y, MInt &jh, MInt &jl)
11784
11785 {
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801 static MDouble pbig, plit;
11802
11803 static MInt i, j, nparp1;
11804
11805
11806
11807
11808
11809 for (i = 1; i <= fNpar; ++i) { fP[i + jh*fMaxpar - fMaxpar-1] = pnew[i-1]; }
11810
11811 y[jh-1] = ynew;
11812
11813 if (ynew < fAmin) {
11814
11815 for (i = 1; i <= fNpar; ++i) { fX[i-1] = pnew[i-1]; }
11816
11817 mninex(fX);
11818
11819 fAmin = ynew;
11820
11821 fCstatu = "PROGRESS ";
11822
11823 jl = jh;
11824
11825 }
11826
11827 jh = 1;
11828
11829 nparp1 = fNpar + 1;
11830
11831 for (j = 2; j <= nparp1; ++j) { if (y[j-1] > y[jh-1]) jh = j; }
11832
11833 fEDM = y[jh-1] - y[jl-1];
11834
11835 if (fEDM <= 0) goto L45;
11836
11837 for (i = 1; i <= fNpar; ++i) {
11838
11839 pbig = fP[i-1];
11840
11841 plit = pbig;
11842
11843 for (j = 2; j <= nparp1; ++j) {
11844
11845 if (fP[i + j*fMaxpar - fMaxpar-1] > pbig) pbig = fP[i + j*fMaxpar - fMaxpar-1];
11846
11847 if (fP[i + j*fMaxpar - fMaxpar-1] < plit) plit = fP[i + j*fMaxpar - fMaxpar-1];
11848
11849 }
11850
11851 fDirin[i-1] = pbig - plit;
11852
11853 }
11854
11855 L40:
11856
11857 return;
11858
11859 L45:
11860
11861 fPrintf(" FUNCTION VALUE DOES NOT SEEM TO DEPEND ON ANY OF THE%d VARIABLE PARAMETERS.",fNpar);
11862
11863 fPrintf(" VERIFY THAT STEP SIZES ARE BIG ENOUGH AND CHECK FCN LOGIC.");
11864
11865 fPrintf(" *******************************************************************************");
11866
11867 fPrintf(" *******************************************************************************");
11868
11869 goto L40;
11870
11871 }
11872
11873
11874
11875
11876
11877 void Midnight::mnrn15(MDouble &val, MInt &inseed)
11878
11879 {
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901 static MInt iseed = 12345;
11902
11903
11904
11905 MInt k;
11906
11907
11908
11909 if (val == 3) goto L100;
11910
11911 inseed = iseed;
11912
11913 k = iseed / 53668;
11914
11915 iseed = (iseed - k*53668)*40014 - k*12211;
11916
11917 if (iseed < 0) iseed += 2147483563;
11918
11919 val = MDouble(iseed*4.656613e-10);
11920
11921 return;
11922
11923
11924
11925 L100:
11926
11927 iseed = inseed;
11928
11929 }
11930
11931
11932
11933
11934
11935 void Midnight::mnrset(MInt iopt)
11936
11937 {
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955 static MInt iext, i;
11956
11957
11958
11959 fCstatu = "RESET ";
11960
11961 if (iopt >= 1) {
11962
11963 fAmin = fUndefi;
11964
11965 fFval3 = TMath_Abs(fAmin)*2 + 1;
11966
11967 fEDM = fBigedm;
11968
11969 fISW[3] = 0;
11970
11971 fISW[1] = 0;
11972
11973 fDcovar = 1;
11974
11975 fISW[0] = 0;
11976
11977 }
11978
11979 fLnolim = kTRUE;
11980
11981 for (i = 1; i <= fNpar; ++i) {
11982
11983 iext = fNexofi[i-1];
11984
11985 if (fNvarl[iext-1] >= 4) fLnolim = kFALSE;
11986
11987 fErp[i-1] = 0;
11988
11989 fErn[i-1] = 0;
11990
11991 fGlobcc[i-1] = 0;
11992
11993 }
11994
11995 if (fISW[1] >= 1) {
11996
11997 fISW[1] = 1;
11998
11999 fDcovar = TMath_Max(fDcovar,.5);
12000
12001 }
12002
12003 }
12004
12005
12006
12007
12008
12009 void Midnight::mnsave()
12010
12011 {
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025 fPrintf("mnsave is dummy in the base class Minuit: Use MinuitOld");
12026
12027
12028
12029 }
12030
12031
12032
12033
12034
12035 void Midnight::mnscan()
12036
12037 {
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055 static MDouble step, uhigh, xhreq, xlreq, ubest, fnext, unext, xh, xl;
12056
12057 static MInt ipar, iint, icall, ncall, nbins, nparx;
12058
12059 static MInt nxypt, nccall, iparwd;
12060
12061
12062
12063 xlreq = TMath_Min(fWord7[2],fWord7[3]);
12064
12065 xhreq = TMath_Max(fWord7[2],fWord7[3]);
12066
12067 ncall = MInt((fWord7[1] + .01));
12068
12069 if (ncall <= 1) ncall = 41;
12070
12071 if (ncall > 101) ncall = 101;
12072
12073 nccall = ncall;
12074
12075 if (fAmin == fUndefi) mnamin();
12076
12077 iparwd = MInt((fWord7[0] + .1));
12078
12079 ipar = TMath_Max(iparwd,0);
12080
12081 iint = fNiofex[ipar-1];
12082
12083 fCstatu = "NO CHANGE";
12084
12085 if (iparwd > 0) goto L200;
12086
12087
12088
12089
12090
12091 L100:
12092
12093 ++ipar;
12094
12095 if (ipar > fNu) goto L900;
12096
12097 iint = fNiofex[ipar-1];
12098
12099 if (iint <= 0) goto L100;
12100
12101
12102
12103 L200:
12104
12105 ubest = fU[ipar-1];
12106
12107 fXpt[0] = ubest;
12108
12109 fYpt[0] = fAmin;
12110
12111 fChpt[0] = ' ';
12112
12113 fXpt[1] = ubest;
12114
12115 fYpt[1] = fAmin;
12116
12117 fChpt[1] = 'X';
12118
12119 nxypt = 2;
12120
12121 if (fNvarl[ipar-1] > 1) goto L300;
12122
12123
12124
12125
12126
12127 if (xlreq == xhreq) goto L250;
12128
12129 unext = xlreq;
12130
12131 step = (xhreq - xlreq) / MDouble(ncall-1);
12132
12133 goto L500;
12134
12135 L250:
12136
12137 xl = ubest - fWerr[iint-1];
12138
12139 xh = ubest + fWerr[iint-1];
12140
12141 mnbins(xl, xh, ncall, unext, uhigh, nbins, step);
12142
12143 nccall = nbins + 1;
12144
12145 goto L500;
12146
12147
12148
12149 L300:
12150
12151 if (xlreq == xhreq) goto L350;
12152
12153
12154
12155 xl = TMath_Max(xlreq,fAlim[ipar-1]);
12156
12157
12158
12159 xh = TMath_Min(xhreq,fBlim[ipar-1]);
12160
12161 if (xl >= xh) goto L700;
12162
12163 unext = xl;
12164
12165 step = (xh - xl) / MDouble(ncall-1);
12166
12167 goto L500;
12168
12169 L350:
12170
12171 unext = fAlim[ipar-1];
12172
12173 step = (fBlim[ipar-1] - fAlim[ipar-1]) / MDouble(ncall-1);
12174
12175
12176
12177 L500:
12178
12179 for (icall = 1; icall <= nccall; ++icall) {
12180
12181 fU[ipar-1] = unext;
12182
12183 nparx = fNpar;
12184
12185 (*fFCN)(nparx, fGin, fnext, fU, 4); ++fNfcn;
12186
12187 ++nxypt;
12188
12189 fXpt[nxypt-1] = unext;
12190
12191 fYpt[nxypt-1] = fnext;
12192
12193 fChpt[nxypt-1] = '*';
12194
12195 if (fnext < fAmin) {
12196
12197 fAmin = fnext;
12198
12199 ubest = unext;
12200
12201 fCstatu = "IMPROVED ";
12202
12203 }
12204
12205 unext += step;
12206
12207 }
12208
12209
12210
12211 fU[ipar-1] = ubest;
12212
12213 mnexin(fX);
12214
12215 fPrintf("%dSCAN OF PARAMETER NO. %d, %s"
12216
12217 ,fNewpag,ipar,(const char*)fCpnam[ipar-1]);
12218
12219 mnplot(fXpt, fYpt, fChpt, nxypt, fNpagwd, fNpagln);
12220
12221 goto L800;
12222
12223 L700:
12224
12225 fPrintf(" REQUESTED RANGE OUTSIDE LIMITS FOR PARAMETER %d",ipar);
12226
12227 L800:
12228
12229 if (iparwd <= 0) goto L100;
12230
12231
12232
12233 L900:
12234
12235 mnprin(5, fAmin);
12236
12237 }
12238
12239
12240
12241
12242
12243 void Midnight::mnseek()
12244
12245 {
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271 static MDouble xmid[kMAXDIM], dxdi, rnum, ftry, rnum1, rnum2, alpha;
12272
12273 static MDouble flast, xbest[kMAXDIM], bar;
12274
12275 static MInt ipar, iext, j, ifail, iseed, nparx, istep, ib, mxfail, mxstep;
12276
12277
12278
12279 mxfail = MInt(fWord7[0]);
12280
12281 if (mxfail <= 0) mxfail = fNpar*20 + 100;
12282
12283 mxstep = mxfail*10;
12284
12285 if (fAmin == fUndefi) mnamin();
12286
12287 alpha = fWord7[1];
12288
12289 if (alpha <= 0) alpha = 3;
12290
12291 if (fISW[4] >= 1) {
12292
12293 fPrintf(" MNSEEK: MONTE CARLO MINIMIZATION USING METROPOLIS ALGORITHM");
12294
12295 fPrintf(" TO STOP AFTER %6d SUCCESSIVE FAILURES, OR %7d STEPS",mxfail,mxstep);
12296
12297 fPrintf(" MAXIMUM STEP SIZE IS %9.3f ERROR BARS.",alpha);
12298
12299 }
12300
12301 fCstatu = "INITIAL ";
12302
12303 if (fISW[4] >= 2) mnprin(2, fAmin);
12304
12305 fCstatu = "UNCHANGED ";
12306
12307 ifail = 0;
12308
12309 rnum = 0;
12310
12311 rnum1 = 0;
12312
12313 rnum2 = 0;
12314
12315 nparx = fNpar;
12316
12317 flast = fAmin;
12318
12319
12320
12321 for (ipar = 1; ipar <= fNpar; ++ipar) {
12322
12323 iext = fNexofi[ipar-1];
12324
12325 fDirin[ipar-1] = alpha*2*fWerr[ipar-1];
12326
12327 if (fNvarl[iext-1] > 1) {
12328
12329
12330
12331 mndxdi(fX[ipar-1], ipar-1, dxdi);
12332
12333 if (dxdi == 0) dxdi = 1;
12334
12335 fDirin[ipar-1] = alpha*2*fWerr[ipar-1] / dxdi;
12336
12337 if (TMath_Abs(fDirin[ipar-1]) > 6.2831859999999997) {
12338
12339 fDirin[ipar-1] = 6.2831859999999997;
12340
12341 }
12342
12343 }
12344
12345 xmid[ipar-1] = fX[ipar-1];
12346
12347 xbest[ipar-1] = fX[ipar-1];
12348
12349 }
12350
12351
12352
12353 for (istep = 1; istep <= mxstep; ++istep) {
12354
12355 if (ifail >= mxfail) break;
12356
12357 for (ipar = 1; ipar <= fNpar; ++ipar) {
12358
12359 mnrn15(rnum1, iseed);
12360
12361 mnrn15(rnum2, iseed);
12362
12363 fX[ipar-1] = xmid[ipar-1] + (rnum1 + rnum2 - 1)*.5*fDirin[ipar-1];
12364
12365 }
12366
12367 mninex(fX);
12368
12369 (*fFCN)(nparx, fGin, ftry, fU, 4); ++fNfcn;
12370
12371 if (ftry < flast) {
12372
12373 if (ftry < fAmin) {
12374
12375 fCstatu = "IMPROVEMNT";
12376
12377 fAmin = ftry;
12378
12379 for (ib = 1; ib <= fNpar; ++ib) { xbest[ib-1] = fX[ib-1]; }
12380
12381 ifail = 0;
12382
12383 if (fISW[4] >= 2) mnprin(2, fAmin);
12384
12385 }
12386
12387 goto L300;
12388
12389 } else {
12390
12391 ++ifail;
12392
12393
12394
12395 bar = (fAmin - ftry) / fUp;
12396
12397 mnrn15(rnum, iseed);
12398
12399 if (bar < TMath_Log(rnum)) continue;
12400
12401 }
12402
12403
12404
12405 L300:
12406
12407 for (j = 1; j <= fNpar; ++j) { xmid[j-1] = fX[j-1]; }
12408
12409 flast = ftry;
12410
12411 }
12412
12413
12414
12415 if (fISW[4] > 1) {
12416
12417 fPrintf(" MNSEEK: %5d SUCCESSIVE UNSUCCESSFUL TRIALS.",ifail);
12418
12419 }
12420
12421 for (ib = 1; ib <= fNpar; ++ib) { fX[ib-1] = xbest[ib-1]; }
12422
12423 mninex(fX);
12424
12425 if (fISW[4] >= 1) mnprin(2, fAmin);
12426
12427 if (fISW[4] == 0) mnprin(0, fAmin);
12428
12429 }
12430
12431
12432
12433
12434
12435 void Midnight::mnset()
12436
12437 {
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465 static MString cname[30] = {
12466
12467 "FCN value ",
12468
12469 "PARameters",
12470
12471 "LIMits ",
12472
12473 "COVariance",
12474
12475 "CORrelatio",
12476
12477 "PRInt levl",
12478
12479 "NOGradient",
12480
12481 "GRAdient ",
12482
12483 "ERRor def ",
12484
12485 "INPut file",
12486
12487 "WIDth page",
12488
12489 "LINes page",
12490
12491 "NOWarnings",
12492
12493 "WARnings ",
12494
12495 "RANdom gen",
12496
12497 "TITle ",
12498
12499 "STRategy ",
12500
12501 "EIGenvalue",
12502
12503 "PAGe throw",
12504
12505 "MINos errs",
12506
12507 "EPSmachine",
12508
12509 "OUTputfile",
12510
12511 "BATch ",
12512
12513 "INTeractiv",
12514
12515 "VERsion ",
12516
12517 "reserve ",
12518
12519 "NODebug ",
12520
12521 "DEBug ",
12522
12523 "SHOw ",
12524
12525 "SET "};
12526
12527
12528
12529 static MInt nname = 25;
12530
12531 static MInt nntot = 30;
12532
12533 static MString cprlev[5] = {
12534
12535 "-1: NO OUTPUT EXCEPT FROM SHOW ",
12536
12537 " 0: REDUCED OUTPUT ",
12538
12539 " 1: NORMAL OUTPUT ",
12540
12541 " 2: EXTRA OUTPUT FOR PROBLEM CASES",
12542
12543 " 3: MAXIMUM OUTPUT "};
12544
12545
12546
12547 static MString cstrat[3] = {
12548
12549 " 0: MINIMIZE THE NUMBER OF CALLS TO FUNCTION",
12550
12551 " 1: TRY TO BALANCE SPEED AGAINST RELIABILITY",
12552
12553 " 2: MAKE SURE MINIMUM TRUE, ERRORS CORRECT "};
12554
12555
12556
12557 static MString cdbopt[7] = {
12558
12559 "REPORT ALL EXCEPTIONAL CONDITIONS ",
12560
12561 "MNLINE: LINE SEARCH MINIMIZATION ",
12562
12563 "MNDERI: FIRST DERIVATIVE CALCULATIONS ",
12564
12565 "MNHESS: SECOND DERIVATIVE CALCULATIONS ",
12566
12567 "MNMIGR: COVARIANCE MATRIX UPDATES ",
12568
12569 "MNHES1: FIRST DERIVATIVE UNCERTAINTIES ",
12570
12571 "MNCONT: MNCONTOUR PLOT (MNCROS SEARCH) "};
12572
12573
12574
12575
12576
12577 MInt f_inqu();
12578
12579
12580
12581
12582
12583 static MDouble val;
12584
12585 static MInt iset, iprm, i, jseed, kname, iseed, iunit, id, ii, kk;
12586
12587 static MInt ikseed, idbopt, igrain, iswsav, isw2;
12588
12589 static MString cfname, cmode, ckind, cwarn, copt, ctemp, ctemp2;
12590
12591 static MBool lname;
12592
12593
12594
12595 for (i = 1; i <= nntot; ++i) {
12596
12597 ctemp = cname[i-1](0,3);
12598
12599 ctemp2 = fCword(3,7);
12600
12601 if (strstr((const char*)ctemp2, (const char*)ctemp)) goto L5;
12602
12603 }
12604
12605 i = 0;
12606
12607 L5:
12608
12609 kname = i;
12610
12611
12612
12613
12614
12615 if (fCword(0,3) == "HEL") goto L2000;
12616
12617 if (fCword(0,3) == "SHO") goto L1000;
12618
12619 if (fCword(0,3) != "SET") goto L1900;
12620
12621
12622
12623 ckind = "SET ";
12624
12625
12626
12627 if (kname <= 0) goto L1900;
12628
12629
12630
12631 switch ((int)kname) {
12632
12633 case 1: goto L3000;
12634
12635 case 2: goto L20;
12636
12637 case 3: goto L30;
12638
12639 case 4: goto L40;
12640
12641 case 5: goto L3000;
12642
12643 case 6: goto L60;
12644
12645 case 7: goto L70;
12646
12647 case 8: goto L80;
12648
12649 case 9: goto L90;
12650
12651 case 10: goto L100;
12652
12653 case 11: goto L110;
12654
12655 case 12: goto L120;
12656
12657 case 13: goto L130;
12658
12659 case 14: goto L140;
12660
12661 case 15: goto L150;
12662
12663 case 16: goto L160;
12664
12665 case 17: goto L170;
12666
12667 case 18: goto L3000;
12668
12669 case 19: goto L190;
12670
12671 case 20: goto L3000;
12672
12673 case 21: goto L210;
12674
12675 case 22: goto L220;
12676
12677 case 23: goto L230;
12678
12679 case 24: goto L240;
12680
12681 case 25: goto L3000;
12682
12683 case 26: goto L1900;
12684
12685 case 27: goto L270;
12686
12687 case 28: goto L280;
12688
12689 case 29: goto L290;
12690
12691 case 30: goto L300;
12692
12693 }
12694
12695
12696
12697
12698
12699 L20:
12700
12701 iprm = MInt(fWord7[0]);
12702
12703 if (iprm > fNu) goto L25;
12704
12705 if (iprm <= 0) goto L25;
12706
12707 if (fNvarl[iprm-1] < 0) goto L25;
12708
12709 fU[iprm-1] = fWord7[1];
12710
12711 mnexin(fX);
12712
12713 isw2 = fISW[1];
12714
12715 mnrset(1);
12716
12717
12718
12719 fISW[1] = TMath_Min(isw2,1);
12720
12721 fCfrom = "SET PARM";
12722
12723 fNfcnfr = fNfcn;
12724
12725 fCstatu = "NEW VALUES";
12726
12727 return;
12728
12729 L25:
12730
12731 fPrintf(" UNDEFINED PARAMETER NUMBER. IGNORED.");
12732
12733 return;
12734
12735
12736
12737 L30:
12738
12739 mnlims();
12740
12741 return;
12742
12743
12744
12745 L40:
12746
12747
12748
12749 goto L3000;
12750
12751
12752
12753 L60:
12754
12755 fISW[4] = MInt(fWord7[0]);
12756
12757 return;
12758
12759
12760
12761 L70:
12762
12763 fISW[2] = 0;
12764
12765 return;
12766
12767
12768
12769 L80:
12770
12771 mngrad();
12772
12773 return;
12774
12775
12776
12777 L90:
12778
12779 if (fWord7[0] == fUp) return;
12780
12781 if (fWord7[0] <= 0) {
12782
12783 if (fUp == fUpdflt) return;
12784
12785 fUp = fUpdflt;
12786
12787 } else {
12788
12789 fUp = fWord7[0];
12790
12791 }
12792
12793 for (i = 1; i <= fNpar; ++i) {
12794
12795 fErn[i-1] = 0;
12796
12797 fErp[i-1] = 0;
12798
12799 }
12800
12801 mnwerr();
12802
12803 return;
12804
12805
12806
12807
12808
12809
12810
12811 L100:
12812
12813 goto L3000;
12814
12815
12816
12817 L110:
12818
12819 fNpagwd = MInt(fWord7[0]);
12820
12821 fNpagwd = TMath_Max(fNpagwd,50);
12822
12823 return;
12824
12825
12826
12827 L120:
12828
12829 fNpagln = MInt(fWord7[0]);
12830
12831 return;
12832
12833
12834
12835
12836
12837 L130:
12838
12839 fLwarn = kFALSE;
12840
12841 return;
12842
12843
12844
12845 L140:
12846
12847 fLwarn = kTRUE;
12848
12849 mnwarn("W", "SHO", "SHO");
12850
12851 return;
12852
12853
12854
12855 L150:
12856
12857 jseed = MInt(fWord7[0]);
12858
12859 val = 3;
12860
12861 mnrn15(val, jseed);
12862
12863 if (fISW[4] > 0) {
12864
12865 fPrintf(" MINUIT RANDOM NUMBER SEED SET TO %d",jseed);
12866
12867 }
12868
12869 return;
12870
12871
12872
12873 L160:
12874
12875
12876
12877 goto L3000;
12878
12879
12880
12881 L170:
12882
12883 fIstrat = MInt(fWord7[0]);
12884
12885 fIstrat = TMath_Max(fIstrat,0);
12886
12887 fIstrat = TMath_Min(fIstrat,2);
12888
12889 if (fISW[4] > 0) goto L1172;
12890
12891 return;
12892
12893
12894
12895 L190:
12896
12897 fNewpag = MInt(fWord7[0]);
12898
12899 goto L1190;
12900
12901
12902
12903 L210:
12904
12905 if (fWord7[0] > 0 && fWord7[0] < .1) {
12906
12907 fEpsmac = fWord7[0];
12908
12909 }
12910
12911 fEpsma2 = TMath_Sqrt(fEpsmac);
12912
12913 goto L1210;
12914
12915
12916
12917 L220:
12918
12919 iunit = MInt(fWord7[0]);
12920
12921 fIsyswr = iunit;
12922
12923 fIstkwr[0] = iunit;
12924
12925 if (fISW[4] >= 0) goto L1220;
12926
12927 return;
12928
12929
12930
12931 L230:
12932
12933 fISW[5] = 0;
12934
12935 if (fISW[4] >= 0) goto L1100;
12936
12937 return;
12938
12939
12940
12941 L240:
12942
12943 fISW[5] = 1;
12944
12945 if (fISW[4] >= 0) goto L1100;
12946
12947 return;
12948
12949
12950
12951 L270:
12952
12953 iset = 0;
12954
12955 goto L281;
12956
12957
12958
12959 L280:
12960
12961 iset = 1;
12962
12963 L281:
12964
12965 idbopt = MInt(fWord7[0]);
12966
12967 if (idbopt > 6) goto L288;
12968
12969 if (idbopt >= 0) {
12970
12971 fIdbg[idbopt] = iset;
12972
12973 if (iset == 1) fIdbg[0] = 1;
12974
12975 } else {
12976
12977
12978
12979 for (id = 0; id <= 6; ++id) { fIdbg[id] = iset; }
12980
12981 }
12982
12983 fLrepor = fIdbg[0] >= 1;
12984
12985 mnwarn("D", "SHO", "SHO");
12986
12987 return;
12988
12989 L288:
12990
12991 fPrintf(" UNKNOWN DEBUG OPTION %d REQUESTED. IGNORED",idbopt);
12992
12993 return;
12994
12995
12996
12997 L290:
12998
12999
13000
13001 L300:
13002
13003 goto L3000;
13004
13005
13006
13007 L1000:
13008
13009
13010
13011 ckind = "SHOW";
13012
13013 if (kname <= 0) goto L1900;
13014
13015
13016
13017 switch ((int)kname) {
13018
13019 case 1: goto L1010;
13020
13021 case 2: goto L1020;
13022
13023 case 3: goto L1030;
13024
13025 case 4: goto L1040;
13026
13027 case 5: goto L1050;
13028
13029 case 6: goto L1060;
13030
13031 case 7: goto L1070;
13032
13033 case 8: goto L1070;
13034
13035 case 9: goto L1090;
13036
13037 case 10: goto L1100;
13038
13039 case 11: goto L1110;
13040
13041 case 12: goto L1120;
13042
13043 case 13: goto L1130;
13044
13045 case 14: goto L1130;
13046
13047 case 15: goto L1150;
13048
13049 case 16: goto L1160;
13050
13051 case 17: goto L1170;
13052
13053 case 18: goto L1180;
13054
13055 case 19: goto L1190;
13056
13057 case 20: goto L1200;
13058
13059 case 21: goto L1210;
13060
13061 case 22: goto L1220;
13062
13063 case 23: goto L1100;
13064
13065 case 24: goto L1100;
13066
13067 case 25: goto L1250;
13068
13069 case 26: goto L1900;
13070
13071 case 27: goto L1270;
13072
13073 case 28: goto L1270;
13074
13075 case 29: goto L1290;
13076
13077 case 30: goto L1300;
13078
13079 }
13080
13081
13082
13083
13084
13085 L1010:
13086
13087 if (fAmin == fUndefi) mnamin();
13088
13089 mnprin(0, fAmin);
13090
13091 return;
13092
13093
13094
13095 L1020:
13096
13097 if (fAmin == fUndefi) mnamin();
13098
13099 mnprin(5, fAmin);
13100
13101 return;
13102
13103
13104
13105 L1030:
13106
13107 if (fAmin == fUndefi) mnamin();
13108
13109 mnprin(1, fAmin);
13110
13111 return;
13112
13113
13114
13115 L1040:
13116
13117 mnmatu(1);
13118
13119 return;
13120
13121
13122
13123 L1050:
13124
13125 mnmatu(0);
13126
13127 return;
13128
13129
13130
13131 L1060:
13132
13133 if (fISW[4] < -1) fISW[4] = -1;
13134
13135 if (fISW[4] > 3) fISW[4] = 3;
13136
13137 fPrintf(" ALLOWED PRINT LEVELS ARE:");
13138
13139 fPrintf(" %s",(const char*)cprlev[0]);
13140
13141 fPrintf(" %s",(const char*)cprlev[1]);
13142
13143 fPrintf(" %s",(const char*)cprlev[2]);
13144
13145 fPrintf(" %s",(const char*)cprlev[3]);
13146
13147 fPrintf(" %s",(const char*)cprlev[4]);
13148
13149 fPrintf(" CURRENT PRINTOUT LEVEL IS %s",(const char*)cprlev[fISW[4]]);
13150
13151 return;
13152
13153
13154
13155 L1070:
13156
13157 if (fISW[2] <= 0) {
13158
13159 fPrintf(" NOGRAD IS SET. DERIVATIVES NOT COMPUTED IN FCN.");
13160
13161 } else {
13162
13163 fPrintf(" GRAD IS SET. USER COMPUTES DERIVATIVES IN FCN.");
13164
13165 }
13166
13167 return;
13168
13169
13170
13171 L1090:
13172
13173 fPrintf(" ERRORS CORRESPOND TO FUNCTION CHANGE OF %g",fUp);
13174
13175 return;
13176
13177
13178
13179
13180
13181 L1100:
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221 cmode = "BATCH MODE ";
13222
13223 if (fISW[5] == 1) cmode = "INTERACTIVE MODE";
13224
13225 if (! lname) cfname = "unknown";
13226
13227 fPrintf(" INPUT NOW BEING READ IN %s FROM UNIT NO. %d FILENAME: %s"
13228
13229 ,(const char*)cmode,fIsysrd,(const char*)cfname);
13230
13231 return;
13232
13233
13234
13235 L1110:
13236
13237 fPrintf(" PAGE WIDTH IS SET TO %d COLUMNS",fNpagwd);
13238
13239 return;
13240
13241
13242
13243 L1120:
13244
13245 fPrintf(" PAGE LENGTH IS SET TO %d LINES",fNpagln);
13246
13247 return;
13248
13249
13250
13251 L1130:
13252
13253 cwarn = "SUPPRESSED";
13254
13255 if (fLwarn) cwarn = "REPORTED ";
13256
13257 fPrintf("%s",(const char*)cwarn);
13258
13259 if (! fLwarn) mnwarn("W", "SHO", "SHO");
13260
13261 return;
13262
13263
13264
13265 L1150:
13266
13267 val = 0;
13268
13269 mnrn15(val, igrain);
13270
13271 ikseed = igrain;
13272
13273 fPrintf(" MINUIT RNDM SEED IS CURRENTLY=",ikseed);
13274
13275 val = 3;
13276
13277 iseed = ikseed;
13278
13279 mnrn15(val, iseed);
13280
13281 return;
13282
13283
13284
13285 L1160:
13286
13287 fPrintf(" TITLE OF CURRENT TASK IS:%s",(const char*)fCtitl);
13288
13289 return;
13290
13291
13292
13293 L1170:
13294
13295 fPrintf(" ALLOWED STRATEGIES ARE:");
13296
13297 fPrintf(" %s",(const char*)cstrat[0]);
13298
13299 fPrintf(" %s",(const char*)cstrat[1]);
13300
13301 fPrintf(" %s",(const char*)cstrat[2]);
13302
13303 L1172:
13304
13305 fPrintf(" NOW USING STRATEGY %s",(const char*)cstrat[fIstrat]);
13306
13307 return;
13308
13309
13310
13311 L1180:
13312
13313 iswsav = fISW[4];
13314
13315 fISW[4] = 3;
13316
13317 if (fISW[1] < 1) {
13318
13319 fPrintf("%s",(const char*)fCovmes[0]);
13320
13321 } else {
13322
13323 mnpsdf();
13324
13325 }
13326
13327 fISW[4] = iswsav;
13328
13329 return;
13330
13331
13332
13333 L1190:
13334
13335 fPrintf(" PAGE THROW CARRIAGE CONTROL = %d",fNewpag);
13336
13337 if (fNewpag == 0) {
13338
13339 fPrintf(" NO PAGE THROWS IN MINUIT OUTPUT");
13340
13341 }
13342
13343 return;
13344
13345
13346
13347 L1200:
13348
13349 for (ii = 1; ii <= fNpar; ++ii) {
13350
13351 if (fErp[ii-1] > 0 || fErn[ii-1] < 0) goto L1204;
13352
13353 }
13354
13355 fPrintf(" THERE ARE NO MINOS ERRORS CURRENTLY VALID.");
13356
13357 return;
13358
13359 L1204:
13360
13361 mnprin(4, fAmin);
13362
13363 return;
13364
13365
13366
13367 L1210:
13368
13369 fPrintf(" FLOATING-POINT NUMBERS ASSUMED ACCURATE TO %g",fEpsmac);
13370
13371 return;
13372
13373
13374
13375 L1220:
13376
13377 fPrintf(" MINUIT PRIMARY OUTPUT TO UNIT %d",fIsyswr);
13378
13379 return;
13380
13381
13382
13383 L1250:
13384
13385 fPrintf(" THIS IS MINUIT VERSION:%s",(const char*)fCvrsn);
13386
13387 return;
13388
13389
13390
13391 L1270:
13392
13393 for (id = 0; id <= 6; ++id) {
13394
13395 copt = "OFF";
13396
13397 if (fIdbg[id] >= 1) copt = "ON ";
13398
13399 fPrintf(" DEBUG OPTION %3d IS %3s :%s"
13400
13401 ,id,(const char*)copt,(const char*)cdbopt[id]);
13402
13403 }
13404
13405 if (! fLrepor) mnwarn("D", "SHO", "SHO");
13406
13407 return;
13408
13409
13410
13411 L1290:
13412
13413 ckind = "SHOW";
13414
13415 goto L2100;
13416
13417
13418
13419 L1300:
13420
13421 ckind = "SET ";
13422
13423 goto L2100;
13424
13425
13426
13427
13428
13429 L1900:
13430
13431 fPrintf(" THE COMMAND:%10s IS UNKNOWN.",(const char*)fCword);
13432
13433 goto L2100;
13434
13435
13436
13437
13438
13439 L2000:
13440
13441 ckind = "SET ";
13442
13443 ctemp = fCword(3,7);
13444
13445 if (strcmp((const char*)ctemp, "SHO")) ckind = "SHOW";
13446
13447 L2100:
13448
13449 fPrintf(" THE FORMAT OF THE %4s COMMAND IS:",(const char*)ckind);
13450
13451 fPrintf(" %s xxx [numerical arguments if any]",(const char*)ckind);
13452
13453 fPrintf(" WHERE xxx MAY BE ONE OF THE FOLLOWING:");
13454
13455 for (kk = 1; kk <= nname; ++kk) {
13456
13457 fPrintf(" %s",(const char*)cname[kk-1]);
13458
13459 }
13460
13461 return;
13462
13463
13464
13465
13466
13467 L3000:
13468
13469 fPrintf(" ABOVE COMMAND IS ILLEGAL. IGNORED");
13470
13471
13472
13473 }
13474
13475
13476
13477
13478
13479 void Midnight::mnsimp()
13480
13481 {
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499 static MDouble alpha = 1;
13500
13501 static MDouble beta = .5;
13502
13503 static MDouble gamma = 2;
13504
13505 static MDouble rhomin = 4;
13506
13507 static MDouble rhomax = 8;
13508
13509
13510
13511
13512
13513 static MDouble dmin_, dxdi, yrho, f, ynpp1, y[kMAXDIM+1], aming, ypbar;
13514
13515 static MDouble bestx, ystar, y1, y2, ystst, pb, wg;
13516
13517 static MDouble absmin, rho, sig2, rho1, rho2;
13518
13519 static MInt npfn, i, j, k, jhold, ncycl, nparx;
13520
13521 static MInt nparp1, kg, jh, nf, jl, ns;
13522
13523
13524
13525 if (fNpar <= 0) return;
13526
13527 if (fAmin == fUndefi) mnamin();
13528
13529 fCfrom = "SIMPLEX ";
13530
13531 fNfcnfr = fNfcn;
13532
13533 fCstatu = "UNCHANGED ";
13534
13535 npfn = fNfcn;
13536
13537 nparp1 = fNpar + 1;
13538
13539 nparx = fNpar;
13540
13541 rho1 = alpha + 1;
13542
13543 rho2 = rho1 + alpha*gamma;
13544
13545 wg = 1 / MDouble(fNpar);
13546
13547 if (fISW[4] >= 0) {
13548
13549 fPrintf(" START SIMPLEX MINIMIZATION. CONVERGENCE WHEN EDM .LT. %g",fEpsi);
13550
13551 }
13552
13553 for (i = 1; i <= fNpar; ++i) {
13554
13555 fDirin[i-1] = fWerr[i-1];
13556
13557 mndxdi(fX[i-1], i-1, dxdi);
13558
13559 if (dxdi != 0) fDirin[i-1] = fWerr[i-1] / dxdi;
13560
13561 dmin_ = fEpsma2*TMath_Abs(fX[i-1]);
13562
13563 if (fDirin[i-1] < dmin_) fDirin[i-1] = dmin_;
13564
13565 }
13566
13567
13568
13569 L1:
13570
13571 ynpp1 = fAmin;
13572
13573 jl = nparp1;
13574
13575 y[nparp1-1] = fAmin;
13576
13577 absmin = fAmin;
13578
13579 for (i = 1; i <= fNpar; ++i) {
13580
13581 aming = fAmin;
13582
13583 fPbar[i-1] = fX[i-1];
13584
13585 bestx = fX[i-1];
13586
13587 kg = 0;
13588
13589 ns = 0;
13590
13591 nf = 0;
13592
13593 L4:
13594
13595 fX[i-1] = bestx + fDirin[i-1];
13596
13597 mninex(fX);
13598
13599 (*fFCN)(nparx, fGin, f, fU, 4); ++fNfcn;
13600
13601 if (f <= aming) goto L6;
13602
13603
13604
13605 if (kg == 1) goto L8;
13606
13607 kg = -1;
13608
13609 ++nf;
13610
13611 fDirin[i-1] *= -.4;
13612
13613 if (nf < 3) goto L4;
13614
13615 ns = 6;
13616
13617
13618
13619 L6:
13620
13621 bestx = fX[i-1];
13622
13623 fDirin[i-1] *= 3;
13624
13625 aming = f;
13626
13627 fCstatu = "PROGRESS ";
13628
13629 kg = 1;
13630
13631 ++ns;
13632
13633 if (ns < 6) goto L4;
13634
13635
13636
13637 L8:
13638
13639 y[i-1] = aming;
13640
13641 if (aming < absmin) jl = i;
13642
13643 if (aming < absmin) absmin = aming;
13644
13645 fX[i-1] = bestx;
13646
13647 for (k = 1; k <= fNpar; ++k) { fP[k + i*fMaxpar - fMaxpar-1] = fX[k-1]; }
13648
13649 }
13650
13651 jh = nparp1;
13652
13653 fAmin = y[jl-1];
13654
13655 mnrazz(ynpp1, fPbar, y, jh, jl);
13656
13657 for (i = 1; i <= fNpar; ++i) { fX[i-1] = fP[i + jl*fMaxpar - fMaxpar-1]; }
13658
13659 mninex(fX);
13660
13661 fCstatu = "PROGRESS ";
13662
13663 if (fISW[4] >= 1) mnprin(5, fAmin);
13664
13665 fEDM = fBigedm;
13666
13667 sig2 = fEDM;
13668
13669 ncycl = 0;
13670
13671
13672
13673 L50:
13674
13675 if (sig2 < fEpsi && fEDM < fEpsi) goto L76;
13676
13677 sig2 = fEDM;
13678
13679 if (fNfcn - npfn > fNfcnmx) goto L78;
13680
13681
13682
13683 for (i = 1; i <= fNpar; ++i) {
13684
13685 pb = 0;
13686
13687 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
13688
13689 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
13690
13691 fPstar[i-1] = (alpha + 1)*fPbar[i-1] - alpha*fP[i + jh*fMaxpar - fMaxpar-1];
13692
13693 }
13694
13695 mninex(fPstar);
13696
13697 (*fFCN)(nparx, fGin, ystar, fU, 4); ++fNfcn;
13698
13699 if (ystar >= fAmin) goto L70;
13700
13701
13702
13703 for (i = 1; i <= fNpar; ++i) {
13704
13705 fPstst[i-1] = gamma*fPstar[i-1] + (1 - gamma)*fPbar[i-1];
13706
13707 }
13708
13709 mninex(fPstst);
13710
13711 (*fFCN)(nparx, fGin, ystst, fU, 4); ++fNfcn;
13712
13713
13714
13715 y1 = (ystar - y[jh-1])*rho2;
13716
13717 y2 = (ystst - y[jh-1])*rho1;
13718
13719 rho = (rho2*y1 - rho1*y2)*.5 / (y1 - y2);
13720
13721 if (rho < rhomin) goto L66;
13722
13723 if (rho > rhomax) rho = rhomax;
13724
13725 for (i = 1; i <= fNpar; ++i) {
13726
13727 fPrho[i-1] = rho*fPbar[i-1] + (1 - rho)*fP[i + jh*fMaxpar - fMaxpar-1];
13728
13729 }
13730
13731 mninex(fPrho);
13732
13733 (*fFCN)(nparx, fGin, yrho, fU, 4); ++fNfcn;
13734
13735 if (yrho < y[jl-1] && yrho < ystst) goto L65;
13736
13737 if (ystst < y[jl-1]) goto L67;
13738
13739 if (yrho > y[jl-1]) goto L66;
13740
13741
13742
13743 L65:
13744
13745 mnrazz(yrho, fPrho, y, jh, jl);
13746
13747 goto L68;
13748
13749 L66:
13750
13751 if (ystst < y[jl-1]) goto L67;
13752
13753 mnrazz(ystar, fPstar, y, jh, jl);
13754
13755 goto L68;
13756
13757 L67:
13758
13759 mnrazz(ystst, fPstst, y, jh, jl);
13760
13761 L68:
13762
13763 ++ncycl;
13764
13765 if (fISW[4] < 2) goto L50;
13766
13767 if (fISW[4] >= 3 || ncycl % 10 == 0) {
13768
13769 mnprin(5, fAmin);
13770
13771 }
13772
13773 goto L50;
13774
13775
13776
13777 L70:
13778
13779 if (ystar >= y[jh-1]) goto L73;
13780
13781 jhold = jh;
13782
13783 mnrazz(ystar, fPstar, y, jh, jl);
13784
13785 if (jhold != jh) goto L50;
13786
13787
13788
13789 L73:
13790
13791 for (i = 1; i <= fNpar; ++i) {
13792
13793 fPstst[i-1] = beta*fP[i + jh*fMaxpar - fMaxpar-1] + (1 - beta)*fPbar[i-1];
13794
13795 }
13796
13797 mninex(fPstst);
13798
13799 (*fFCN)(nparx, fGin, ystst, fU, 4); ++fNfcn;
13800
13801 if (ystst > y[jh-1]) goto L1;
13802
13803
13804
13805 if (ystst < fAmin) goto L67;
13806
13807 mnrazz(ystst, fPstst, y, jh, jl);
13808
13809 goto L50;
13810
13811
13812
13813 L76:
13814
13815 if (fISW[4] >= 0) {
13816
13817 fPrintf(" SIMPLEX MINIMIZATION HAS CONVERGED.");
13818
13819 }
13820
13821 fISW[3] = 1;
13822
13823 goto L80;
13824
13825 L78:
13826
13827 if (fISW[4] >= 0) {
13828
13829 fPrintf(" SIMPLEX TERMINATES WITHOUT CONVERGENCE.");
13830
13831 }
13832
13833 fCstatu = "CALL LIMIT";
13834
13835 fISW[3] = -1;
13836
13837 fISW[0] = 1;
13838
13839 L80:
13840
13841 for (i = 1; i <= fNpar; ++i) {
13842
13843 pb = 0;
13844
13845 for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
13846
13847 fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
13848
13849 }
13850
13851 mninex(fPbar);
13852
13853 (*fFCN)(nparx, fGin, ypbar, fU, 4); ++fNfcn;
13854
13855 if (ypbar < fAmin) mnrazz(ypbar, fPbar, y, jh, jl);
13856
13857 mninex(fX);
13858
13859 if (fNfcnmx + npfn - fNfcn < fNpar*3) goto L90;
13860
13861 if (fEDM > fEpsi*2) goto L1;
13862
13863 L90:
13864
13865 if (fISW[4] >= 0) mnprin(5, fAmin);
13866
13867 }
13868
13869
13870
13871
13872
13873 void Midnight::mnstat(MDouble &fmin, MDouble &fedm, MDouble &errdef, MInt &npari, MInt &nparx, MInt &istat)
13874
13875 {
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911 fmin = fAmin;
13912
13913 fedm = fEDM;
13914
13915 errdef = fUp;
13916
13917 npari = fNpar;
13918
13919 nparx = fNu;
13920
13921 istat = fISW[1];
13922
13923 if (fEDM == fBigedm) fedm = fUp;
13924
13925 if (fAmin == fUndefi) {
13926
13927 fmin = 0;
13928
13929 fedm = fUp;
13930
13931 istat = 0;
13932
13933 }
13934
13935 }
13936
13937
13938
13939
13940
13941 void Midnight::mntiny(MDouble epsp1, MDouble &epsbak)
13942
13943 {
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959 epsbak = epsp1 - 1;
13960
13961 }
13962
13963
13964
13965
13966
13967 MBool Midnight::mnunpt(MString &cfname)
13968
13969 {
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979 static MInt i, l, ic;
13980
13981 MBool ret_val;
13982
13983 static MString cpt = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./;:[]$%*_!@#&+()";
13984
13985
13986
13987 ret_val = kFALSE;
13988
13989 l = strlen((const char*)cfname);
13990
13991 for (i = 1; i <= l; ++i) {
13992
13993 for (ic = 1; ic <= 80; ++ic) {
13994
13995 if (cfname[i-1] == cpt[ic-1]) goto L100;
13996
13997 }
13998
13999 return kTRUE;
14000
14001 L100:
14002
14003 ;
14004
14005 }
14006
14007 return ret_val;
14008
14009 }
14010
14011
14012
14013
14014
14015 void Midnight::mnvert(MDouble *a, MInt l, MInt, MInt n, MInt &ifail)
14016
14017 {
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035 MInt a_offset;
14036
14037
14038
14039
14040
14041 static MDouble q[kMAXDIM], s[kMAXDIM], si, pp[kMAXDIM];
14042
14043 static MInt i, j, k, kp1, km1;
14044
14045
14046
14047
14048
14049 a_offset = l + 1;
14050
14051 a -= a_offset;
14052
14053
14054
14055
14056
14057 ifail = 0;
14058
14059 if (n < 1) goto L100;
14060
14061 if (n > fMaxint) goto L100;
14062
14063
14064
14065 for (i = 1; i <= n; ++i) {
14066
14067 si = a[i + i*l];
14068
14069 if (si <= 0) goto L100;
14070
14071 s[i-1] = 1 / TMath_Sqrt(si);
14072
14073 }
14074
14075 for (i = 1; i <= n; ++i) {
14076
14077 for (j = 1; j <= n; ++j) {
14078
14079 a[i + j*l] = a[i + j*l]*s[i-1]*s[j-1];
14080
14081 }
14082
14083 }
14084
14085
14086
14087 for (i = 1; i <= n; ++i) {
14088
14089 k = i;
14090
14091
14092
14093 if (a[k + k*l] != 0) q[k-1] = 1 / a[k + k*l];
14094
14095 else goto L100;
14096
14097 pp[k-1] = 1;
14098
14099 a[k + k*l] = 0;
14100
14101 kp1 = k + 1;
14102
14103 km1 = k - 1;
14104
14105 if (km1 < 0) goto L100;
14106
14107 else if (km1 == 0) goto L50;
14108
14109 else goto L40;
14110
14111 L40:
14112
14113 for (j = 1; j <= km1; ++j) {
14114
14115 pp[j-1] = a[j + k*l];
14116
14117 q[j-1] = a[j + k*l]*q[k-1];
14118
14119 a[j + k*l] = 0;
14120
14121 }
14122
14123 L50:
14124
14125 if (k - n < 0) goto L51;
14126
14127 else if (k - n == 0) goto L60;
14128
14129 else goto L100;
14130
14131 L51:
14132
14133 for (j = kp1; j <= n; ++j) {
14134
14135 pp[j-1] = a[k + j*l];
14136
14137 q[j-1] = -a[k + j*l]*q[k-1];
14138
14139 a[k + j*l] = 0;
14140
14141 }
14142
14143
14144
14145 L60:
14146
14147 for (j = 1; j <= n; ++j) {
14148
14149 for (k = j; k <= n; ++k) { a[j + k*l] += pp[j-1]*q[k-1]; }
14150
14151 }
14152
14153 }
14154
14155
14156
14157 for (j = 1; j <= n; ++j) {
14158
14159 for (k = 1; k <= j; ++k) {
14160
14161 a[k + j*l] = a[k + j*l]*s[k-1]*s[j-1];
14162
14163 a[j + k*l] = a[k + j*l];
14164
14165 }
14166
14167 }
14168
14169 return;
14170
14171
14172
14173 L100:
14174
14175 ifail = 1;
14176
14177 }
14178
14179
14180
14181
14182
14183 void Midnight::mnwarn(const char *copt1, const char *corg1, const char *cmes1)
14184
14185 {
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211 MString copt = copt1;
14212
14213 MString corg = corg1;
14214
14215 MString cmes = cmes1;
14216
14217
14218
14219 const MInt MAXMES = 10;
14220
14221 static MInt ityp, i, ic, nm;
14222
14223 static MString englsh, ctyp;
14224
14225
14226
14227 if (corg(0,3) != "SHO" || cmes(0,3) != "SHO") {
14228
14229
14230
14231
14232
14233 if (copt == "W") {
14234
14235 ityp = 1;
14236
14237 if (fLwarn) {
14238
14239 fPrintf(" MINUIT WARNING IN %s",(const char*)corg);
14240
14241 fPrintf(" ============== ",(const char*)cmes);
14242
14243 return;
14244
14245 }
14246
14247 } else {
14248
14249 ityp = 2;
14250
14251 if (fLrepor) {
14252
14253 fPrintf(" MINUIT DEBUG FOR %s",(const char*)corg);
14254
14255 fPrintf(" =============== %s ",(const char*)cmes);
14256
14257 return;
14258
14259 }
14260
14261 }
14262
14263
14264
14265 if (fNwrmes[ityp-1] == 0) fIcirc[ityp-1] = 0;
14266
14267 ++fNwrmes[ityp-1];
14268
14269 ++fIcirc[ityp-1];
14270
14271 if (fIcirc[ityp-1] > 10) fIcirc[ityp-1] = 1;
14272
14273 ic = fIcirc[ityp-1];
14274
14275 fOrigin[ic + ityp*10 - 11] = corg;
14276
14277 fWarmes[ic + ityp*10 - 11] = cmes;
14278
14279 fNfcwar[ic + ityp*10 - 11] = fNfcn;
14280
14281 return;
14282
14283 }
14284
14285
14286
14287
14288
14289 if (copt == "W") {
14290
14291 ityp = 1;
14292
14293 ctyp = "WARNING";
14294
14295 } else {
14296
14297 ityp = 2;
14298
14299 ctyp = "*DEBUG*";
14300
14301 }
14302
14303 if (fNwrmes[ityp-1] > 0) {
14304
14305 englsh = " WAS SUPPRESSED. ";
14306
14307 if (fNwrmes[ityp-1] > 1) englsh = "S WERE SUPPRESSED.";
14308
14309 fPrintf(" %5d MINUIT %s MESSAGE%s",fNwrmes[ityp-1]
14310
14311 ,(const char*)ctyp,(const char*)englsh);
14312
14313 nm = fNwrmes[ityp-1];
14314
14315 ic = 0;
14316
14317 if (nm > MAXMES) {
14318
14319 fPrintf(" ONLY THE MOST RECENT 10 WILL BE LISTED BELOW.");
14320
14321 nm = MAXMES;
14322
14323 ic = fIcirc[ityp-1];
14324
14325 }
14326
14327 fPrintf(" CALLS ORIGIN MESSAGE");
14328
14329 for (i = 1; i <= nm; ++i) {
14330
14331 ++ic;
14332
14333 if (ic > MAXMES) ic = 1;
14334
14335 fPrintf(" %6d %s %s", fNfcwar[ic + ityp*10 - 11],
14336
14337 (const char*)fOrigin + (ic + ityp*10 - 11)*10,
14338
14339 (const char*)fWarmes + (ic + ityp*10 - 11)*60);
14340
14341 }
14342
14343 fNwrmes[ityp-1] = 0;
14344
14345 fPrintf(" ");
14346
14347 }
14348
14349 }
14350
14351
14352
14353
14354
14355 void Midnight::mnwerr()
14356
14357 {
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371 static MDouble denom, ba, al, dx, du1, du2;
14372
14373 static MInt ndex, ierr, i, j, k, l, ndiag, k1, iin;
14374
14375
14376
14377
14378
14379 if (fISW[1] >= 1) {
14380
14381 for (l = 1; l <= fNpar; ++l) {
14382
14383 ndex = l*(l + 1) / 2;
14384
14385 dx = TMath_Sqrt(TMath_Abs(fVhmat[ndex-1]*fUp));
14386
14387 i = fNexofi[l-1];
14388
14389 if (fNvarl[i-1] > 1) {
14390
14391 al = fAlim[i-1];
14392
14393 ba = fBlim[i-1] - al;
14394
14395 du1 = al + 0.5*(TMath_Sin(fX[l-1] + dx) + 1)*ba - fU[i-1];
14396
14397 du2 = al + 0.5*(TMath_Sin(fX[l-1] - dx) + 1)*ba - fU[i-1];
14398
14399 if (dx > 1) du1 = ba;
14400
14401 dx = 0.5*(TMath_Abs(du1) + TMath_Abs(du2));
14402
14403 }
14404
14405 fWerr[l-1] = dx;
14406
14407 }
14408
14409 }
14410
14411
14412
14413 if (fISW[1] >= 1) {
14414
14415 for (i = 1; i <= fNpar; ++i) {
14416
14417 fGlobcc[i-1] = 0;
14418
14419 k1 = i*(i-1) / 2;
14420
14421 for (j = 1; j <= i; ++j) {
14422
14423 k = k1 + j;
14424
14425 fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[k-1];
14426
14427 fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
14428
14429 }
14430
14431 }
14432
14433 mnvert(fP, fMaxint, fMaxint, fNpar, ierr);
14434
14435 if (ierr == 0) {
14436
14437 for (iin = 1; iin <= fNpar; ++iin) {
14438
14439 ndiag = iin*(iin + 1) / 2;
14440
14441 denom = fP[iin + iin*fMaxpar - fMaxpar-1]*fVhmat[ndiag-1];
14442
14443 if (denom <= 1 && denom >= 0) fGlobcc[iin-1] = 0;
14444
14445 else fGlobcc[iin-1] = TMath_Sqrt(1 - 1 / denom);
14446
14447 }
14448
14449 }
14450
14451 }
14452
14453 }
14454
14456
14457 static char* Form(
14458
14459 char* aFormat
14460
14461 ,...
14462
14463 )
14464
14466
14468
14469 {
14470
14471 va_list args;
14472
14473 va_start(args,aFormat);
14474
14475 vsprintf(sBuffer,aFormat,args);
14476
14477 va_end(args);
14478
14479 return sBuffer;
14480
14481 }
14482
14483
14484
14486
14487 static void Printf(
14488
14489 const char* aFormat
14490
14491 ,...
14492
14493 )
14494
14496
14498
14499 {
14500
14501 va_list args;
14502
14503 va_start(args,aFormat);
14504
14505 vprintf(aFormat,args);
14506
14507 va_end(args);
14508
14509 printf("\n");
14510
14511 }
14512