AmpTools
URMinuit.cc
Go to the documentation of this file.
1 // @(#)root/minuit:$Name: $:$Id: URMinuit.cc,v 1.5 2010/07/14 20:53:57 mashephe Exp $
2 // Author: Rene Brun, Frederick James 12/08/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 //#include <stdlib.h>
14 //#include <stdio.h>
15 #include <cstdlib>
16 #include <cstdio>
17 #include <string>
18 #include <sstream>
19 #include <iostream>
20 #include <iomanip>
21 #include <functional>
22 
23 #include "UpRootMinuit/URMinuit.h"
24 #include "UpRootMinuit/URMath.h"
25 
26 //#include "TError.h"
27 //#include "TPluginManager.h"
28 //#include "TClass.h"
29 //#include "Api.h"
30 
31 using namespace std;
32 
33 typedef unsigned int uint;
34 
35 const char charal[29] = " .ABCDEFGHIJKLMNOPQRSTUVWXYZ";
36 const Int_urt kDefaultMaximumInternalParameters = 200; // necessary until class rewritten completely w/ STL
38 const string kUndefinedParameterName( ")UNDEFINED" );
39 
40 //______________________________________________________________________________
42  m_userParameterIdToInternalId(kDefaultMaximumExternalParameters+1,0),
43  m_userParameterValue(kDefaultMaximumExternalParameters+1,0),
45  m_userParameterFlag(kDefaultMaximumExternalParameters+1,-1),
46  m_logStream( &cout )
47 {
48 //*-*-*-*-*-*-*-*-*-*-*Minuit normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
49 //*-* ========================
50 
51  zeroPointers();
53 
54  fStatus = 0;
55  fEmpty = 0;
57  mninit(5,6,7);
58 }
59 
60 //______________________________________________________________________________
62  m_userParameterIdToInternalId(2*maxpar+1),
63  m_userParameterValue(2*maxpar+1,0),
64  m_userParameterName(2*maxpar+1,kUndefinedParameterName),
65  m_userParameterFlag(2*maxpar+1,-1),
66  m_logStream( &cout )
67 {
68 //*-*-*-*-*-*-*-*-*-*-*Minuit normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
69 //*-* ========================
70 //
71 // maxpar is the maximum number of parameters used with this URMinuit object.
72 
73  zeroPointers();
74  BuildArrays(maxpar);
75 
76  fStatus = 0;
77  fEmpty = 0;
79 
80  mninit(5,6,7);
81 }
82 
83 //______________________________________________________________________________
85 {
86 //*-*-*-*-*-*-*-*-*-*-*Minuit default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
87 //*-* =========================
88 
89  DeleteArrays();
90 }
91 
92 //______________________________________________________________________________
93 void
95 {
96  //preset all pointers to null
97 // fCpnam = 0;
98 // fU = 0;
99  fAlim = 0;
100  fBlim = 0;
101  fPstar = 0;
102  fGin = 0;
103 // fNvarl = 0;
104 // fNiofex = 0;
105 
106  fNexofi = 0;
107  fIpfix = 0;
108  fErp = 0;
109  fErn = 0;
110  fWerr = 0;
111  fGlobcc = 0;
112  fX = 0;
113  fXt = 0;
114  fDirin = 0;
115  fXs = 0;
116  fXts = 0;
117  fDirins = 0;
118  fGrd = 0;
119  fG2 = 0;
120  fGstep = 0;
121  fDgrd = 0;
122  fGrds = 0;
123  fG2s = 0;
124  fGsteps = 0;
125  fPstst = 0;
126  fPbar = 0;
127  fPrho = 0;
128  fWord7 = 0;
129  fVhmat = 0;
130  fSecDer = 0;
131  fVthmat = 0;
132  fP = 0;
133  fXpt = 0;
134  fYpt = 0;
135  fChpt = 0;
136  fCONTgcc = 0;
137  fCONTw = 0;
138  fFIXPyy = 0;
139  fGRADgf = 0;
140  fHESSyy = 0;
141  fIMPRdsav = 0;
142  fIMPRy = 0;
143  fMATUvline = 0;
144  fMIGRflnu = 0;
145  fMIGRstep = 0;
146  fMIGRgs = 0;
147  fMIGRvg = 0;
148  fMIGRxxs = 0;
149  fMNOTxdev = 0;
150  fMNOTw = 0;
151  fMNOTgcc = 0;
152  fPSDFs = 0;
153  fSEEKxmid = 0;
154  fSEEKxbest = 0;
155  fSIMPy = 0;
156  fVERTq = 0;
157  fVERTs = 0;
158  fVERTpp = 0;
159  fCOMDplist = 0;
160  fPARSplist = 0;
161 }
162 
163 //______________________________________________________________________________
165 {
166 //*-*-*-*-*-*-*Create internal Minuit arrays for the maxpar parameters*-*-*-*
167 //*-* =======================================================
168 
169 // fMaxpar = kDefaultMaximumInternalParameters;
170 // fMaxpar2= 2*fMaxpar;
171 // if (maxpar > kDefaultMaximumInternalParameters) {
172  fMaxpar = maxpar;
173  fMaxpar2= 2*fMaxpar;
174 // m_userParameterIdToInternalId.resize( fMaxpar2+1, 0 );
175 // m_userParameterValue.resize( fMaxpar2+1, 0 );
176 // m_userParameterName.resize( fMaxpar2+1, kUndefinedParameterName );
177 // m_userParameterFlag.resize( fMaxpar2+1, -1 );
178 // }
179  fMaxpar1= fMaxpar*(fMaxpar+1);
180  fMaxpar5= fMaxpar1/2;
181  fMaxcpt = 101;
182 // fCpnam = new string[fMaxpar2];
183 // fU = new Double_urt[fMaxpar2];
184  fAlim = new Double_urt[fMaxpar2];
185  fBlim = new Double_urt[fMaxpar2];
186  fPstar = new Double_urt[fMaxpar2];
187  fGin = new Double_urt[fMaxpar2];
188 // fNvarl = new Int_urt[fMaxpar2];
189 // fNiofex = new Int_urt[fMaxpar2];
190 
191  fNexofi = new Int_urt[fMaxpar];
192  fIpfix = new Int_urt[fMaxpar];
193  fErp = new Double_urt[fMaxpar];
194  fErn = new Double_urt[fMaxpar];
195  fWerr = new Double_urt[fMaxpar];
196  fGlobcc = new Double_urt[fMaxpar];
197  fX = new Double_urt[fMaxpar];
198  fXt = new Double_urt[fMaxpar];
199  fDirin = new Double_urt[fMaxpar];
200  fXs = new Double_urt[fMaxpar];
201  fXts = new Double_urt[fMaxpar];
202  fDirins = new Double_urt[fMaxpar];
203  fGrd = new Double_urt[fMaxpar];
204  fG2 = new Double_urt[fMaxpar];
205  fGstep = new Double_urt[fMaxpar];
206  fDgrd = new Double_urt[fMaxpar];
207  fGrds = new Double_urt[fMaxpar];
208  fG2s = new Double_urt[fMaxpar];
209  fGsteps = new Double_urt[fMaxpar];
210  fPstst = new Double_urt[fMaxpar];
211  fPbar = new Double_urt[fMaxpar];
212  fPrho = new Double_urt[fMaxpar];
213  fWord7 = new Double_urt[fMaxpar];
214  fVhmat = new Double_urt[fMaxpar5];
215  fSecDer = new Double_urt[fMaxpar5];
216  fVthmat = new Double_urt[fMaxpar5];
217  fP = new Double_urt[fMaxpar1];
218  fXpt = new Double_urt[fMaxcpt];
219  fYpt = new Double_urt[fMaxcpt];
220  fChpt = new char[fMaxcpt+1];
221  // initialisation of dynamic arrays used internally in some functions
222  // these arrays had a fix dimension in Minuit
223  fCONTgcc = new Double_urt[fMaxpar];
224  fCONTw = new Double_urt[fMaxpar];
225  fFIXPyy = new Double_urt[fMaxpar];
226  fGRADgf = new Double_urt[fMaxpar];
227  fHESSyy = new Double_urt[fMaxpar];
229  fIMPRy = new Double_urt[fMaxpar];
233  fMIGRgs = new Double_urt[fMaxpar];
234  fMIGRvg = new Double_urt[fMaxpar];
235  fMIGRxxs = new Double_urt[fMaxpar];
237  fMNOTw = new Double_urt[fMaxpar];
238  fMNOTgcc = new Double_urt[fMaxpar];
239  fPSDFs = new Double_urt[fMaxpar];
242  fSIMPy = new Double_urt[fMaxpar];
243  fVERTq = new Double_urt[fMaxpar];
244  fVERTs = new Double_urt[fMaxpar];
245  fVERTpp = new Double_urt[fMaxpar];
248 
249  for (int i = 0; i < fMaxpar; i++) {
250  fErp[i] = 0;
251  fErn[i] = 0;
252  }
253 }
254 
255 
256 //______________________________________________________________________________
257 Int_urt URMinuit::Command(const char *command)
258 {
259 // execute a Minuit command
260 // Equivalent to MNEXCM except that the command is given as a
261 // character string.
262 // See URMinuit::mnhelp for the full list of available commands
263 //
264 // Returns the status of the execution:
265 // = 0: command executed normally
266 // 1: command is blank, ignored
267 // 2: command line unreadable, ignored
268 // 3: unknown command, ignored
269 // 4: abnormal termination (e.g., MIGRAD not converged)
270 // 5: command is a request to read PARAMETER definitions
271 // 6: 'SET INPUT' command
272 // 7: 'SET TITLE' command
273 // 8: 'SET COVAR' command
274 // 9: reserved
275 // 10: END command
276 // 11: EXIT or STOP command
277 // 12: RETURN command
278 //
279 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
280 
281  Int_urt status = 0;
282  mncomd(command,status);
283  return status;
284 }
285 
286 
287 //______________________________________________________________________________
288 Int_urt URMinuit::DefineParameter( Int_urt parNo, const string& name, Double_urt initVal, Double_urt initErr, Double_urt lowerLimit, Double_urt upperLimit )
289 {
290 // Define a parameter
291 
292  Int_urt err;
293 
294  const string& sname = name;
295  mnparm( parNo, sname, initVal, initErr, lowerLimit, upperLimit, err);
296 
297  return err;
298 }
299 
300 //______________________________________________________________________________
302 {
303 //*-*-*-*-*-*-*-*-*-*-*-*Delete internal Minuit arrays*-*-*-*-*-*-*-*-*
304 //*-* =============================
305  if (fEmpty) return;
306 // delete [] fCpnam;
307 // delete [] fU;
308  delete [] fAlim;
309  delete [] fBlim;
310  delete [] fErp;
311  delete [] fErn;
312  delete [] fWerr;
313  delete [] fGlobcc;
314 // delete [] fNvarl;
315 // delete [] fNiofex;
316  delete [] fNexofi;
317  delete [] fX;
318  delete [] fXt;
319  delete [] fDirin;
320  delete [] fXs;
321  delete [] fXts;
322  delete [] fDirins;
323  delete [] fGrd;
324  delete [] fG2;
325  delete [] fGstep;
326  delete [] fGin;
327  delete [] fDgrd;
328  delete [] fGrds;
329  delete [] fG2s;
330  delete [] fGsteps;
331  delete [] fIpfix;
332  delete [] fVhmat;
333  delete [] fVthmat;
334  delete [] fP;
335  delete [] fPstar;
336  delete [] fPstst;
337  delete [] fPbar;
338  delete [] fPrho;
339  delete [] fWord7;
340  delete [] fXpt;
341  delete [] fYpt;
342  delete [] fChpt;
343 
344  delete [] fCONTgcc;
345  delete [] fCONTw;
346  delete [] fFIXPyy;
347  delete [] fGRADgf;
348  delete [] fHESSyy;
349  delete [] fIMPRdsav;
350  delete [] fIMPRy;
351  delete [] fMATUvline;
352  delete [] fMIGRflnu;
353  delete [] fMIGRstep;
354  delete [] fMIGRgs;
355  delete [] fMIGRvg;
356  delete [] fMIGRxxs;
357  delete [] fMNOTxdev;
358  delete [] fMNOTw;
359  delete [] fMNOTgcc;
360  delete [] fPSDFs;
361  delete [] fSEEKxmid;
362  delete [] fSEEKxbest;
363  delete [] fSIMPy;
364  delete [] fVERTq;
365  delete [] fVERTs;
366  delete [] fVERTpp;
367  delete [] fCOMDplist;
368  delete [] fPARSplist;
369 
370  fEmpty = 1;
371 }
372 
373 //______________________________________________________________________________
374 Int_urt URMinuit::Eval(Int_urt npar, Double_urt *grad, Double_urt &fval, const vector<Double_urt>& par, Int_urt flag)
375 {
376 // Evaluate the minimisation function
377 // Input parameters:
378 // npar: number of currently variable parameters
379 // par: array of (constant and variable) parameters
380 // flag: Indicates what is to be calculated (see example below)
381 // grad: array of gradients
382 // Output parameters:
383 // fval: The calculated function value.
384 // grad: The (optional) vector of first derivatives).
385 //
386 // The meaning of the parameters par is of course defined by the user,
387 // who uses the values of those parameters to calculate his function value.
388 // The starting values must be specified by the user.
389 // Later values are determined by Minuit as it searches for the minimum
390 // or performs whatever analysis is requested by the user.
391 //
392 // Note that this virtual function may be redefined in a class derived from URMinuit.
393 // The default function calls the function specified in SetFCN
394 //
395 // Example of Minimisation function:
396 /*
397  if (flag == 1) {
398  read input data,
399  calculate any necessary constants, etc.
400  }
401  if (flag == 2) {
402  calculate GRAD, the first derivatives of FVAL
403  (this is optional)
404  }
405  Always calculate the value of the function, FVAL,
406  which is usually a chisquare or log likelihood.
407  if (iflag == 3) {
408  will come here only after the fit is finished.
409  Perform any final calculations, output fitted data, etc.
410  }
411 */
412 // See concrete examples in TH1::H1FitChisquare, H1FitLikelihood
413 
414  if (fFCN) (*fFCN)(npar,grad,fval,par,flag);
415  return 0;
416 }
417 
418 //______________________________________________________________________________
419 bool URMinuit::parameterFixed( Int_urt externalParameterId )
420 {
421 
422  // obtain internal Minuit id
423  Int_urt kint = m_userParameterIdToInternalId[externalParameterId];
424 
425  //*-*- see if parameter is floating
426  if (kint > 0) {
427  return false;
428  }
429  return true;
430 }
431 
432 //______________________________________________________________________________
434 {
435 // fix a parameter
436 
437  Int_urt err;
438 // Double_urt tmp = parNo+1; //set internal Minuit nuumbering
439  Double_urt tmp = parNo;
440 
441  mnexcm( "FIX", &tmp, 1, err );
442 
443  return err;
444 }
445 
446 
447 //______________________________________________________________________________
448 Int_urt URMinuit::GetParameter( Int_urt parNo, Double_urt &currentValue, Double_urt &currentError ) const
449 {
450 // return parameter value and error
451  Int_urt err;
452  string name; // ignored
453  Double_urt bnd1, bnd2; // ignored
454 
455  mnpout( parNo, name, currentValue, currentError, bnd1, bnd2, err );
456 
457  return err;
458 }
459 
460 //______________________________________________________________________________
462 {
463 // returns the number of currently fixed parameters
464 
465  return fNpfix;
466 }
467 
468 //______________________________________________________________________________
470 {
471 // returns the number of currently free parameters
472 
473  return fNpar;
474 }
475 
476 //______________________________________________________________________________
478 {
479 // returns the total number of parameters that have been defined.
480 // (fixed and free)
481 
482  return fNpar + fNpfix;
483 }
484 
485 //______________________________________________________________________________
487 {
488 // invokes the MIGRAD minimizer
489  Int_urt err;
490 
491 // configure command arguments here
492  Double_urt plist[] = { static_cast<Double_urt>(fMaxIterations) };
493  Int_urt npar = 1;
494 
495  mnexcm( "MIGRAD", plist, npar, err );
496 
497  return err;
498 }
499 
500 //______________________________________________________________________________
502 {
503  // invokes the HESSE error evaluation
504  Int_urt err;
505 
506  // configure command arguments here
507  Double_urt plist[] = { static_cast<Double_urt>(fMaxIterations) };
508  Int_urt npar = 1;
509 
510  mnexcm( "HESSE", plist, npar, err );
511 
512  return err;
513 }
514 
515 //______________________________________________________________________________
517 {
518  // invokes the MINOS minimizer
519  Int_urt err;
520 
521  // configure command arguments here
522  Double_urt plist[] = { static_cast<Double_urt>(fMaxIterations) };
523  Int_urt npar = 1;
524 
525  mnexcm( "MINOS", plist, npar, err );
526 
527  return err;
528 }
529 
530 //______________________________________________________________________________
532 {
533 // release a parameter
534 
535  Int_urt err;
536 // Double_urt tmp = parNo+1; //set internal Minuit numbering
537  Double_urt tmp = parNo; //set internal Minuit numbering
538 
539  mnexcm( "RELEASE", &tmp, 1, err );
540 
541  return err;
542 }
543 
544 //______________________________________________________________________________
546 {
547  Int_urt err;
548 
549  mnexcm( "SET ERRDEF", &up, 1, err );
550 
551  return err;
552 }
553 
554 //______________________________________________________________________________
556 {
557 //*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-*
558 //*-* ===============================================
559 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
560  fFCN = fcn;
561 }
562 
563 //______________________________________________________________________________
565 {
566  Int_urt err;
567  Double_urt tmp = printLevel;
568 
569  mnexcm( "SET PRINT", &tmp, 1, err );
570 
571  return err;
572 }
573 
574 //______________________________________________________________________________
576 {
577 //*-*-*-*-*-*-*-*-*-*-*-*-*Initialize AMIN*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
578 //*-* ===============
579 //*-*C Called from many places. Initializes the value of AMIN by
580 //*-*C calling the user function. Prints out the function value and
581 //*-*C parameter values if Print Flag value is high enough.
582 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
583 
584  /* Local variables */
585  Double_urt fnew;
586  Int_urt nparx;
587 
588  nparx = fNpar;
589  if (fISW[4] >= 1) {
590  *m_logStream << " FIRST CALL TO USER FUNCTION AT NEW START POINT, WITH IFLAG=4." << endl;;
591  }
592  mnexin(fX);
593 // Eval(nparx, fGin, fnew, fU, 4); ++fNfcn;
594  Eval(nparx, fGin, fnew, m_userParameterValue, 4); ++fNfcn;
595  fAmin = fnew;
596  fEDM = fBigedm;
597 } /* mnamin_ */
598 
599 //______________________________________________________________________________
601 {
602 //*-*-*-*-*-*-*-*-*-*-*Compute reasonable histogram intervals*-*-*-*-*-*-*-*-*
603 //*-* ======================================
604 //*-* Function TO DETERMINE REASONABLE HISTOGRAM INTERVALS
605 //*-* GIVEN ABSOLUTE UPPER AND LOWER BOUNDS A1 AND A2
606 //*-* AND DESIRED MAXIMUM NUMBER OF BINS NAA
607 //*-* PROGRAM MAKES REASONABLE BINNING FROM BL TO BH OF WIDTH BWID
608 //*-* F. JAMES, AUGUST, 1974 , stolen for Minuit, 1988
609 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
610 
611  /* Local variables */
612  Double_urt awid,ah, al, sigfig, sigrnd, alb;
613  Int_urt kwid, lwid, na=0, log_;
614 
615  al = URMath::Min(a1,a2);
616  ah = URMath::Max(a1,a2);
617  if (al == ah) ah = al + 1;
618 
619 //*-*- IF NAA .EQ. -1 , PROGRAM USES BWID INPUT FROM CALLING ROUTINE
620  if (naa == -1) goto L150;
621 L10:
622  na = naa - 1;
623  if (na < 1) na = 1;
624 
625 //*-*- GET NOMINAL BIN WIDTH IN EXPON FORM
626 L20:
627  awid = (ah-al) / Double_urt(na);
628  log_ = Int_urt(URMath::Log10(awid));
629  if (awid <= 1) --log_;
630  sigfig = awid*URMath::Power(10, -log_);
631 //*-*- ROUND MANTISSA UP TO 2, 2.5, 5, OR 10
632  if (sigfig > 2) goto L40;
633  sigrnd = 2;
634  goto L100;
635 L40:
636  if (sigfig > 2.5) goto L50;
637  sigrnd = 2.5;
638  goto L100;
639 L50:
640  if (sigfig > 5) goto L60;
641  sigrnd = 5;
642  goto L100;
643 L60:
644  sigrnd = 1;
645  ++log_;
646 L100:
647  bwid = sigrnd*URMath::Power(10, log_);
648  goto L200;
649 //*-*- GET NEW BOUNDS FROM NEW WIDTH BWID
650 L150:
651  if (bwid <= 0) goto L10;
652 L200:
653  alb = al / bwid;
654  lwid = Int_urt(alb);
655  if (alb < 0) --lwid;
656  bl = bwid*Double_urt(lwid);
657  alb = ah / bwid + 1;
658  kwid = Int_urt(alb);
659  if (alb < 0) --kwid;
660  bh = bwid*Double_urt(kwid);
661  nb = kwid - lwid;
662  if (naa > 5) goto L240;
663  if (naa == -1) return;
664 //*-*- REQUEST FOR ONE BIN IS DIFFICULT CASE
665  if (naa > 1 || nb == 1) return;
666  bwid *= 2;
667  nb = 1;
668  return;
669 L240:
670  if (nb << 1 != naa) return;
671  ++na;
672  goto L20;
673 } /* mnbins_ */
674 
675 //______________________________________________________________________________
677 {
678 //*-*-*-*-*-*-*-*-*-*Transform FCN to find further minima*-*-*-*-*-*-*-*-*-*
679 //*-* ====================================
680 //*-* Called only from MNIMPR. Transforms the function FCN
681 //*-* by dividing out the quadratic part in order to find further
682 //*-* minima. Calculates ycalf = (f-fmin)/(x-xmin)*v*(x-xmin)
683 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
684 
685  /* Local variables */
686  Int_urt ndex, i, j, m, n, nparx;
687  Double_urt denom, f;
688 
689  nparx = fNpar;
690  mninex(&pvec[0]);
691 // Eval(nparx, fGin, f, fU, 4); ++fNfcn;
692  Eval(nparx, fGin, f, m_userParameterValue, 4); ++fNfcn;
693  for (i = 1; i <= fNpar; ++i) {
694  fGrd[i-1] = 0;
695  for (j = 1; j <= fNpar; ++j) {
696  m = URMath::Max(i,j);
697  n = URMath::Min(i,j);
698  ndex = m*(m-1) / 2 + n;
699  fGrd[i-1] += fVthmat[ndex-1]*(fXt[j-1] - pvec[j-1]);
700  }
701  }
702  denom = 0;
703  for (i = 1; i <= fNpar; ++i) {denom += fGrd[i-1]*(fXt[i-1] - pvec[i-1]); }
704  if (denom <= 0) {
705  fDcovar = 1;
706  fISW[1] = 0;
707  denom = 1;
708  }
709  ycalf = (f - fApsi) / denom;
710 } /* mncalf_ */
711 
712 //______________________________________________________________________________
714 {
715 //*-*-*-*-*-*-*-*-*-*-*Resets the parameter list to UNDEFINED*-*-*-*-*-*-*-*
716 //*-* ======================================
717 //*-* Called from MINUIT and by option from MNEXCM
718 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
719 
720  Int_urt i;
721 
722  fNpfix = 0;
723  fNu = 0;
724  fNpar = 0;
725  fNfcn = 0;
726  fNwrmes[0] = 0;
727  fNwrmes[1] = 0;
728  for (i = 1; i <= fMaxext; ++i) {
729 // fU[i-1] = 0;
730  m_userParameterValue[i] = 0;
731 // fCpnam[i-1] = fCundef;
732  m_userParameterName[i] = fCundef;
733 // fNvarl[i-1] = -1;
734  m_userParameterFlag[i] = -1;
735 // fNiofex[i-1] = 0;
736  m_userParameterIdToInternalId[i] = 0;
737  }
738  mnrset(1);
739  fCfrom = "CLEAR ";
740  fNfcnfr = fNfcn;
741  fCstatu = "UNDEFINED ";
742  fLnolim = kurTRUE;
743  fLphead = kurTRUE;
744 } /* mncler_ */
745 
746 //______________________________________________________________________________
747 void URMinuit::mncntr(Int_urt ike1, Int_urt ike2, Int_urt &ierrf)
748 {
749 //*-*-*-*-*Print function contours in two variables, on line printer*-*-*-*-*
750 //*-* =========================================================
751 //*-*
752 //*-* input arguments: parx, pary, devs, ngrid
753 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
754 
755  static string clabel = "0123456789ABCDEFGHIJ";
756 
757  /* Local variables */
758  Double_urt d__1, d__2;
759  Double_urt fcna[115], fcnb[115], contur[20];
760  Double_urt ylabel, fmn, fmx, xlo, ylo, xup, yup;
761  Double_urt devs, xsav, ysav, bwidx, bwidy, unext, ff, xb4;
762  Int_urt i, ngrid, ixmid, nparx, ix, nx, ny, ki1, ki2, ixzero, iy, ics;
763  string chmid, chln, chzero;
764 
765  // modified ke1, ke2 to not increment ike1,ike2
766  Int_urt ke1 = ike1;
767  Int_urt ke2 = ike2;
768  if (ke1 <= 0 || ke2 <= 0) goto L1350;
769  if (ke1 > fNu || ke2 > fNu) goto L1350;
770 // ki1 = fNiofex[ke1-1];
771 // ki2 = fNiofex[ke2-1];
772  ki1 = m_userParameterIdToInternalId[ke1];
773  ki2 = m_userParameterIdToInternalId[ke2];
774  if (ki1 <= 0 || ki2 <= 0) goto L1350;
775  if (ki1 == ki2) goto L1350;
776 
777  if (fISW[1] < 1) {
778  mnhess();
779  mnwerr();
780  }
781  nparx = fNpar;
782 // xsav = fU[ke1-1];
783 // ysav = fU[ke2-1];
784  xsav = m_userParameterValue[ke1];
785  ysav = m_userParameterValue[ke2];
786  devs = fWord7[2];
787  if (devs <= 0) devs = 2;
788 // xlo = fU[ke1-1] - devs*fWerr[ki1-1];
789 // xup = fU[ke1-1] + devs*fWerr[ki1-1];
790 // ylo = fU[ke2-1] - devs*fWerr[ki2-1];
791 // yup = fU[ke2-1] + devs*fWerr[ki2-1];
792  xlo = m_userParameterValue[ke1] - devs*fWerr[ki1-1];
793  xup = m_userParameterValue[ke1] + devs*fWerr[ki1-1];
794  ylo = m_userParameterValue[ke2] - devs*fWerr[ki2-1];
795  yup = m_userParameterValue[ke2] + devs*fWerr[ki2-1];
796  ngrid = Int_urt(fWord7[3]);
797  if (ngrid <= 0) {
798  ngrid = 25;
799 //*-* Computing MIN
800  nx = URMath::Min(fNpagwd - 15,ngrid);
801 //*-* Computing MIN
802  ny = URMath::Min(fNpagln - 7,ngrid);
803  } else {
804  nx = ngrid;
805  ny = ngrid;
806  }
807  if (nx < 11) nx = 11;
808  if (ny < 11) ny = 11;
809  if (nx >= 115) nx = 114;
810 
811 //*-*- ask if parameter outside limits
812 // if (fNvarl[ke1-1] > 1) {
813  if (m_userParameterFlag[ke1] > 1) {
814  if (xlo < fAlim[ke1-1]) xlo = fAlim[ke1-1];
815  if (xup > fBlim[ke1-1]) xup = fBlim[ke1-1];
816  }
817 // if (fNvarl[ke2-1] > 1) {
818  if (m_userParameterFlag[ke2] > 1) {
819  if (ylo < fAlim[ke2-1]) ylo = fAlim[ke2-1];
820  if (yup > fBlim[ke2-1]) yup = fBlim[ke2-1];
821  }
822  bwidx = (xup - xlo) / Double_urt(nx);
823  bwidy = (yup - ylo) / Double_urt(ny);
824  ixmid = Int_urt(((xsav - xlo)*Double_urt(nx) / (xup - xlo)) + 1);
825  if (fAmin == fUndefi) mnamin();
826 
827  for (i = 1; i <= 20; ++i) { contur[i-1] = fAmin + fUp*(i-1)*(i-1); }
828  contur[0] += fUp*.01;
829 //*-*- fill FCNB to prepare first row, and find column zero/
830 // fU[ke2-1] = yup;
831  m_userParameterValue[ke2] = yup;
832  ixzero = 0;
833  xb4 = 1;
834 //TH
835  chmid.resize(nx+1, ' ');
836  chzero.resize(nx+1, ' ');
837  chln.resize(nx+1, ' ');
838  for (ix = 1; ix <= nx + 1; ++ix) {
839 // fU[ke1-1] = xlo + Double_urt(ix-1)*bwidx;
840  m_userParameterValue[ke1] = xlo + Double_urt(ix-1)*bwidx;
841 // Eval(nparx, fGin, ff, fU, 4);
842  Eval(nparx, fGin, ff, m_userParameterValue, 4);
843  fcnb[ix-1] = ff;
844 // if (xb4 < 0 && fU[ke1-1] > 0) ixzero = ix - 1;
845  if (xb4 < 0 && m_userParameterValue[ke1] > 0) ixzero = ix - 1;
846 // xb4 = fU[ke1-1];
847  xb4 = m_userParameterValue[ke1];
848  chmid[ix-1] = '*';
849  chzero[ix-1] = '-';
850  }
851 // std::printf(" Y-AXIS: PARAMETER %3d: %s\n",ke2, fCpnam[ke2-1].c_str() );
852 // std::printf(" Y-AXIS: PARAMETER %3d: %s\n",ke2, m_userParameterName[ke2].c_str() );
853  *m_logStream << " Y-AXIS: PARAMETER " << setw(3) << ke2 << ": " << m_userParameterName[ke2] << '\n';
854  if (ixzero > 0) {
855  chzero[ixzero-1] = '+';
856  chln = " ";
857  *m_logStream << " X=0\n";
858  //std::printf(" X=0\n");
859  }
860 //*-*- loop over rows
861  for (iy = 1; iy <= ny; ++iy) {
862 // unext = fU[ke2-1] - bwidy;
863  unext = m_userParameterValue[ke2] - bwidy;
864 //*-*- prepare this line background pattern for contour
865  chln = " ";
866 // TH
867  chln.resize(nx+1, ' ');
868  chln[ixmid-1] = '*';
869  if (ixzero != 0) chln[ixzero-1] = ':';
870 // if (fU[ke2-1] > ysav && unext < ysav) chln = chmid;
871 // if (fU[ke2-1] > 0 && unext < 0) chln = chzero;
872  if (m_userParameterValue[ke2] > ysav && unext < ysav) chln = chmid;
873  if (m_userParameterValue[ke2] > 0 && unext < 0) chln = chzero;
874 // fU[ke2-1] = unext;
875 // ylabel = fU[ke2-1] + bwidy*.5;
876  m_userParameterValue[ke2] = unext;
877  ylabel = m_userParameterValue[ke2] + bwidy*.5;
878 //*-*- move FCNB to FCNA and fill FCNB with next row
879  for (ix = 1; ix <= nx + 1; ++ix) {
880  fcna[ix-1] = fcnb[ix-1];
881 // fU[ke1-1] = xlo + Double_urt(ix-1)*bwidx;
882  m_userParameterValue[ke1] = xlo + Double_urt(ix-1)*bwidx;
883 // Eval(nparx, fGin, ff, fU, 4);
884  Eval(nparx, fGin, ff, m_userParameterValue, 4);
885  fcnb[ix-1] = ff;
886  }
887 //*-*- look for contours crossing the FCNxy squares
888  for (ix = 1; ix <= nx; ++ix) {
889  d__1 = URMath::Max(fcna[ix-1],fcnb[ix-1]),
890  d__2 = URMath::Max(fcna[ix],fcnb[ix]);
891  fmx = URMath::Max(d__1,d__2);
892  d__1 = URMath::Min(fcna[ix-1],fcnb[ix-1]),
893  d__2 = URMath::Min(fcna[ix],fcnb[ix]);
894  fmn = URMath::Min(d__1,d__2);
895  for (ics = 1; ics <= 20; ++ics) {
896  if (contur[ics-1] > fmn) goto L240;
897  }
898  continue;
899 L240:
900  if (contur[ics-1] < fmx) chln[ix-1] = clabel[ics-1];
901  }
902 //*-*- print a row of the contour plot
903  *m_logStream << setw(12) << setprecision(4) << ylabel << chln << '\n';
904  // std::printf(" %12.4g %s\n",ylabel,chln.c_str() );
905  }
906 //*-*- contours printed, label x-axis
907  chln = " ";
908  chln.resize(nx+1, ' ');
909  chln.replace(0,1,"I");
910  chln.replace(ixmid-1,1,"I");
911  chln.replace(nx-1,1,"I");
912  // std::printf(" %s\n", chln.c_str());
913  *m_logStream << " " << chln << '\n';
914 
915 //*-*- the hardest of all: print x-axis scale!
916  chln = " ";
917  if (nx <= 26) {
918  //std::printf(" %12.4g%s%12.4g\n",xlo,chln.c_str(),xup);
919  *m_logStream << " " << setw(12) << setprecision(4) << xlo << chln << setw(12) << xup << '\n';
920  //std::printf(" %s%12.4g\n",chln.c_str(),xsav);
921  *m_logStream << " " << chln << setw(12) << setprecision(4) << xsav << '\n';
922  } else {
923  //std::printf(" %12.4g%s%12.4g%s%12.4g\n",xlo,chln.c_str(),xsav,chln.c_str(),xup);
924  *m_logStream << " " << setw(12) << setprecision(4) << xlo << chln
925  << setw(12) << setprecision(4) << xsav << chln
926  << setw(12) << setprecision(4) << xup << '\n';
927  }
928 // std::printf(" X-AXIS: PARAMETER%3d: %s ONE COLUMN=%12.4g\n"
929 // ,ke1,(fCpnam[ke1-1]).c_str(),bwidx);
930  //std::printf(" X-AXIS: PARAMETER%3d: %s ONE COLUMN=%12.4g\n"
931  // ,ke1,(m_userParameterName[ke1]).c_str(),bwidx);
932  *m_logStream << " X-AXIS: PARAMETER" << setw(3) << ke1 << ": "<< m_userParameterName[ke1]
933  << " ONE COLUMN=" << setw(12) << setprecision(4) << bwidx << '\n';
934  //std::printf(" FUNCTION VALUES: F(I)=%12.4g +%12.4g *I**2\n",fAmin,fUp);
935  *m_logStream << " FUNCTION VALUES: F(I)=" << setw(12) << setprecision(4) << fAmin
936  << " +" << setw(12) << setprecision(4) << fUp << " *I**2\n";
937 //*-*- finished. reset input values
938 // fU[ke1-1] = xsav;
939 // fU[ke2-1] = ysav;
940  m_userParameterValue[ke1] = xsav;
941  m_userParameterValue[ke2] = ysav;
942  ierrf = 0;
943  *m_logStream << endl;
944  return;
945 L1350:
946  *m_logStream << " INVALID PARAMETER NUMBER(S) REQUESTED. IGNORED." << endl;
947  //std::printf(" INVALID PARAMETER NUMBER(S) REQUESTED. IGNORED.\n");
948  ierrf = 1;
949 } /* mncntr_ */
950 
951 //______________________________________________________________________________
952 void URMinuit::mncomd(const string& crdbin, Int_urt &icondn)
953 {
954 //*-*-*-*-*-*-*-*-*-*-*Reads a command string and executes*-*-*-*-*-*-*-*-*-*
955 //*-* ===================================
956 //*-* Called by user. 'Reads' a command string and executes.
957 //*-* Equivalent to MNEXCM except that the command is given as a
958 //*-* character string.
959 //*-*
960 //*-* ICONDN = 0: command executed normally
961 //*-* 1: command is blank, ignored
962 //*-* 2: command line unreadable, ignored
963 //*-* 3: unknown command, ignored
964 //*-* 4: abnormal termination (e.g., MIGRAD not converged)
965 //*-* 5: command is a request to read PARAMETER definitions
966 //*-* 6: 'SET INPUT' command
967 //*-* 7: 'SET TITLE' command
968 //*-* 8: 'SET COVAR' command
969 //*-* 9: reserved
970 //*-* 10: END command
971 //*-* 11: EXIT or STOP command
972 //*-* 12: RETURN command
973 //*-*
974 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
975 
976  /* Local variables */
977  Int_urt ierr, ipos, i, llist, lenbuf, lnc;
978  Bool_urt leader;
979  string comand, crdbuf, ctemp;
980 
981  crdbuf = crdbin;
982  int (*pf)(int)=toupper;
983  transform(crdbuf.begin(), crdbuf.end(), crdbuf.begin(), pf);
984  lenbuf = crdbuf.length();
985  icondn = 0;
986 //*-*- record not case-sensitive, get upper case, strip leading blanks
987  leader = kurTRUE;
988  ipos = 1;
989  for (i = 1; i <= URMath::Min(20,lenbuf); ++i) {
990  if (crdbuf[i-1] == '\'') break;
991  if (crdbuf[i-1] == ' ') {
992  if (leader) ++ipos;
993  continue;
994  }
995  leader = kurFALSE;
996  }
997 
998 //*-*- blank or null command
999  if (ipos > lenbuf) {
1000  *m_logStream << " BLANK COMMAND IGNORED." << endl;
1001  //std::printf(" BLANK COMMAND IGNORED.\n");
1002  icondn = 1;
1003  return;
1004  }
1005 //*-*- . . preemptive commands
1006 //*-*- if command is 'PARAMETER'
1007  if (crdbuf.substr(ipos-1,3) == "PAR") {
1008  icondn = 5;
1009  fLphead = kurTRUE;
1010  return;
1011  }
1012 //*-*- if command is 'SET INPUT'
1013  if (crdbuf.substr(ipos-1,7) == "SET INP") {
1014  icondn = 6;
1015  fLphead = kurTRUE;
1016  return;
1017  }
1018 //*-*- if command is 'SET TITLE'
1019  if (crdbuf.substr(ipos-1,7) == "SET TIT") {
1020  icondn = 7;
1021  fLphead = kurTRUE;
1022  return;
1023  }
1024 //*-*- if command is 'SET COVARIANCE'
1025  if (crdbuf.substr(ipos-1,7) == "SET COV") {
1026  icondn = 8;
1027  fLphead = kurTRUE;
1028  return;
1029  }
1030 //*-*- crack the command . . . . . . . . . . . . . . . .
1031  ctemp = crdbuf.substr(ipos-1,lenbuf-ipos+1);
1032  mncrck(ctemp, 20, comand, lnc, fMaxpar, fCOMDplist, llist, ierr, fIsyswr);
1033  if (ierr > 0) {
1034  //std::printf(" COMMAND CANNOT BE INTERPRETED\n");
1035  *m_logStream << " COMMAND CANNOT BE INTERPRETED" << endl;
1036  icondn = 2;
1037  return;
1038  }
1039 
1040  mnexcm(comand, fCOMDplist, llist, ierr);
1041  icondn = ierr;
1042 } /* mncomd_ */
1043 
1044 //______________________________________________________________________________
1045 void URMinuit::mncont(Int_urt ike1, Int_urt ike2, Int_urt nptu, Double_urt *xptu, Double_urt *yptu, Int_urt &ierrf)
1046 {
1047 //*-*-*-*-*-*-*Find points along a contour where FCN is minimum*-*-*-*-*-*-*
1048 //*-* ================================================
1049 //*-* Find NPTU points along a contour where the function
1050 //*-* FMIN (X(KE1),X(KE2)) = AMIN+UP
1051 //*-* where FMIN is the minimum of FCN with respect to all
1052 //*-* the other NPAR-2 variable parameters (if any).
1053 //*-* IERRF on return will be equal to the number of points found:
1054 //*-* NPTU if normal termination with NPTU points found
1055 //*-* -1 if errors in the calling sequence (KE1, KE2 not variable)
1056 //*-* 0 if less than four points can be found (using MNMNOT)
1057 //*-* n>3 if only n points can be found (n < NPTU)
1058 //*-*
1059 //*-* input arguments: parx, pary, devs, ngrid
1060 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1061  /* System generated locals */
1062  Int_urt i__1;
1063 
1064  /* Local variables */
1065  Double_urt d__1, d__2;
1066  Double_urt dist, xdir, ydir, aopt, u1min, u2min;
1067  Double_urt abest, scalx, scaly;
1068  Double_urt a1, a2, val2mi, val2pl, dc, sclfac, bigdis, sigsav;
1069  Int_urt nall, iold, line, mpar, ierr, inew, move, next, i, j, nfcol, iercr;
1070  Int_urt idist=0, npcol, kints, i2, i1, lr, nfcnco=0, ki1, ki2, ki3, ke3;
1071  Int_urt nowpts, istrav, nfmxin, isw2, isw4;
1072  Bool_urt ldebug;
1073 
1074  /* Function Body */
1075 // Int_urt ke1 = ike1+1;
1076 // Int_urt ke2 = ike2+1;
1077  Int_urt ke1 = ike1;
1078  Int_urt ke2 = ike2;
1079  ldebug = fIdbg[6] >= 1;
1080 // if (ke1 <= 0 || ke2 <= 0) goto L1350;
1081 // if (ke1 > fNu || ke2 > fNu) goto L1350;
1082  if (ke1 <= 0 || ke2 <= 0) goto L1350;
1083  if (ke1 > fNu || ke2 > fNu) goto L1350;
1084 // ki1 = fNiofex[ke1-1];
1085 // ki2 = fNiofex[ke2-1];
1086  ki1 = m_userParameterIdToInternalId[ke1];
1087  ki2 = m_userParameterIdToInternalId[ke2];
1088  if (ki1 <= 0 || ki2 <= 0) goto L1350;
1089  if (ki1 == ki2) goto L1350;
1090  if (nptu < 4) goto L1400;
1091 
1092  nfcnco = fNfcn;
1093  fNfcnmx = (nptu + 5)*100*(fNpar + 1);
1094 //*-*- The minimum
1095  mncuve();
1096 // u1min = fU[ke1-1];
1097 // u2min = fU[ke2-1];
1098  u1min = m_userParameterValue[ke1];
1099  u2min = m_userParameterValue[ke2];
1100  ierrf = 0;
1101  fCfrom = "MNContour ";
1102  fNfcnfr = nfcnco;
1103  if (fISW[4] >= 0) {
1104  //std::printf(" START MNCONTOUR CALCULATION OF%4d POINTS ON CONTOUR.\n",nptu);
1105  *m_logStream << " START MNCONTOUR CALCULATION OF" << setw(4) << nptu << " POINTS ON CONTOUR." << endl;
1106  if (fNpar > 2) {
1107  if (fNpar == 3) {
1108  ki3 = 6 - ki1 - ki2;
1109  ke3 = fNexofi[ki3-1];
1110 // std::printf(" EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER %3d %s\n",ke3,fCpnam[ke3-1].c_str());
1111  //std::printf(" EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER %3d %s\n",ke3,m_userParameterName[ke3].c_str());
1112  *m_logStream << " EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER " << setw(3) << ke3
1113  << " " << m_userParameterName[ke3] << endl;
1114  } else {
1115  //std::printf(" EACH POINT IS A MINIMUM WITH RESPECT TO THE OTHER%3d VARIABLE PARAMETERS.\n",fNpar - 2);
1116  *m_logStream << " EACH POINT IS A MINIMUM WITH RESPECT TO THE OTHER" << setw(3) << (fNpar - 2)
1117  << " VARIABLE PARAMETERS." << endl;
1118  }
1119  }
1120  }
1121 
1122 //*-*- Find the first four points using MNMNOT
1123 //*-*- ........................ first two points
1124  mnmnot(ke1, ke2, val2pl, val2mi);
1125  if (fErn[ki1-1] == fUndefi) {
1126  xptu[0] = fAlim[ke1-1];
1127  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1128  } else {
1129  if (fErn[ki1-1] >= 0) goto L1500;
1130  xptu[0] = u1min + fErn[ki1-1];
1131  }
1132  yptu[0] = val2mi;
1133 
1134  if (fErp[ki1-1] == fUndefi) {
1135  xptu[2] = fBlim[ke1-1];
1136  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1137  } else {
1138  if (fErp[ki1-1] <= 0) goto L1500;
1139  xptu[2] = u1min + fErp[ki1-1];
1140  }
1141  yptu[2] = val2pl;
1142  scalx = 1 / (xptu[2] - xptu[0]);
1143 //*-*- ........................... next two points
1144  mnmnot(ke2, ke1, val2pl, val2mi);
1145  if (fErn[ki2-1] == fUndefi) {
1146  yptu[1] = fAlim[ke2-1];
1147  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1148  } else {
1149  if (fErn[ki2-1] >= 0) goto L1500;
1150  yptu[1] = u2min + fErn[ki2-1];
1151  }
1152  xptu[1] = val2mi;
1153  if (fErp[ki2-1] == fUndefi) {
1154  yptu[3] = fBlim[ke2-1];
1155  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1156  } else {
1157  if (fErp[ki2-1] <= 0) goto L1500;
1158  yptu[3] = u2min + fErp[ki2-1];
1159  }
1160  xptu[3] = val2pl;
1161  scaly = 1 / (yptu[3] - yptu[1]);
1162  nowpts = 4;
1163  next = 5;
1164  if (ldebug) {
1165  //std::printf(" Plot of four points found by MINOS\n");
1166  *m_logStream << " Plot of four points found by MINOS" << endl;
1167  fXpt[0] = u1min;
1168  fYpt[0] = u2min;
1169  fChpt[0] = ' ';
1170 //*-* Computing MIN
1171  nall = URMath::Min(nowpts + 1,101);
1172  for (i = 2; i <= nall; ++i) {
1173  fXpt[i-1] = xptu[i-2];
1174  fYpt[i-1] = yptu[i-2];
1175  }
1176  //std::printf(fChpt,"%s"," ABCD");
1177  *m_logStream << fChpt << " ABCD" << endl;
1178  mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1179  }
1180 
1181 //*-*- ..................... save some values before fixing
1182  isw2 = fISW[1];
1183  isw4 = fISW[3];
1184  sigsav = fEDM;
1185  istrav = fIstrat;
1186  dc = fDcovar;
1187  fApsi = fEpsi*.5;
1188  abest = fAmin;
1189  mpar = fNpar;
1190  nfmxin = fNfcnmx;
1191  for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
1192  i__1 = mpar*(mpar + 1) / 2;
1193  for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
1194  for (i = 1; i <= mpar; ++i) {
1195  fCONTgcc[i-1] = fGlobcc[i-1];
1196  fCONTw[i-1] = fWerr[i-1];
1197  }
1198 //*-*- fix the two parameters in question
1199 // kints = fNiofex[ke1-1];
1200  kints = m_userParameterIdToInternalId[ke1];
1201  mnfixp(kints-1, ierr);
1202 // kints = fNiofex[ke2-1];
1203  kints = m_userParameterIdToInternalId[ke2];
1204  mnfixp(kints-1, ierr);
1205 //*-*- ......................Fill in the rest of the points
1206  for (inew = next; inew <= nptu; ++inew) {
1207 //*-* find the two neighbouring points with largest separation
1208  bigdis = 0;
1209  for (iold = 1; iold <= inew - 1; ++iold) {
1210  i2 = iold + 1;
1211  if (i2 == inew) i2 = 1;
1212  d__1 = scalx*(xptu[iold-1] - xptu[i2-1]);
1213  d__2 = scaly*(yptu[iold-1] - yptu[i2-1]);
1214  dist = d__1*d__1 + d__2*d__2;
1215  if (dist > bigdis) {
1216  bigdis = dist;
1217  idist = iold;
1218  }
1219  }
1220  i1 = idist;
1221  i2 = i1 + 1;
1222  if (i2 == inew) i2 = 1;
1223 //*-*- next point goes between I1 and I2
1224  a1 = .5;
1225  a2 = .5;
1226 L300:
1227  fXmidcr = a1*xptu[i1-1] + a2*xptu[i2-1];
1228  fYmidcr = a1*yptu[i1-1] + a2*yptu[i2-1];
1229  xdir = yptu[i2-1] - yptu[i1-1];
1230  ydir = xptu[i1-1] - xptu[i2-1];
1231  sclfac = URMath::Max(URMath::Abs(xdir*scalx),URMath::Abs(ydir*scaly));
1232  fXdircr = xdir / sclfac;
1233  fYdircr = ydir / sclfac;
1234  fKe1cr = ke1;
1235  fKe2cr = ke2;
1236 //*-*- Find the contour crossing point along DIR
1237  fAmin = abest;
1238  mncros(aopt, iercr);
1239  if (iercr > 1) {
1240 //*-*- If cannot find mid-point, try closer to point 1
1241  if (a1 > .5) {
1242  if (fISW[4] >= 0) {
1243  //std::printf(" MNCONT CANNOT FIND NEXT POINT ON CONTOUR. ONLY%3d POINTS FOUND.\n",nowpts);
1244  *m_logStream << " MNCONT CANNOT FIND NEXT POINT ON CONTOUR. ONLY" << setw(3) << nowpts
1245  << " POINTS FOUND." << endl;
1246  }
1247  goto L950;
1248  }
1249  mnwarn("W", "MNContour ", "Cannot find midpoint, try closer.");
1250  a1 = .75;
1251  a2 = .25;
1252  goto L300;
1253  }
1254 //*-*- Contour has been located, insert new point in list
1255  for (move = nowpts; move >= i1 + 1; --move) {
1256  xptu[move] = xptu[move-1];
1257  yptu[move] = yptu[move-1];
1258  }
1259  ++nowpts;
1260  xptu[i1] = fXmidcr + fXdircr*aopt;
1261  yptu[i1] = fYmidcr + fYdircr*aopt;
1262  }
1263 L950:
1264 
1265  ierrf = nowpts;
1266  fCstatu = "SUCCESSFUL";
1267  if (nowpts < nptu) fCstatu = "INCOMPLETE";
1268 
1269 //*-*- make a lineprinter plot of the contour
1270  if (fISW[4] >= 0) {
1271  fXpt[0] = u1min;
1272  fYpt[0] = u2min;
1273  fChpt[0] = ' ';
1274  nall = URMath::Min(nowpts + 1,101);
1275  for (i = 2; i <= nall; ++i) {
1276  fXpt[i-1] = xptu[i-2];
1277  fYpt[i-1] = yptu[i-2];
1278  fChpt[i-1] = 'X';
1279  }
1280  fChpt[nall] = 0;
1281 // std::printf(" Y-AXIS: PARAMETER %3d %s\n",ke2,fCpnam[ke2-1].c_str());
1282  //std::printf(" Y-AXIS: PARAMETER %3d %s\n",ke2,m_userParameterName[ke2].c_str());
1283  *m_logStream << " Y-AXIS: PARAMETER " << setw(3) << ke2 << " " << m_userParameterName[ke2] << '\n';
1284 
1285  mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1286 
1287 // std::printf(" X-AXIS: PARAMETER %3d %s\n",ke1,fCpnam[ke1-1].c_str());
1288  //std::printf(" X-AXIS: PARAMETER %3d %s\n",ke1,m_userParameterName[ke1].c_str());
1289  *m_logStream << " X-AXIS: PARAMETER " << setw(3) << ke1 << " " << m_userParameterName[ke1] << '\n';
1290  }
1291 //*-*- print out the coordinates around the contour
1292  if (fISW[4] >= 1) {
1293  npcol = (nowpts + 1) / 2;
1294  nfcol = nowpts / 2;
1295  //std::printf("%5d POINTS ON CONTOUR. FMIN=%13.5e ERRDEF=%11.3g\n",nowpts,abest,fUp);
1296  *m_logStream << setw(5) << nowpts << " POINTS ON CONTOUR. FMIN=" << setw(13) << setprecision(5) << abest
1297  << " ERRDEF=" << setw(11) << setprecision(3) << fUp << '\n';
1298 // std::printf(" %s%s%s%s\n",fCpnam[ke1-1].c_str(),
1299 // fCpnam[ke2-1].c_str(),
1300 // fCpnam[ke1-1].c_str(),
1301 // fCpnam[ke2-1].c_str());
1302  //std::printf(" %s%s%s%s\n",m_userParameterName[ke1].c_str(),
1303  // m_userParameterName[ke2].c_str(),
1304  // m_userParameterName[ke1].c_str(),
1305  // m_userParameterName[ke2].c_str());
1306  *m_logStream << " " << m_userParameterName[ke1] << m_userParameterName[ke2]
1307  << m_userParameterName[ke1] << m_userParameterName[ke1] << '\n';
1308  for (line = 1; line <= nfcol; ++line) {
1309  lr = line + npcol;
1310  //std::printf(" %5d%13.5e%13.5e %5d%13.5e%13.5e\n",line,xptu[line-1],yptu[line-1],lr,xptu[lr-1],yptu[lr-1]);
1311  *m_logStream << setw(6) << line << setw(13) << setprecision(5) << xptu[line-1] << setw(13) << setprecision(5) << yptu[line-1]
1312  << setw(15) << lr << setw(13) << setprecision(5) << xptu[lr-1] << setw(13) << setprecision(5) << yptu[lr-1] << '\n';
1313  }
1314  if (nfcol < npcol) {
1315  //std::printf(" %5d%13.5e%13.5e\n",npcol,xptu[npcol-1],yptu[npcol-1]);
1316  *m_logStream << setw(6) << npcol << setw(13) << setprecision(5) << xptu[npcol-1] << setw(13) << setprecision(5) << yptu[npcol-1] << '\n';
1317  }
1318  }
1319 //*-*- . . contour finished. reset v
1320  fItaur = 1;
1321  mnfree(1);
1322  mnfree(1);
1323  i__1 = mpar*(mpar + 1) / 2;
1324  for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
1325  for (i = 1; i <= mpar; ++i) {
1326  fGlobcc[i-1] = fCONTgcc[i-1];
1327  fWerr[i-1] = fCONTw[i-1];
1328  fX[i-1] = fXt[i-1];
1329  }
1330  mninex(fX);
1331  fEDM = sigsav;
1332  fAmin = abest;
1333  fISW[1] = isw2;
1334  fISW[3] = isw4;
1335  fDcovar = dc;
1336  fItaur = 0;
1337  fNfcnmx = nfmxin;
1338  fIstrat = istrav;
1339 // fU[ke1-1] = u1min;
1340 // fU[ke2-1] = u2min;
1341  m_userParameterValue[ke1] = u1min;
1342  m_userParameterValue[ke2] = u2min;
1343  goto L2000;
1344 //*-*- Error returns
1345 L1350:
1346  //std::printf(" INVALID PARAMETER NUMBERS.\n");
1347  *m_logStream << " INVALID PARAMETER NUMBERS.\n";
1348  goto L1450;
1349 L1400:
1350  //std::printf(" LESS THAN FOUR POINTS REQUESTED.\n");
1351  *m_logStream << " LESS THAN FOUR POINTS REQUESTED.\n";
1352 L1450:
1353  ierrf = -1;
1354  fCstatu = "USER ERROR";
1355  goto L2000;
1356 L1500:
1357  //std::printf(" MNCONT UNABLE TO FIND FOUR POINTS.\n");
1358  *m_logStream << " MNCONT UNABLE TO FIND FOUR POINTS.\n";
1359 // fU[ke1-1] = u1min;
1360 // fU[ke2-1] = u2min;
1361  m_userParameterValue[ke1] = u1min;
1362  m_userParameterValue[ke2] = u2min;
1363  ierrf = 0;
1364  fCstatu = "FAILED";
1365 L2000:
1366  fCfrom = "MNContour ";
1367  fNfcnfr = nfcnco;
1368  *m_logStream << endl;
1369 } /* mncont_ */
1370 
1371 //______________________________________________________________________________
1372 //void URMinuit::mncrck(const string& cardbuf, Int_urt maxcwd, const string &comand, Int_urt &lnc,
1373 // header change (mrs43):
1374 // seems as if the point of this is to modify comand - should not be a const reference
1375 // cardbuf also appears to be an input only -- pass by value instead of const reference
1376 void URMinuit::mncrck(string cardbuf, Int_urt maxcwd, string& comand, Int_urt &lnc,
1377  Int_urt mxp, Double_urt *plist, Int_urt &llist, Int_urt &ierr, Int_urt)
1378 {
1379 //*-*-*-*-*-*-*-*-*-*-*-*Cracks the free-format input*-*-*-*-*-*-*-*-*-*-*-*-*
1380 //*-* ============================
1381 //*-* Cracks the free-format input, expecting zero or more
1382 //*-* alphanumeric fields (which it joins into COMAND(1:LNC))
1383 //*-* followed by one or more numeric fields separated by
1384 //*-* blanks and/or one comma. The numeric fields are put into
1385 //*-* the LLIST (but at most MXP) elements of PLIST.
1386 //*-* IERR = 0 if no errors,
1387 //*-* = 1 if error(s).
1388 //*-*
1389 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1390  /* Initialized data */
1391 
1392  char *cnull = 0;
1393  const char *cnumer = "123456789-.0+";
1394 
1395  /* Local variables */
1396  Int_urt ifld, iend, lend, left, nreq, ipos, kcmnd, nextb, ic, ibegin, ltoadd;
1397  Int_urt ielmnt, lelmnt[25], nelmnt;
1398  string ctemp;
1399  char *celmnt[25];
1400  char command[25];
1401 
1402  /* Function Body */
1403  char *crdbuf = const_cast<char*>( cardbuf.c_str() );
1404  lend = cardbuf.length();
1405  ielmnt = 0;
1406  nextb = 1;
1407  ierr = 0;
1408 //*-*- . . . . loop over words CELMNT
1409 L10:
1410  for (ipos = nextb; ipos <= lend; ++ipos) {
1411  ibegin = ipos;
1412  if (crdbuf[ipos-1] == ' ') continue;
1413  if (crdbuf[ipos-1] == ',') goto L250;
1414  goto L150;
1415  }
1416  goto L300;
1417 L150:
1418 //*-*- found beginning of word, look for end
1419  for (ipos = ibegin + 1; ipos <= lend; ++ipos) {
1420  if (crdbuf[ipos-1] == ' ') goto L250;
1421  if (crdbuf[ipos-1] == ',') goto L250;
1422  }
1423  ipos = lend + 1;
1424 L250:
1425  iend = ipos - 1;
1426  ++ielmnt;
1427  if (iend >= ibegin) celmnt[ielmnt-1] = &crdbuf[ibegin-1];
1428  else celmnt[ielmnt-1] = cnull;
1429  lelmnt[ielmnt-1] = iend - ibegin + 1;
1430  if (lelmnt[ielmnt-1] > 19) {
1431  //std::printf(" MINUIT WARNING: INPUT DATA WORD TOO LONG.\n");
1432  *m_logStream << " MINUIT WARNING: INPUT DATA WORD TOO LONG." << endl;
1433  ctemp = cardbuf.substr(ibegin-1,iend-ibegin+1);
1434  //std::printf(" ORIGINAL:%s\n",ctemp.c_str());
1435  *m_logStream << " ORIGINAL:" << ctemp << '\n';
1436  //std::printf(" TRUNCATED TO:%s\n",celmnt[ielmnt-1]);
1437  *m_logStream << " TRUNCATED TO:" << celmnt[ielmnt-1] << endl;
1438  lelmnt[ielmnt-1] = 19;
1439  }
1440  if (ipos >= lend) goto L300;
1441  if (ielmnt >= 25) goto L300;
1442 //*-*- look for comma or beginning of next word
1443  for (ipos = iend + 1; ipos <= lend; ++ipos) {
1444  if (crdbuf[ipos-1] == ' ') continue;
1445  nextb = ipos;
1446  if (crdbuf[ipos-1] == ',') nextb = ipos + 1;
1447  goto L10;
1448  }
1449 //*-*- All elements found, join the alphabetic ones to
1450 //*-*- form a command
1451 L300:
1452  nelmnt = ielmnt;
1453  command[0] = ' '; command[1] = 0;
1454  lnc = 1;
1455  plist[0] = 0;
1456  llist = 0;
1457  if (ielmnt == 0) goto L900;
1458  kcmnd = 0;
1459  for (ielmnt = 1; ielmnt <= nelmnt; ++ielmnt) {
1460  if ( celmnt[ielmnt-1] == cnull) goto L450;
1461  for (ic = 1; ic <= 13; ++ic) {
1462  if (*celmnt[ielmnt-1] == cnumer[ic-1]) goto L450;
1463  }
1464  if (kcmnd >= maxcwd) continue;
1465  left = maxcwd - kcmnd;
1466  ltoadd = lelmnt[ielmnt-1];
1467  if (ltoadd > left) ltoadd = left;
1468  strncpy(&command[kcmnd],celmnt[ielmnt-1],ltoadd);
1469  kcmnd += ltoadd;
1470  if (kcmnd == maxcwd) continue;
1471  command[kcmnd] = ' ';
1472  ++kcmnd;
1473  command[kcmnd] = 0;
1474  }
1475  lnc = kcmnd;
1476  goto L900;
1477 L450:
1478  lnc = kcmnd;
1479 //*-*- . . . . we have come to a numeric field
1480  llist = 0;
1481  for (ifld = ielmnt; ifld <= nelmnt; ++ifld) {
1482  ++llist;
1483  if (llist > mxp) {
1484  nreq = nelmnt - ielmnt + 1;
1485  //std::printf(" MINUIT WARNING IN MNCRCK: \n");
1486  *m_logStream << " MINUIT WARNING IN MNCRCK: \n";
1487  //std::printf(" COMMAND HAS INPUT%5d NUMERIC FIELDS, BUT MINUIT CAN ACCEPT ONLY%3d\n",nreq,mxp);
1488  *m_logStream << " COMMAND HAS INPUT" << setw(5) << nreq << " NUMERIC FIELDS, BUT MINUIT CAN ACCEPT ONLY"
1489  << setw(3) << mxp << endl;
1490  goto L900;
1491  }
1492  if (celmnt[ifld-1] == cnull) plist[llist-1] = 0;
1493  else {
1494  sscanf(celmnt[ifld-1],"%lf",&plist[llist-1]);
1495  }
1496  }
1497 //*-*- end loop over numeric fields
1498 L900:
1499  if (lnc <= 0) lnc = 1;
1500  comand = command;
1501 } /* mncrck_ */
1502 
1503 //______________________________________________________________________________
1505 {
1506 //*-*-*-*-*-*-*-*-*-*-*Find point where MNEVAL=AMIN+UP*-*-*-*-*-*-*-*-*-*-*-*
1507 //*-* ===============================
1508 //*-* Find point where MNEVAL=AMIN+UP, along the line through
1509 //*-* XMIDCR,YMIDCR with direction XDIRCR,YDIRCR, where X and Y
1510 //*-* are parameters KE1CR and KE2CR. If KE2CR=0 (from MINOS),
1511 //*-* only KE1CR is varied. From MNCONT, both are varied.
1512 //*-* Crossing point is at
1513 //*-* (U(KE1),U(KE2)) = (XMID,YMID) + AOPT*(XDIR,YDIR)
1514 //*-*
1515 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1516 
1517  /* Local variables */
1518  Double_urt alsb[3], flsb[3], bmin, bmax, zmid, sdev, zdir, zlim;
1519  Double_urt coeff[3], aleft, aulim, fdist, adist, aminsv;
1520  Double_urt anext, fnext, slope, s1, s2, x1, x2, ecarmn, ecarmx;
1521  Double_urt determ, rt, smalla, aright, aim, tla, tlf, dfda,ecart;
1522  Int_urt iout=0, i, ileft, ierev, maxlk, ibest, ik, it;
1523  Int_urt noless, iworst=0, iright, itoohi, kex, ipt;
1524  Bool_urt ldebug;
1525  const char *chsign;
1526  x2 = 0;
1527 
1528  ldebug = fIdbg[6] >= 1;
1529  aminsv = fAmin;
1530 //*-*- convergence when F is within TLF of AIM and next prediction
1531 //*-*- of AOPT is within TLA of previous value of AOPT
1532  aim = fAmin + fUp;
1533  tlf = fUp*.01;
1534  tla = .01;
1535  fXpt[0] = 0;
1536  fYpt[0] = aim;
1537  fChpt[0] = ' ';
1538  ipt = 1;
1539  if (fKe2cr == 0) {
1540  fXpt[1] = -1;
1541  fYpt[1] = fAmin;
1542  fChpt[1] = '.';
1543  ipt = 2;
1544  }
1545 //*-*- find the largest allowed A
1546  aulim = 100;
1547  for (ik = 1; ik <= 2; ++ik) {
1548  if (ik == 1) {
1549  kex = fKe1cr;
1550  zmid = fXmidcr;
1551  zdir = fXdircr;
1552  } else {
1553  if (fKe2cr == 0) continue;
1554  kex = fKe2cr;
1555  zmid = fYmidcr;
1556  zdir = fYdircr;
1557  }
1558 // if (fNvarl[kex-1] <= 1) continue;
1559  if (m_userParameterFlag[kex] <= 1) continue;
1560  if (zdir == 0) continue;
1561  zlim = fAlim[kex-1];
1562  if (zdir > 0) zlim = fBlim[kex-1];
1563  aulim = URMath::Min(aulim,(zlim - zmid) / zdir);
1564  }
1565 //*-*- LSB = Line Search Buffer
1566 //*-*- first point
1567  anext = 0;
1568  aopt = anext;
1569  fLimset = kurFALSE;
1570  if (aulim < aopt + tla) fLimset = kurTRUE;
1571  mneval(anext, fnext, ierev);
1572 //*-* debug printout:
1573  if (ldebug) {
1574  std::printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f\n",fNfcn,aim,fnext,aopt);
1575  }
1576  if (ierev > 0) goto L900;
1577  if (fLimset && fnext <= aim) goto L930;
1578  ++ipt;
1579  fXpt[ipt-1] = anext;
1580  fYpt[ipt-1] = fnext;
1581  fChpt[ipt-1] = charal[ipt-1];
1582  alsb[0] = anext;
1583  flsb[0] = fnext;
1584  fnext = URMath::Max(fnext,aminsv + fUp*.1);
1585  aopt = URMath::Sqrt(fUp / (fnext - aminsv)) - 1;
1586  if (URMath::Abs(fnext - aim) < tlf) goto L800;
1587 
1588  if (aopt < -.5)aopt = -.5;
1589  if (aopt > 1) aopt = 1;
1590  fLimset = kurFALSE;
1591  if (aopt > aulim) {
1592  aopt = aulim;
1593  fLimset = kurTRUE;
1594  }
1595  mneval(aopt, fnext, ierev);
1596 //*-* debug printout:
1597  if (ldebug) {
1598  std::printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f\n",fNfcn,aim,fnext,aopt);
1599  }
1600  if (ierev > 0) goto L900;
1601  if (fLimset && fnext <= aim) goto L930;
1602  alsb[1] = aopt;
1603  ++ipt;
1604  fXpt[ipt-1] = alsb[1];
1605  fYpt[ipt-1] = fnext;
1606  fChpt[ipt-1] = charal[ipt-1];
1607  flsb[1] = fnext;
1608  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1609 //*-*- DFDA must be positive on the contour
1610  if (dfda > 0) goto L460;
1611 L300:
1612  mnwarn("D", "MNCROS ", "Looking for slope of the right sign");
1613  maxlk = 15 - ipt;
1614  for (it = 1; it <= maxlk; ++it) {
1615  alsb[0] = alsb[1];
1616  flsb[0] = flsb[1];
1617  aopt = alsb[0] + Double_urt(it)*.2;
1618  fLimset = kurFALSE;
1619  if (aopt > aulim) {
1620  aopt = aulim;
1621  fLimset = kurTRUE;
1622  }
1623  mneval(aopt, fnext, ierev);
1624 //*-* debug printout:
1625  if (ldebug) {
1626  std::printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f\n",fNfcn,aim,fnext,aopt);
1627  }
1628  if (ierev > 0) goto L900;
1629  if (fLimset && fnext <= aim) goto L930;
1630  alsb[1] = aopt;
1631  ++ipt;
1632  fXpt[ipt-1] = alsb[1];
1633  fYpt[ipt-1] = fnext;
1634  fChpt[ipt-1] = charal[ipt-1];
1635  flsb[1] = fnext;
1636  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1637  if (dfda > 0) goto L450;
1638  }
1639  mnwarn("W", "MNCROS ", "Cannot find slope of the right sign");
1640  goto L950;
1641 L450:
1642 //*-*- we have two points with the right slope
1643 L460:
1644  aopt = alsb[1] + (aim - flsb[1]) / dfda;
1645  fdist = URMath::Min(URMath::Abs(aim - flsb[0]),URMath::Abs(aim - flsb[1]));
1646  adist = URMath::Min(URMath::Abs(aopt - alsb[0]),URMath::Abs(aopt - alsb[1]));
1647  tla = .01;
1648  if (URMath::Abs(aopt) > 1) tla = URMath::Abs(aopt)*.01;
1649  if (adist < tla && fdist < tlf) goto L800;
1650  if (ipt >= 15) goto L950;
1651  bmin = URMath::Min(alsb[0],alsb[1]) - 1;
1652  if (aopt < bmin) aopt = bmin;
1653  bmax = URMath::Max(alsb[0],alsb[1]) + 1;
1654  if (aopt > bmax) aopt = bmax;
1655 //*-*- Try a third point
1656  fLimset = kurFALSE;
1657  if (aopt > aulim) {
1658  aopt = aulim;
1659  fLimset = kurTRUE;
1660  }
1661  mneval(aopt, fnext, ierev);
1662 //*-* debug printout:
1663  if (ldebug) {
1664  std::printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f\n",fNfcn,aim,fnext,aopt);
1665  }
1666  if (ierev > 0) goto L900;
1667  if (fLimset && fnext <= aim) goto L930;
1668  alsb[2] = aopt;
1669  ++ipt;
1670  fXpt[ipt-1] = alsb[2];
1671  fYpt[ipt-1] = fnext;
1672  fChpt[ipt-1] = charal[ipt-1];
1673  flsb[2] = fnext;
1674 //*-*- now we have three points, ask how many <AIM
1675  ecarmn = URMath::Abs(fnext-aim);
1676  ibest = 3;
1677  ecarmx = 0;
1678  noless = 0;
1679  for (i = 1; i <= 3; ++i) {
1680  ecart = URMath::Abs(flsb[i-1] - aim);
1681  if (ecart > ecarmx) { ecarmx = ecart; iworst = i; }
1682  if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
1683  if (flsb[i-1] < aim) ++noless;
1684  }
1685 //*-*- if at least one on each side of AIM, fit a parabola
1686  if (noless == 1 || noless == 2) goto L500;
1687 //*-*- if all three are above AIM, third must be closest to AIM
1688  if (noless == 0 && ibest != 3) goto L950;
1689 //*-*- if all three below, and third is not best, then slope
1690 //*-*- has again gone negative, look for positive slope.
1691  if (noless == 3 && ibest != 3) {
1692  alsb[1] = alsb[2];
1693  flsb[1] = flsb[2];
1694  goto L300;
1695  }
1696 //*-*- in other cases, new straight line thru last two points
1697  alsb[iworst-1] = alsb[2];
1698  flsb[iworst-1] = flsb[2];
1699  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1700  goto L460;
1701 //*-*- parabola fit
1702 L500:
1703  mnpfit(alsb, flsb, 3, coeff, sdev);
1704  if (coeff[2] <= 0) {
1705  mnwarn("D", "MNCROS ", "Curvature is negative near contour line.");
1706  }
1707  determ = coeff[1]*coeff[1] - coeff[2]*4*(coeff[0] - aim);
1708  if (determ <= 0) {
1709  mnwarn("D", "MNCROS ", "Problem 2, impossible determinant");
1710  goto L950;
1711  }
1712 //*-*- Find which root is the right one
1713  rt = URMath::Sqrt(determ);
1714  x1 = (-coeff[1] + rt) / (coeff[2]*2);
1715  x2 = (-coeff[1] - rt) / (coeff[2]*2);
1716  s1 = coeff[1] + x1*2*coeff[2];
1717  s2 = coeff[1] + x2*2*coeff[2];
1718  if (s1*s2 > 0) {
1719  //std::printf(" MNCONTour problem 1\n");
1720  *m_logStream << " MNCONTour problem 1" << endl;
1721  }
1722  aopt = x1;
1723  slope = s1;
1724  if (s2 > 0) {
1725  aopt = x2;
1726  slope = s2;
1727  }
1728 //*-*- ask if converged
1729  tla = .01;
1730  if (URMath::Abs(aopt) > 1) tla = URMath::Abs(aopt)*.01;
1731  if (URMath::Abs(aopt - alsb[ibest-1]) < tla && URMath::Abs(flsb[ibest-1] - aim) < tlf) {
1732  goto L800;
1733  }
1734  if (ipt >= 15) goto L950;
1735 
1736 //*-*- see if proposed point is in acceptable zone between L and R
1737 //*-*- first find ILEFT, IRIGHT, IOUT and IBEST
1738  ileft = 0;
1739  iright = 0;
1740  ibest = 1;
1741  ecarmx = 0;
1742  ecarmn = URMath::Abs(aim - flsb[0]);
1743  for (i = 1; i <= 3; ++i) {
1744  ecart = URMath::Abs(flsb[i-1] - aim);
1745  if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
1746  if (ecart > ecarmx) { ecarmx = ecart; }
1747  if (flsb[i-1] > aim) {
1748  if (iright == 0) iright = i;
1749  else if (flsb[i-1] > flsb[iright-1]) iout = i;
1750  else { iout = iright; iright = i; }
1751  }
1752  else if (ileft == 0) ileft = i;
1753  else if (flsb[i-1] < flsb[ileft-1]) iout = i;
1754  else { iout = ileft; ileft = i; }
1755  }
1756 //*-*- avoid keeping a very bad point next time around
1757  if (ecarmx > URMath::Abs(flsb[iout-1] - aim)*10) {
1758  aopt = aopt*.5 + (alsb[iright-1] + alsb[ileft-1])*.25;
1759  }
1760 //*-*- knowing ILEFT and IRIGHT, get acceptable window
1761  smalla = tla*.1;
1762  if (slope*smalla > tlf) smalla = tlf / slope;
1763  aleft = alsb[ileft-1] + smalla;
1764  aright = alsb[iright-1] - smalla;
1765 //*-*- move proposed point AOPT into window if necessary
1766  if (aopt < aleft) aopt = aleft;
1767  if (aopt > aright) aopt = aright;
1768  if (aleft > aright) aopt = (aleft + aright)*.5;
1769 
1770 //*-*- see if proposed point outside limits (should be impossible!)
1771  fLimset = kurFALSE;
1772  if (aopt > aulim) {
1773  aopt = aulim;
1774  fLimset = kurTRUE;
1775  }
1776 //*-*- Evaluate function at new point AOPT
1777  mneval(aopt, fnext, ierev);
1778 //*-* debug printout:
1779  if (ldebug) {
1780  std::printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f\n",fNfcn,aim,fnext,aopt);
1781  }
1782  if (ierev > 0) goto L900;
1783  if (fLimset && fnext <= aim) goto L930;
1784  ++ipt;
1785  fXpt[ipt-1] = aopt;
1786  fYpt[ipt-1] = fnext;
1787  fChpt[ipt-1] = charal[ipt-1];
1788 //*-*- Replace odd point by new one
1789  alsb[iout-1] = aopt;
1790  flsb[iout-1] = fnext;
1791 //*-*- the new point may not be the best, but it is the only one
1792 //*-*- which could be good enough to pass convergence criteria
1793  ibest = iout;
1794  goto L500;
1795 
1796 //*-*- Contour has been located, return point to MNCONT OR MINOS
1797 L800:
1798  iercr = 0;
1799  goto L1000;
1800 //*-*- error in the minimization
1801 L900:
1802  if (ierev == 1) goto L940;
1803  goto L950;
1804 //*-*- parameter up against limit
1805 L930:
1806  iercr = 1;
1807  goto L1000;
1808 //*-*- too many calls to FCN
1809 L940:
1810  iercr = 2;
1811  goto L1000;
1812 //*-*- cannot find next point
1813 L950:
1814  iercr = 3;
1815 //*-*- in any case
1816 L1000:
1817  if (ldebug) {
1818  itoohi = 0;
1819  for (i = 1; i <= ipt; ++i) {
1820  if (fYpt[i-1] > aim + fUp) {
1821  fYpt[i-1] = aim + fUp;
1822  fChpt[i-1] = '+';
1823  itoohi = 1;
1824  }
1825  }
1826  fChpt[ipt] = 0;
1827  chsign = "POSI";
1828  if (fXdircr < 0) chsign = "NEGA";
1829  if (fKe2cr == 0) {
1830  //std::printf(" %sTIVE MINOS ERROR, PARAMETER %3d\n",chsign,fKe1cr);
1831  *m_logStream << chsign << "TIVE MINOS ERROR, PARAMETER " << setw(3) << fKe1cr << endl;
1832  }
1833  if (itoohi == 1) {
1834  //std::printf("POINTS LABELLED '+' WERE TOO HIGH TO PLOT.\n");
1835  *m_logStream << "POINTS LABELLED '+' WERE TOO HIGH TO PLOT." << endl;
1836  }
1837  if (iercr == 1) {
1838  //std::printf("RIGHTMOST POINT IS UP AGAINST LIMIT.\n");
1839  *m_logStream << "RIGHTMOST POINT IS UP AGAINST LIMIT." << endl;
1840  }
1841  mnplot(fXpt, fYpt, fChpt, ipt, fNpagwd, fNpagln);
1842  }
1843 } /* mncros_ */
1844 
1845 //______________________________________________________________________________
1847 {
1848 //*-*-*-*-*-*-*-*Makes sure that the current point is a local minimum*-*-*-*-*
1849 //*-* ====================================================
1850 //*-* Makes sure that the current point is a local
1851 //*-* minimum and that the error matrix exists,
1852 //*-* or at least something good enough for MINOS and MNCONT
1853 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1854 
1855  /* Local variables */
1856  Double_urt dxdi, wint;
1857  Int_urt ndex, iext, i, j;
1858 
1859  if (fISW[3] < 1) {
1860  //std::printf(" FUNCTION MUST BE MINIMIZED BEFORE CALLING %s\n",fCfrom.c_str());
1861  *m_logStream << " FUNCTION MUST BE MINIMIZED BEFORE CALLING " << fCfrom << endl;
1862  fApsi = fEpsi;
1863  mnmigr();
1864  }
1865  if (fISW[1] < 3) {
1866  mnhess();
1867  if (fISW[1] < 1) {
1868  mnwarn("W", fCfrom.c_str(), "NO ERROR MATRIX. WILL IMPROVISE.\n");
1869  for (i = 1; i <= fNpar; ++i) {
1870  ndex = i*(i-1) / 2;
1871  for (j = 1; j <= i-1; ++j) {
1872  ++ndex;
1873  fVhmat[ndex-1] = 0;
1874  }
1875  ++ndex;
1876  if (fG2[i-1] <= 0) {
1877  wint = fWerr[i-1];
1878  iext = fNexofi[i-1];
1879 // if (fNvarl[iext-1] > 1) {
1880  if (m_userParameterFlag[iext] > 1) {
1881  mndxdi(fX[i-1], i-1, dxdi);
1882  if (URMath::Abs(dxdi) < .001) wint = .01;
1883  else wint /= URMath::Abs(dxdi);
1884  }
1885  fG2[i-1] = fUp / (wint*wint);
1886  }
1887  fVhmat[ndex-1] = 2 / fG2[i-1];
1888  }
1889  fISW[1] = 1;
1890  fDcovar = 1;
1891  } else mnwerr();
1892  }
1893 } /* mncuve_ */
1894 
1895 //______________________________________________________________________________
1897 {
1898 //*-*-*-*-*-*-*-*Calculates the first derivatives of FCN (GRD)*-*-*-*-*-*-*-*
1899 //*-* =============================================
1900 //*-* Calculates the first derivatives of FCN (GRD),
1901 //*-* either by finite differences or by transforming the user-
1902 //*-* supplied derivatives to internal coordinates,
1903 //*-* according to whether ISW(3) is zero or one.
1904 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1905 
1906  /* Local variables */
1907  Double_urt step, dfmin, stepb4, dd, df, fs1;
1908  Double_urt tlrstp, tlrgrd, epspri, optstp, stpmax, stpmin, fs2, grbfor=0, d1d2, xtf;
1909  Int_urt icyc, ncyc, iint, iext, i, nparx;
1910  Bool_urt ldebug;
1911 
1912  nparx = fNpar;
1913  ldebug = fIdbg[2] >= 1;
1914  if (fAmin == fUndefi) mnamin();
1915  if (fISW[2] == 1) goto L100;
1916 
1917  if (ldebug) {
1918 //*-*- make sure starting at the right place
1919  mninex(fX);
1920  nparx = fNpar;
1921 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
1922  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
1923  if (fs1 != fAmin) {
1924  df = fAmin - fs1;
1925  ostringstream warning;
1926  warning << "function value differs from AMIN by " << df;
1927  mnwarn("D", "MNDERI", warning.str().c_str());
1928  fAmin = fs1;
1929  }
1930  //std::printf(" FIRST DERIVATIVE DEBUG PRINTOUT. MNDERI\n");
1931  //std::printf(" PAR DERIV STEP MINSTEP OPTSTEP D1-D2 2ND DRV\n");
1932  *m_logStream << " FIRST DERIVATIVE DEBUG PRINTOUT. MNDERI\n";
1933  *m_logStream << " PAR DERIV STEP MINSTEP OPTSTEP D1-D2 2ND DRV" << endl;
1934  }
1935  dfmin = fEpsma2*8*(URMath::Abs(fAmin) + fUp);
1936  if (fIstrat <= 0) {
1937  ncyc = 2;
1938  tlrstp = .5;
1939  tlrgrd = .1;
1940  } else if (fIstrat == 1) {
1941  ncyc = 3;
1942  tlrstp = .3;
1943  tlrgrd = .05;
1944  } else {
1945  ncyc = 5;
1946  tlrstp = .1;
1947  tlrgrd = .02;
1948  }
1949 //*-*- loop over variable parameters
1950  for (i = 1; i <= fNpar; ++i) {
1951  epspri = fEpsma2 + URMath::Abs(fGrd[i-1]*fEpsma2);
1952 //*-*- two-point derivatives always assumed necessary
1953 //*-*- maximum number of cycles over step size depends on strategy
1954  xtf = fX[i-1];
1955  stepb4 = 0;
1956 //*-*- loop as little as possible here!/
1957  for (icyc = 1; icyc <= ncyc; ++icyc) {
1958 //*-*- ........ theoretically best step
1959  optstp = URMath::Sqrt(dfmin / (URMath::Abs(fG2[i-1]) + epspri));
1960 //*-*- step cannot decrease by more than a factor of ten
1961  step = URMath::Max(optstp,URMath::Abs(fGstep[i-1]*.1));
1962 //*-*- but if parameter has limits, max step size = 0.5
1963  if (fGstep[i-1] < 0 && step > .5) step = .5;
1964 //*-*- and not more than ten times the previous step
1965  stpmax = URMath::Abs(fGstep[i-1])*10;
1966  if (step > stpmax) step = stpmax;
1967 //*-*- minimum step size allowed by machine precision
1968  stpmin = URMath::Abs(fEpsma2*fX[i-1])*8;
1969  if (step < stpmin) step = stpmin;
1970 //*-*- end of iterations if step change less than factor 2
1971  if (URMath::Abs((step - stepb4) / step) < tlrstp) goto L50;
1972 //*-*- take step positive
1973  stepb4 = step;
1974  if (fGstep[i-1] > 0) fGstep[i-1] = URMath::Abs(step);
1975  else fGstep[i-1] = -URMath::Abs(step);
1976  stepb4 = step;
1977  fX[i-1] = xtf + step;
1978  mninex(fX);
1979 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
1980  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
1981 //*-*- take step negative
1982  fX[i-1] = xtf - step;
1983  mninex(fX);
1984 // Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
1985  Eval(nparx, fGin, fs2, m_userParameterValue, 4); ++fNfcn;
1986  grbfor = fGrd[i-1];
1987  fGrd[i-1] = (fs1 - fs2) / (step*2);
1988  fG2[i-1] = (fs1 + fs2 - fAmin*2) / (step*step);
1989  fX[i-1] = xtf;
1990  if (ldebug) {
1991  d1d2 = (fs1 + fs2 - fAmin*2) / step;
1992  std::printf("%4d%11.3g%11.3g%10.2g%10.2g%10.2g%10.2g\n",i,fGrd[i-1],step,stpmin,optstp,d1d2,fG2[i-1]);
1993  }
1994 //*-*- see if another iteration is necessary
1995  if (URMath::Abs(grbfor - fGrd[i-1]) / (URMath::Abs(fGrd[i-1]) + dfmin/step) < tlrgrd)
1996  goto L50;
1997  }
1998 //*-*- end of ICYC loop. too many iterations
1999  if (ncyc == 1) goto L50;
2000  { ostringstream warning2;
2001  warning2 << "First derivative not converged. " << fGrd[i-1] << grbfor;
2002  mnwarn("D", "MNDERI", warning2.str().c_str()); }
2003 L50:
2004  ;
2005  }
2006  mninex(fX);
2007  return;
2008 //*-*- . derivatives calc by fcn
2009 L100:
2010  for (iint = 1; iint <= fNpar; ++iint) {
2011  iext = fNexofi[iint-1];
2012 // if (fNvarl[iext-1] <= 1) {
2013  if (m_userParameterFlag[iext] <= 1) {
2014  fGrd[iint-1] = fGin[iext-1];
2015  } else {
2016  dd = (fBlim[iext-1] - fAlim[iext-1])*.5*URMath::Cos(fX[iint-1]);
2017  fGrd[iint-1] = fGin[iext-1]*dd;
2018  }
2019  }
2020 } /* mnderi_ */
2021 
2022 //______________________________________________________________________________
2024 {
2025 //*-*-*-*Calculates the transformation factor between ext/internal values*-*
2026 //*-* =====================================================================
2027 //*-* calculates the transformation factor between external and
2028 //*-* internal parameter values. this factor is one for
2029 //*-* parameters which are not limited. called from MNEMAT.
2030 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2031 
2032  Int_urt i = fNexofi[ipar];
2033  dxdi = 1;
2034 // if (fNvarl[i-1] > 1) {
2035  if (m_userParameterFlag[i] > 1) {
2036  dxdi = URMath::Abs((fBlim[i-1] - fAlim[i-1])*URMath::Cos(pint))*.5;
2037  }
2038 } /* mndxdi_ */
2039 
2040 //______________________________________________________________________________
2041 void URMinuit::mneig(Double_urt *a, Int_urt ndima, Int_urt n, Int_urt mits, Double_urt *work, Double_urt precis, Int_urt &ifault)
2042 {
2043 //*-*-*-*-*-*-*-*-*-*-*-*Compute matrix eigen values*-*-*-*-*-*-*-*-*-*-*-*-*
2044 //*-* ===========================
2045  /* System generated locals */
2046  Int_urt a_offset;
2047  Double_urt d__1;
2048 
2049  /* Local variables */
2050  Double_urt b, c, f, h, r, s, hh, gl, pr, pt;
2051  Int_urt i, j, k, l, m=0, i0, i1, j1, m1, n1;
2052 
2053 //*-*- PRECIS is the machine precision EPSMAC
2054  /* Parameter adjustments */
2055  a_offset = ndima + 1;
2056  a -= a_offset;
2057  --work;
2058 
2059  /* Function Body */
2060  ifault = 1;
2061 
2062  i = n;
2063  for (i1 = 2; i1 <= n; ++i1) {
2064  l = i-2;
2065  f = a[i + (i-1)*ndima];
2066  gl = 0;
2067 
2068  if (l < 1) goto L25;
2069 
2070  for (k = 1; k <= l; ++k) {
2071  d__1 = a[i + k*ndima];
2072  gl += d__1*d__1;
2073  }
2074 L25:
2075  h = gl + f*f;
2076 
2077  if (gl > 1e-35) goto L30;
2078 
2079  work[i] = 0;
2080  work[n + i] = f;
2081  goto L65;
2082 L30:
2083  ++l;
2084  gl = URMath::Sqrt(h);
2085  if (f >= 0) gl = -gl;
2086  work[n + i] = gl;
2087  h -= f*gl;
2088  a[i + (i-1)*ndima] = f - gl;
2089  f = 0;
2090  for (j = 1; j <= l; ++j) {
2091  a[j + i*ndima] = a[i + j*ndima] / h;
2092  gl = 0;
2093  for (k = 1; k <= j; ++k) { gl += a[j + k*ndima]*a[i + k*ndima]; }
2094  if (j >= l) goto L47;
2095  j1 = j + 1;
2096  for (k = j1; k <= l; ++k) { gl += a[k + j*ndima]*a[i + k*ndima]; }
2097 L47:
2098  work[n + j] = gl / h;
2099  f += gl*a[j + i*ndima];
2100  }
2101  hh = f / (h + h);
2102  for (j = 1; j <= l; ++j) {
2103  f = a[i + j*ndima];
2104  gl = work[n + j] - hh*f;
2105  work[n + j] = gl;
2106  for (k = 1; k <= j; ++k) {
2107  a[j + k*ndima] = a[j + k*ndima] - f*work[n + k] - gl*a[i + k*ndima];
2108  }
2109  }
2110  work[i] = h;
2111 L65:
2112  --i;
2113  }
2114  work[1] = 0;
2115  work[n + 1] = 0;
2116  for (i = 1; i <= n; ++i) {
2117  l = i-1;
2118  if (work[i] == 0 || l == 0) goto L100;
2119 
2120  for (j = 1; j <= l; ++j) {
2121  gl = 0;
2122  for (k = 1; k <= l; ++k) { gl += a[i + k*ndima]*a[k + j*ndima]; }
2123  for (k = 1; k <= l; ++k) { a[k + j*ndima] -= gl*a[k + i*ndima]; }
2124  }
2125 L100:
2126  work[i] = a[i + i*ndima];
2127  a[i + i*ndima] = 1;
2128  if (l == 0) continue;
2129 
2130  for (j = 1; j <= l; ++j) {
2131  a[i + j*ndima] = 0;
2132  a[j + i*ndima] = 0;
2133  }
2134  }
2135 
2136  n1 = n - 1;
2137  for (i = 2; i <= n; ++i) {
2138  i0 = n + i-1;
2139  work[i0] = work[i0 + 1];
2140  }
2141  work[n + n] = 0;
2142  b = 0;
2143  f = 0;
2144  for (l = 1; l <= n; ++l) {
2145  j = 0;
2146  h = precis*(URMath::Abs(work[l]) + URMath::Abs(work[n + l]));
2147  if (b < h) b = h;
2148  for (m1 = l; m1 <= n; ++m1) {
2149  m = m1;
2150  if (URMath::Abs(work[n + m]) <= b) goto L150;
2151  }
2152 
2153 L150:
2154  if (m == l) goto L205;
2155 
2156 L160:
2157  if (j == mits) return;
2158  ++j;
2159  pt = (work[l + 1] - work[l]) / (work[n + l]*2);
2160  r = URMath::Sqrt(pt*pt + 1);
2161  pr = pt + r;
2162  if (pt < 0) pr = pt - r;
2163 
2164  h = work[l] - work[n + l] / pr;
2165  for (i = l; i <= n; ++i) { work[i] -= h; }
2166  f += h;
2167  pt = work[m];
2168  c = 1;
2169  s = 0;
2170  m1 = m - 1;
2171  i = m;
2172  for (i1 = l; i1 <= m1; ++i1) {
2173  j = i;
2174  --i;
2175  gl = c*work[n + i];
2176  h = c*pt;
2177  if (URMath::Abs(pt) >= URMath::Abs(work[n + i])) goto L180;
2178 
2179  c = pt / work[n + i];
2180  r = URMath::Sqrt(c*c + 1);
2181  work[n + j] = s*work[n + i]*r;
2182  s = 1 / r;
2183  c /= r;
2184  goto L190;
2185 L180:
2186  c = work[n + i] / pt;
2187  r = URMath::Sqrt(c*c + 1);
2188  work[n + j] = s*pt*r;
2189  s = c / r;
2190  c = 1 / r;
2191 L190:
2192  pt = c*work[i] - s*gl;
2193  work[j] = h + s*(c*gl + s*work[i]);
2194  for (k = 1; k <= n; ++k) {
2195  h = a[k + j*ndima];
2196  a[k + j*ndima] = s*a[k + i*ndima] + c*h;
2197  a[k + i*ndima] = c*a[k + i*ndima] - s*h;
2198  }
2199  }
2200  work[n + l] = s*pt;
2201  work[l] = c*pt;
2202 
2203  if (URMath::Abs(work[n + l]) > b) goto L160;
2204 
2205 L205:
2206  work[l] += f;
2207  }
2208  for (i = 1; i <= n1; ++i) {
2209  k = i;
2210  pt = work[i];
2211  i1 = i + 1;
2212  for (j = i1; j <= n; ++j) {
2213  if (work[j] >= pt) continue;
2214  k = j;
2215  pt = work[j];
2216  }
2217 
2218  if (k == i) continue;
2219 
2220  work[k] = work[i];
2221  work[i] = pt;
2222  for (j = 1; j <= n; ++j) {
2223  pt = a[j + i*ndima];
2224  a[j + i*ndima] = a[j + k*ndima];
2225  a[j + k*ndima] = pt;
2226  }
2227  }
2228  ifault = 0;
2229 } /* mneig_ */
2230 
2231 //______________________________________________________________________________
2233 {
2234 // Calculates the external error matrix from the internal matrix
2235 //
2236 // Note that if the matrix is declared like Double_urt matrix[5][5]
2237 // in the calling program, one has to call mnemat with, eg
2238 // gMinuit->mnemat(&matrix[0][0],5);
2239 
2240  /* System generated locals */
2241  Int_urt emat_dim1, emat_offset;
2242 
2243  /* Local variables */
2244  Double_urt dxdi, dxdj;
2245  Int_urt i, j, k, npard, k2, kk, iz, nperln, kga, kgb;
2246  string ctemp;
2247 
2248  /* Parameter adjustments */
2249  emat_dim1 = ndim;
2250  emat_offset = emat_dim1 + 1;
2251  emat -= emat_offset;
2252 
2253  /* Function Body */
2254  if (fISW[1] < 1) return;
2255  if (fISW[4] >= 2) {
2256  //std::printf(" EXTERNAL ERROR MATRIX. NDIM=%4d NPAR=%3d ERR DEF=%g\n",ndim,fNpar,fUp);
2257  *m_logStream << " EXTERNAL ERROR MATRIX. NDIM=" << setw(4) << ndim << " NPAR=" << setw(3)
2258  << fNpar << " ERR DEF=" << fUp << endl;
2259  }
2260 //*-*- size of matrix to be printed
2261  npard = fNpar;
2262  if (ndim < fNpar) {
2263  npard = ndim;
2264  if (fISW[4] >= 0) {
2265  std::printf(" USER-DIMENSIONED ARRAY EMAT NOT BIG ENOUGH. REDUCED MATRIX CALCULATED.\n");
2266  }
2267  }
2268 //*-*- NPERLN is the number of elements that fit on one line
2269 
2270  nperln = (fNpagwd - 5) / 10;
2271  nperln = URMath::Min(nperln,13);
2272  if (fISW[4] >= 1 && npard > nperln) {
2273  // disable annoying printout when obtaining error matrix for fits with
2274  // large numbers of parameters
2275  // std::printf(" ELEMENTS ABOVE DIAGONAL ARE NOT PRINTED.\n");
2276  }
2277 //*-*- I counts the rows of the matrix
2278  for (i = 1; i <= npard; ++i) {
2279  mndxdi(fX[i-1], i-1, dxdi);
2280  kga = i*(i-1) / 2;
2281  for (j = 1; j <= i; ++j) {
2282  mndxdi(fX[j-1], j-1, dxdj);
2283  kgb = kga + j;
2284  emat[i + j*emat_dim1] = dxdi*fVhmat[kgb-1]*dxdj*fUp;
2285  emat[j + i*emat_dim1] = emat[i + j*emat_dim1];
2286  }
2287  }
2288 //*-*- IZ is number of columns to be printed in row I
2289  if (fISW[4] >= 2) {
2290  for (i = 1; i <= npard; ++i) {
2291  iz = npard;
2292  if (npard >= nperln) iz = i;
2293  for (k = 1; nperln < 0 ? k >= iz : k <= iz; k += nperln) {
2294  k2 = k + nperln - 1;
2295  if (k2 > iz) k2 = iz;
2296  ctemp = " ";
2297  for (kk = k; kk <= k2; ++kk) {
2298  ostringstream localTemp;
2299  localTemp << " " << setw(10) << setprecision(3) << emat[i + kk*emat_dim1];
2300  ctemp += localTemp.str();
2301  }
2302  std::printf("%s\n",ctemp.c_str());
2303  }
2304  }
2305  }
2306 } /* mnemat_ */
2307 
2308 //______________________________________________________________________________
2309 void URMinuit::mnerrs(Int_urt number, Double_urt &eplus, Double_urt &eminus, Double_urt &eparab, Double_urt &gcc)
2310 {
2311 //*-*-*-*-*-*-*-*-*-*Utility routine to get MINOS errors*-*-*-*-*-*-*-*-*-*-*
2312 //*-* ===================================
2313 //*-* Called by user.
2314 //*-* NUMBER is the parameter number
2315 //*-* values returned by MNERRS:
2316 //*-* EPLUS, EMINUS are MINOS errors of parameter NUMBER,
2317 //*-* EPARAB is 'parabolic' error (from error matrix).
2318 //*-* (Errors not calculated are set = 0)
2319 //*-* GCC is global correlation coefficient from error matrix
2320 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2321 
2322  Double_urt dxdi;
2323  Int_urt ndiag, iin, iex;
2324 
2325 // iex = number+1;
2326  iex = number;
2327 
2328  if (iex > fNu || iex <= 0) goto L900;
2329 // iin = fNiofex[iex-1];
2330 // cout << "mnerr: request to get error for param = " << iex << endl;
2331  iin = m_userParameterIdToInternalId[iex];
2332 // cout << " found internal parameter iin " << iin << endl;
2333  if (iin <= 0) goto L900;
2334 
2335 //*-*- IEX is external number, IIN is internal number
2336  eplus = fErp[iin-1];
2337  if (eplus == fUndefi) eplus = 0;
2338  eminus = fErn[iin-1];
2339  if (eminus == fUndefi) eminus = 0;
2340  mndxdi(fX[iin-1], iin-1, dxdi);
2341  ndiag = iin*(iin + 1) / 2;
2342  eparab = URMath::Abs(dxdi*URMath::Sqrt(URMath::Abs(fUp*fVhmat[ndiag- 1])));
2343 //*-*- global correlation coefficient
2344  gcc = 0;
2345  if (fISW[1] < 2) return;
2346  gcc = fGlobcc[iin-1];
2347  return;
2348 //*-*- ERROR. parameter number not valid
2349 L900:
2350  eplus = 0;
2351  eminus = 0;
2352  eparab = 0;
2353  gcc = 0;
2354 } /* mnerrs_ */
2355 
2356 //______________________________________________________________________________
2357 void URMinuit::mneval(Double_urt anext, Double_urt &fnext, Int_urt &ierev)
2358 {
2359 //*-*-*-*-*-*-*Evaluates the function being analyzed by MNCROS*-*-*-*-*-*-*-*
2360 //*-* ===============================================
2361 //*-* Evaluates the function being analyzed by MNCROS, which is
2362 //*-* generally the minimum of FCN with respect to all remaining
2363 //*-* variable parameters. The class data members contains the
2364 //*-* data necessary to know the values of U(KE1CR) and U(KE2CR)
2365 //*-* to be used, namely U(KE1CR) = XMIDCR + ANEXT*XDIRCR
2366 //*-* and (if KE2CR .NE. 0) U(KE2CR) = YMIDCR + ANEXT*YDIRCR
2367 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2368 
2369  Int_urt nparx;
2370 
2371 // fU[fKe1cr-1] = fXmidcr + anext*fXdircr;
2372  m_userParameterValue[fKe1cr] = fXmidcr + anext*fXdircr;
2373 // if (fKe2cr != 0) fU[fKe2cr-1] = fYmidcr + anext*fYdircr;
2374  if (fKe2cr != 0) m_userParameterValue[fKe2cr] = fYmidcr + anext*fYdircr;
2375  mninex(fX);
2376  nparx = fNpar;
2377 // Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
2378  Eval(nparx, fGin, fnext, m_userParameterValue, 4); ++fNfcn;
2379  ierev = 0;
2380  if (fNpar > 0) {
2381  fItaur = 1;
2382  fAmin = fnext;
2383  fISW[0] = 0;
2384  mnmigr();
2385  fItaur = 0;
2386  fnext = fAmin;
2387  if (fISW[0] >= 1) ierev = 1;
2388  if (fISW[3] < 1) ierev = 2;
2389  }
2390 } /* mneval_ */
2391 
2392 //______________________________________________________________________________
2393 void URMinuit::mnexcm(const string& command, Double_urt *plist, Int_urt llist, Int_urt &ierflg)
2394 {
2395 //*-*-*-*-*-*Interprets a command and takes appropriate action*-*-*-*-*-*-*-*
2396 //*-* =================================================
2397 //*-* either directly by skipping to the corresponding code in
2398 //*-* MNEXCM, or by setting up a call to a function
2399 //*-*
2400 //*-* recognized MINUIT commands:
2401 //*-* obsolete commands:
2402 //*-* IERFLG is now (94.5) defined the same as ICONDN in MNCOMD
2403 //*-* = 0: command executed normally
2404 //*-* 1: command is blank, ignored
2405 //*-* 2: command line unreadable, ignored
2406 //*-* 3: unknown command, ignored
2407 //*-* 4: abnormal termination (e.g., MIGRAD not converged)
2408 //*-* 9: reserved
2409 //*-* 10: END command
2410 //*-* 11: EXIT or STOP command
2411 //*-* 12: RETURN command
2412 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2413 
2414  /* Initialized data */
2415 
2416  string comand = command;
2417  static string clower = "abcdefghijklmnopqrstuvwxyz";
2418  static string cupper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2419  const string cname[40] = {
2420  "MINImize ",
2421  "SEEk ",
2422  "SIMplex ",
2423  "MIGrad ",
2424  "MINOs ",
2425  "SET xxx ",
2426  "SHOw xxx ",
2427  "TOP of pag",
2428  "FIX ",
2429  "REStore ",
2430  "RELease ",
2431  "SCAn ",
2432  "CONtour ",
2433  "HESse ",
2434  "SAVe ",
2435  "IMProve ",
2436  "CALl fcn ",
2437  "STAndard ",
2438  "END ",
2439  "EXIt ",
2440  "RETurn ",
2441  "CLEar ",
2442  "HELP ",
2443  "MNContour ",
2444  "STOp ",
2445  "JUMp ",
2446  " ",
2447  " ",
2448  " ",
2449  " ",
2450  " ",
2451  " ",
2452  " ",
2453  "COVARIANCE",
2454  "PRINTOUT ",
2455  "GRADIENT ",
2456  "MATOUT ",
2457  "ERROR DEF ",
2458  "LIMITS ",
2459  "PUNCH "};
2460 
2461  Int_urt nntot = 40;
2462 
2463  /* Local variables */
2464  Double_urt step, xptu[101], yptu[101], f, rno;
2465  Int_urt icol, kcol, ierr, iint, iext, lnow, nptu, i, iflag, ierrf;
2466  Int_urt ilist, nparx, izero, nf, lk, it, iw, inonde, nsuper;
2467  Int_urt it2, ke1, ke2, nowprt, kll, krl;
2468  string chwhy, c26, cvblnk, cneway, comd;
2469  string ctemp;
2470  Bool_urt lfreed, ltofix, lfixed;
2471 
2472 //*-* alphabetical order of command names!
2473 
2474  /* Function Body */
2475 
2476  lk = comand.length();
2477  if (lk > 20) lk = 20;
2478  fCword = comand;
2479  int (*pf)(int)=toupper;
2480  transform(fCword.begin(), fCword.end(), fCword.begin(), pf);
2481 //*-*- Copy the first MAXP arguments into WORD7, making
2482 //*-*- sure that WORD7(1)=0 if LLIST=0
2483  for (iw = 1; iw <= fMaxpar; ++iw) {
2484  fWord7[iw-1] = 0;
2485  if (iw <= llist) fWord7[iw-1] = plist[iw-1];
2486  }
2487  ++fIcomnd;
2488  fNfcnlc = fNfcn;
2489  if (fCword.substr(0,7) != "SET PRI" || fWord7[0] >= 0) {
2490  if (fISW[4] >= 0) {
2491  lnow = llist;
2492  if (lnow > 4) lnow = 4;
2493  std::printf(" **********\n");
2494  ostringstream octemp;
2495  octemp << " **" << setw(5) << fIcomnd << " **" << fCword;
2496  ctemp = octemp.str();
2497 // ctemp = Form(" **%5d **%s",.c_str());
2498  for (i = 1; i <= lnow; ++i) {
2499  ostringstream localTemp;
2500  localTemp << " " << plist[i-1];
2501  ctemp += localTemp.str();
2502  }
2503  std::printf("%s\n",ctemp.c_str());
2504  inonde = 0;
2505  if (llist > lnow) {
2506  kll = llist;
2507  if (llist > fMaxpar) {
2508  inonde = 1;
2509  kll = fMaxpar;
2510  }
2511  std::printf(" ***********\n");
2512  for (i = lnow + 1; i <= kll; ++i) {
2513  std::printf("%12.4g\n",plist[i-1]);
2514  }
2515  }
2516  std::printf(" **********\n");
2517  if (inonde > 0) {
2518  std::printf(" ERROR: ABOVE CALL TO MNEXCM TRIED TO PASS MORE THAN %d PARAMETERS.\n", fMaxpar);
2519  }
2520  }
2521  }
2522  fNfcnmx = Int_urt(fWord7[0]);
2523  if (fNfcnmx <= 0) {
2524  fNfcnmx = fNpar*100 + 200 + fNpar*fNpar*5;
2525  }
2526  fEpsi = fWord7[1];
2527  if (fEpsi <= 0) {
2528  fEpsi = fUp*.1;
2529  }
2530  fLnewmn = kurFALSE;
2531  fLphead = kurTRUE;
2532  fISW[0] = 0;
2533  ierflg = 0;
2534 //*-*- look for command in list CNAME . . . . . . . . . .
2535  ctemp = fCword.substr(0,3);
2536  for (i = 1; i <= nntot; ++i) {
2537  if (strncmp(ctemp.c_str(),cname[i-1].c_str(),3) == 0) goto L90;
2538  }
2539  std::printf("UNKNOWN COMMAND IGNORED:%s\n", comand.c_str());
2540  ierflg = 3;
2541  return;
2542 //*-*- normal case: recognized MINUIT command . . . . . . .
2543 L90:
2544  if (fCword.substr(0,4) == "MINO") i = 5;
2545  if (i != 6 && i != 7 && i != 8 && i != 23) {
2546  fCfrom = cname[i-1];
2547  fNfcnfr = fNfcn;
2548  }
2549 //*-*- 1 2 3 4 5 6 7 8 9 10
2550  switch (i) {
2551  case 1: goto L400;
2552  case 2: goto L200;
2553  case 3: goto L300;
2554  case 4: goto L400;
2555  case 5: goto L500;
2556  case 6: goto L700;
2557  case 7: goto L700;
2558  case 8: goto L800;
2559  case 9: goto L900;
2560  case 10: goto L1000;
2561  case 11: goto L1100;
2562  case 12: goto L1200;
2563  case 13: goto L1300;
2564  case 14: goto L1400;
2565  case 15: goto L1500;
2566  case 16: goto L1600;
2567  case 17: goto L1700;
2568  case 18: goto L1800;
2569  case 19: goto L1900;
2570  case 20: goto L1900;
2571  case 21: goto L1900;
2572  case 22: goto L2200;
2573  case 23: goto L2300;
2574  case 24: goto L2400;
2575  case 25: goto L1900;
2576  case 26: goto L2600;
2577  case 27: goto L3300;
2578  case 28: goto L3300;
2579  case 29: goto L3300;
2580  case 30: goto L3300;
2581  case 31: goto L3300;
2582  case 32: goto L3300;
2583  case 33: goto L3300;
2584  case 34: goto L3400;
2585  case 35: goto L3500;
2586  case 36: goto L3600;
2587  case 37: goto L3700;
2588  case 38: goto L3800;
2589  case 39: goto L3900;
2590  case 40: goto L4000;
2591  }
2592 //*-*- . . . . . . . . . . seek
2593 L200:
2594  mnseek();
2595  return;
2596 //*-*- . . . . . . . . . . simplex
2597 L300:
2598  mnsimp();
2599  if (fISW[3] < 1) ierflg = 4;
2600  return;
2601 //*-*- . . . . . . migrad, minimize
2602 L400:
2603  nf = fNfcn;
2604  fApsi = fEpsi;
2605  mnmigr();
2606  mnwerr();
2607  if (fISW[3] >= 1) return;
2608  ierflg = 4;
2609  if (fISW[0] == 1) return;
2610  if (fCword.substr(0,3) == "MIG") return;
2611 
2612  fNfcnmx = fNfcnmx + nf - fNfcn;
2613  nf = fNfcn;
2614  mnsimp();
2615  if (fISW[0] == 1) return;
2616  fNfcnmx = fNfcnmx + nf - fNfcn;
2617  mnmigr();
2618  if (fISW[3] >= 1) ierflg = 0;
2619  mnwerr();
2620  return;
2621 //*-*- . . . . . . . . . . minos
2622 L500:
2623  nsuper = fNfcn + ( ( fNpar + 1 ) << 1)*fNfcnmx;
2624 //*-*- possible loop over new minima
2625  fEpsi = fUp*.1;
2626 L510:
2627  mncuve();
2628  mnmnos();
2629  if (! fLnewmn) return;
2630  mnrset(0);
2631  mnmigr();
2632  mnwerr();
2633  if (fNfcn < nsuper) goto L510;
2634  std::printf(" TOO MANY FUNCTION CALLS. MINOS GIVES UP\n");
2635  ierflg = 4;
2636  return;
2637 //*-*- . . . . . . . . . .set, show
2638 L700:
2639  mnset();
2640  return;
2641 //*-*- . . . . . . . . . . top of page
2642 
2643 L800:
2644  std::printf("1\n");
2645  return;
2646 //*-*- . . . . . . . . . . fix
2647 L900:
2648  ltofix = kurTRUE;
2649 //*-*- . . (also release) ....
2650 L901:
2651  lfreed = kurFALSE;
2652  lfixed = kurFALSE;
2653  if (llist == 0) {
2654  std::printf("%s: NO PARAMETERS REQUESTED \n",fCword.c_str());
2655  return;
2656  }
2657  for (ilist = 1; ilist <= llist; ++ilist) {
2658  iext = Int_urt(plist[ilist-1]);
2659  chwhy = " IS UNDEFINED.";
2660  if (iext <= 0) goto L930;
2661  if (iext > fNu) goto L930;
2662 // if (fNvarl[iext-1] < 0) goto L930;
2663  if (m_userParameterFlag[iext] < 0) goto L930;
2664  chwhy = " IS CONSTANT. ";
2665 // if (fNvarl[iext-1] == 0) goto L930;
2666  if (m_userParameterFlag[iext] == 0) goto L930;
2667 // iint = fNiofex[iext-1];
2668  iint = m_userParameterIdToInternalId[iext];
2669  if (ltofix) {
2670  chwhy = " ALREADY FIXED.";
2671  if (iint == 0) goto L930;
2672  mnfixp(iint-1, ierr);
2673  if (ierr == 0) lfixed = kurTRUE;
2674  else ierflg = 4;
2675  } else {
2676  chwhy = " ALREADY VARIABLE.";
2677  if (iint > 0) goto L930;
2678  krl = -abs(iext);
2679  mnfree(krl);
2680  lfreed = kurTRUE;
2681  }
2682  continue;
2683 L930:
2684  std::printf(" PARAMETER%4d %s IGNORED.\n",iext,chwhy.c_str());
2685  }
2686  if (lfreed || lfixed) mnrset(0);
2687  if (lfreed) {
2688  fISW[1] = 0;
2689  fDcovar = 1;
2690  fEDM = fBigedm;
2691  fISW[3] = 0;
2692  }
2693  mnwerr();
2694  if (fISW[4] > 1) mnprin(5, fAmin);
2695  return;
2696 //*-*- . . . . . . . . . . restore
2697 L1000:
2698  it = Int_urt(fWord7[0]);
2699  if (it > 1 || it < 0) goto L1005;
2700  lfreed = fNpfix > 0;
2701  mnfree(it);
2702  if (lfreed) {
2703  mnrset(0);
2704  fISW[1] = 0;
2705  fDcovar = 1;
2706  fEDM = fBigedm;
2707  }
2708  return;
2709 L1005:
2710  std::printf(" IGNORED. UNKNOWN ARGUMENT:%4d\n",it);
2711  ierflg = 3;
2712  return;
2713 //*-*- . . . . . . . . . . release
2714 L1100:
2715  ltofix = kurFALSE;
2716  goto L901;
2717 //*-*- . . . . . . . . . . scan . . .
2718 L1200:
2719  iext = Int_urt(fWord7[0]);
2720  if (iext <= 0) goto L1210;
2721  it2 = 0;
2722 // if (iext <= fNu) it2 = fNiofex[iext-1];
2723  if (iext <= fNu) it2 = m_userParameterIdToInternalId[iext];
2724  if (it2 <= 0) goto L1250;
2725 
2726 L1210:
2727  mnscan();
2728  return;
2729 L1250:
2730  std::printf(" PARAMETER%4d NOT VARIABLE.\n",iext);
2731  ierflg = 3;
2732  return;
2733 //*-*- . . . . . . . . . . contour
2734 L1300:
2735  ke1 = Int_urt(fWord7[0]);
2736  ke2 = Int_urt(fWord7[1]);
2737  if (ke1 == 0) {
2738  if (fNpar == 2) {
2739  ke1 = fNexofi[0];
2740  ke2 = fNexofi[1];
2741  } else {
2742  std::printf("%s: NO PARAMETERS REQUESTED \n",fCword.c_str());
2743  ierflg = 3;
2744  return;
2745  }
2746  }
2747  fNfcnmx = 1000;
2748 // mncntr(ke1-1, ke2-1, ierrf);
2749  mncntr(ke1, ke2, ierrf);
2750  if (ierrf > 0) ierflg = 3;
2751  return;
2752 //*-*- . . . . . . . . . . hesse
2753 L1400:
2754  mnhess();
2755  mnwerr();
2756  if (fISW[4] >= 0) mnprin(2, fAmin);
2757  if (fISW[4] >= 1) mnmatu(1);
2758  return;
2759 //*-*- . . . . . . . . . . save
2760 L1500:
2761  mnsave();
2762  return;
2763 //*-*- . . . . . . . . . . improve
2764 L1600:
2765  mncuve();
2766  mnimpr();
2767  if (fLnewmn) goto L400;
2768  ierflg = 4;
2769  return;
2770 //*-*- . . . . . . . . . . call fcn
2771 L1700:
2772  iflag = Int_urt(fWord7[0]);
2773  nparx = fNpar;
2774  f = fUndefi;
2775 // Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
2776  Eval(nparx, fGin, f, m_userParameterValue, iflag); ++fNfcn;
2777  nowprt = 0;
2778  if (f != fUndefi) {
2779  if (fAmin == fUndefi) {
2780  fAmin = f;
2781  nowprt = 1;
2782  } else if (f < fAmin) {
2783  fAmin = f;
2784  nowprt = 1;
2785  }
2786  if (fISW[4] >= 0 && iflag <= 5 && nowprt == 1) {
2787  mnprin(5, fAmin);
2788  }
2789  if (iflag == 3) fFval3 = f;
2790  }
2791  if (iflag > 5) mnrset(1);
2792  return;
2793 //*-*- . . . . . . . . . . standard
2794 L1800:
2795 // stand();
2796  return;
2797 //*-*- . . . return, stop, end, exit
2798 L1900:
2799  it = Int_urt(fWord7[0]);
2800  if (fFval3 != fAmin && it == 0) {
2801  iflag = 3;
2802  std::printf(" CALL TO USER FUNCTION WITH IFLAG = 3\n");
2803  nparx = fNpar;
2804 // Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
2805  Eval(nparx, fGin, f, m_userParameterValue, iflag); ++fNfcn;
2806  }
2807  ierflg = 11;
2808  if (fCword.substr(0,3) == "END") ierflg = 10;
2809  if (fCword.substr(0,3) == "RET") ierflg = 12;
2810  return;
2811 //*-*- . . . . . . . . . . clear
2812 L2200:
2813  mncler();
2814  if (fISW[4] >= 1) {
2815  std::printf(" MINUIT MEMORY CLEARED. NO PARAMETERS NOW DEFINED.\n");
2816  }
2817  return;
2818 //*-*- . . . . . . . . . . help
2819 L2300:
2820  kcol = 0;
2821  for (icol = 5; icol <= lk; ++icol) {
2822  if (fCword[icol-1] == ' ') continue;
2823  kcol = icol;
2824  goto L2320;
2825  }
2826 L2320:
2827  if (kcol == 0) comd = "* ";
2828  else comd = fCword.substr(kcol-1,lk-kcol+1);
2829  mnhelp(comd);
2830  return;
2831 //*-*- . . . . . . . . . . MNContour
2832 L2400:
2833  fEpsi = fUp*.05;
2834  ke1 = Int_urt(fWord7[0]);
2835  ke2 = Int_urt(fWord7[1]);
2836  if (ke1 == 0 && fNpar == 2) {
2837  ke1 = fNexofi[0];
2838  ke2 = fNexofi[1];
2839  }
2840  nptu = Int_urt(fWord7[2]);
2841  if (nptu <= 0) nptu = 20;
2842  if (nptu > 101) nptu = 101;
2843  fNfcnmx = (nptu + 5)*100*(fNpar + 1);
2844 // mncont(ke1-1, ke2-1, nptu, xptu, yptu, ierrf);
2845  mncont(ke1, ke2, nptu, xptu, yptu, ierrf);
2846  if (ierrf < nptu) ierflg = 4;
2847  if (ierrf == -1) ierflg = 3;
2848  return;
2849 //*-*- . . . . . . . . . . jump
2850 L2600:
2851  step = fWord7[0];
2852  if (step <= 0) step = 2;
2853  rno = 0;
2854  izero = 0;
2855  for (i = 1; i <= fNpar; ++i) {
2856  mnrn15(rno, izero);
2857  rno = rno*2 - 1;
2858  fX[i-1] += rno*step*fWerr[i-1];
2859  }
2860  mninex(fX);
2861  mnamin();
2862  mnrset(0);
2863  return;
2864 //*-*- . . . . . . . . . . blank line
2865 L3300:
2866  std::printf(" BLANK COMMAND IGNORED.\n");
2867  ierflg = 1;
2868  return;
2869 //*-* . . . . . . . . obsolete commands . . . . . . . . . . . . . .
2870 //*-*- . . . . . . . . . . covariance
2871 L3400:
2872  std::printf(" THE *COVARIANCE* COMMAND IS OSBSOLETE. THE COVARIANCE MATRIX IS NOW SAVED IN A DIFFERENT FORMAT WITH THE *SAVE* COMMAND AND READ IN WITH:*SET COVARIANCE*\n");
2873  ierflg = 3;
2874  return;
2875 //*-*- . . . . . . . . . . printout
2876 L3500:
2877  cneway = "SET PRInt ";
2878  goto L3100;
2879 //*-*- . . . . . . . . . . gradient
2880 L3600:
2881  cneway = "SET GRAd ";
2882  goto L3100;
2883 //*-*- . . . . . . . . . . matout
2884 L3700:
2885  cneway = "SHOW COVar";
2886  goto L3100;
2887 //*-*- . . . . . . . . . error def
2888 L3800:
2889  cneway = "SET ERRdef";
2890  goto L3100;
2891 //*-*- . . . . . . . . . . limits
2892 L3900:
2893  cneway = "SET LIMits";
2894  goto L3100;
2895 //*-*- . . . . . . . . . . punch
2896 L4000:
2897  cneway = "SAVE ";
2898 //*-*- ....... come from obsolete commands
2899 L3100:
2900  std::printf(" OBSOLETE COMMAND:%s PLEASE USE: %s\n",fCword.c_str()
2901  ,cneway.c_str());
2902  fCword = cneway;
2903  if (fCword == "SAVE ") goto L1500;
2904  goto L700;
2905 //*-* . . . . . . . . . . . . . . . . . .
2906 } /* mnexcm_ */
2907 
2908 //______________________________________________________________________________
2910 {
2911 //*-*-*-*-*Transforms the external parameter values U to internal values*-*-*
2912 //*-* =============================================================
2913 //*-* Transforms the external parameter values U to internal
2914 //*-* values in the dense array PINT.
2915 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2916 
2917  Double_urt pinti;
2918  Int_urt iint, iext;
2919 
2920  fLimset = kurFALSE;
2921  for (iint = 1; iint <= fNpar; ++iint) {
2922  iext = fNexofi[iint-1];
2923 // mnpint(fU[iext-1], iext-1, pinti);
2924  mnpint(m_userParameterValue[iext], iext, pinti);
2925  pint[iint-1] = pinti;
2926  }
2927 } /* mnexin_ */
2928 
2929 //______________________________________________________________________________
2931 {
2932 //*-*-*-*-*-*-*Removes parameter IINT from the internal parameter list*-*-*
2933 //*-* =======================================================
2934 //*-* and arranges the rest of the list to fill the hole.
2935 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2936 
2937  /* Local variables */
2938  Double_urt yyover;
2939  Int_urt kold, nold, ndex, knew, iext, i, j, m, n, lc, ik;
2940 
2941 //*-*- first see if it can be done
2942  ierr = 0;
2943  Int_urt iint = iint1+1;
2944  if (iint > fNpar || iint <= 0) {
2945  ierr = 1;
2946  std::printf(" MINUIT ERROR. ARGUMENT TO MNFIXP=%4d\n",iint);
2947  return;
2948  }
2949  iext = fNexofi[iint-1];
2950  if (fNpfix >= fMaxpar) {
2951  ierr = 1;
2952  std::printf(" MINUIT CANNOT FIX PARAMETER%4d MAXIMUM NUMBER THAT CAN BE FIXED IS %d\n",iext,fMaxpar);
2953  return;
2954  }
2955 //*-*- reduce number of variable parameters by one
2956 
2957 // fNiofex[iext-1] = 0;
2958  m_userParameterIdToInternalId[iext] = 0;
2959  nold = fNpar;
2960  --fNpar;
2961 //*-*- save values in case parameter is later restored
2962 
2963  ++fNpfix;
2964  fIpfix[fNpfix-1] = iext;
2965  lc = iint;
2966  fXs[fNpfix-1] = fX[lc-1];
2967  fXts[fNpfix-1] = fXt[lc-1];
2968  fDirins[fNpfix-1] = fWerr[lc-1];
2969  fGrds[fNpfix-1] = fGrd[lc-1];
2970  fG2s[fNpfix-1] = fG2[lc-1];
2971  fGsteps[fNpfix-1] = fGstep[lc-1];
2972 //*-*- shift values for other parameters to fill hole
2973  for (ik = iext + 1; ik <= fNu; ++ik) {
2974 // if (fNiofex[ik-1] > 0) {
2975  if (m_userParameterIdToInternalId[ik] > 0) {
2976 // lc = fNiofex[ik-1] - 1;
2977  lc = m_userParameterIdToInternalId[ik] - 1;
2978 // fNiofex[ik-1] = lc;
2979  m_userParameterIdToInternalId[ik] = lc;
2980  fNexofi[lc-1] = ik;
2981  fX[lc-1] = fX[lc];
2982  fXt[lc-1] = fXt[lc];
2983  fDirin[lc-1] = fDirin[lc];
2984  fWerr[lc-1] = fWerr[lc];
2985  fGrd[lc-1] = fGrd[lc];
2986  fG2[lc-1] = fG2[lc];
2987  fGstep[lc-1] = fGstep[lc];
2988  }
2989  }
2990  if (fISW[1] <= 0) return;
2991 //*-*- remove one row and one column from variance matrix
2992  if (fNpar <= 0) return;
2993  for (i = 1; i <= nold; ++i) {
2994  m = URMath::Max(i,iint);
2995  n = URMath::Min(i,iint);
2996  ndex = m*(m-1) / 2 + n;
2997  fFIXPyy[i-1] = fVhmat[ndex-1];
2998  }
2999  yyover = 1 / fFIXPyy[iint-1];
3000  knew = 0;
3001  kold = 0;
3002  for (i = 1; i <= nold; ++i) {
3003  for (j = 1; j <= i; ++j) {
3004  ++kold;
3005  if (j == iint || i == iint) continue;
3006  ++knew;
3007  fVhmat[knew-1] = fVhmat[kold-1] - fFIXPyy[j-1]*fFIXPyy[i-1]*yyover;
3008  }
3009  }
3010 } /* mnfixp_ */
3011 
3012 //______________________________________________________________________________
3014 {
3015 //*-*-*-*Restores one or more fixed parameter(s) to variable status*-*-*-*-*-*
3016 //*-* ==========================================================
3017 //*-* Restores one or more fixed parameter(s) to variable status
3018 //*-* by inserting it into the internal parameter list at the
3019 //*-* appropriate place.
3020 //*-*
3021 //*-* K = 0 means restore all parameters
3022 //*-* K = 1 means restore the last parameter fixed
3023 //*-* K = -I means restore external parameter I (if possible)
3024 //*-* IQ = fix-location where internal parameters were stored
3025 //*-* IR = external number of parameter being restored
3026 //*-* IS = internal number of parameter being restored
3027 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3028 
3029  /* Local variables */
3030  Double_urt grdv, xv, dirinv, g2v, gstepv, xtv;
3031  Int_urt i, ipsav, ka, lc, ik, iq, ir, is;
3032 
3033  if (k > 1) {
3034  std::printf(" CALL TO MNFREE IGNORED. ARGUMENT GREATER THAN ONE\n");
3035  }
3036  if (fNpfix < 1) {
3037  std::printf(" CALL TO MNFREE IGNORED. THERE ARE NO FIXED PARAMETERS\n");
3038  }
3039  if (k == 1 || k == 0) goto L40;
3040 
3041 //*-*- release parameter with specified external number
3042  ka = abs(k);
3043 // if (fNiofex[ka-1] == 0) goto L15;
3044  if (m_userParameterIdToInternalId[ka] == 0) goto L15;
3045  std::printf(" IGNORED. PARAMETER SPECIFIED IS ALREADY VARIABLE.\n");
3046  return;
3047 L15:
3048  if (fNpfix < 1) goto L21;
3049  for (ik = 1; ik <= fNpfix; ++ik) { if (fIpfix[ik-1] == ka) goto L24; }
3050 L21:
3051  std::printf(" PARAMETER%4d NOT FIXED. CANNOT BE RELEASED.\n",ka);
3052  return;
3053 L24:
3054  if (ik == fNpfix) goto L40;
3055 
3056 //*-*- move specified parameter to end of list
3057  ipsav = ka;
3058  xv = fXs[ik-1];
3059  xtv = fXts[ik-1];
3060  dirinv = fDirins[ik-1];
3061  grdv = fGrds[ik-1];
3062  g2v = fG2s[ik-1];
3063  gstepv = fGsteps[ik-1];
3064  for (i = ik + 1; i <= fNpfix; ++i) {
3065  fIpfix[i-2] = fIpfix[i-1];
3066  fXs[i-2] = fXs[i-1];
3067  fXts[i-2] = fXts[i-1];
3068  fDirins[i-2] = fDirins[i-1];
3069  fGrds[i-2] = fGrds[i-1];
3070  fG2s[i-2] = fG2s[i-1];
3071  fGsteps[i-2] = fGsteps[i-1];
3072  }
3073  fIpfix[fNpfix-1] = ipsav;
3074  fXs[fNpfix-1] = xv;
3075  fXts[fNpfix-1] = xtv;
3076  fDirins[fNpfix-1] = dirinv;
3077  fGrds[fNpfix-1] = grdv;
3078  fG2s[fNpfix-1] = g2v;
3079  fGsteps[fNpfix-1] = gstepv;
3080 //*-*- restore last parameter in fixed list -- IPFIX(NPFIX)
3081 L40:
3082  if (fNpfix < 1) goto L300;
3083  ir = fIpfix[fNpfix-1];
3084  is = 0;
3085  // shift internal one higher to create hole for parameter that has been freed
3086  for (ik = fNu; ik >= ir; --ik) {
3087 // if (fNiofex[ik-1] > 0) {
3088  if (m_userParameterIdToInternalId[ik] > 0) {
3089 // lc = fNiofex[ik-1] + 1;
3090  lc = m_userParameterIdToInternalId[ik] + 1;
3091  is = lc - 1;
3092 // fNiofex[ik-1] = lc;
3093  m_userParameterIdToInternalId[ik] = lc;
3094  fNexofi[lc-1] = ik;
3095  fX[lc-1] = fX[lc-2];
3096  fXt[lc-1] = fXt[lc-2];
3097  fDirin[lc-1] = fDirin[lc-2];
3098  fWerr[lc-1] = fWerr[lc-2];
3099  fGrd[lc-1] = fGrd[lc-2];
3100  fG2[lc-1] = fG2[lc-2];
3101  fGstep[lc-1] = fGstep[lc-2];
3102  }
3103  }
3104  ++fNpar;
3105  if (is == 0) is = fNpar;
3106 // fNiofex[ir-1] = is;
3107  m_userParameterIdToInternalId[ir] = is;
3108  fNexofi[is-1] = ir;
3109  iq = fNpfix;
3110  fX[is-1] = fXs[iq-1];
3111  fXt[is-1] = fXts[iq-1];
3112  fDirin[is-1] = fDirins[iq-1];
3113  fWerr[is-1] = fDirins[iq-1];
3114  fGrd[is-1] = fGrds[iq-1];
3115  fG2[is-1] = fG2s[iq-1];
3116  fGstep[is-1] = fGsteps[iq-1];
3117  --fNpfix;
3118  fISW[1] = 0;
3119  fDcovar = 1;
3120  if (fISW[4] - fItaur >= 1) {
3121 // std::printf(" PARAMETER%4d %s RESTORED TO VARIABLE.\n",ir,
3122 // fCpnam[ir-1].c_str());
3123  std::printf(" PARAMETER%4d %s RESTORED TO VARIABLE.\n",ir,
3124  m_userParameterName[ir].c_str());
3125  }
3126  if (k == 0) goto L40;
3127 L300:
3128 //*-*- if different from internal, external values are taken
3129  mnexin(fX);
3130 } /* mnfree_ */
3131 
3132 //______________________________________________________________________________
3134 {
3135 //*-*-*-*-*-*-*-*-*-*Interprets the SET GRAD command*-*-*-*-*-*-*-*-*-*-*-*-*
3136 //*-* ===============================
3137 //*-* Called from MNSET
3138 //*-* Interprets the SET GRAD command, which informs MINUIT whether
3139 //*-* the first derivatives of FCN will be calculated by the user
3140 //*-* inside FCN. It can check the user derivative calculation
3141 //*-* by comparing it with a finite difference approximation.
3142 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3143 
3144  /* Local variables */
3145  Double_urt fzero, err;
3146  Int_urt i, nparx, lc, istsav;
3147  Bool_urt lnone;
3148  static string cwd = " ";
3149 
3150  fISW[2] = 1;
3151  nparx = fNpar;
3152  if (fWord7[0] > 0) goto L2000;
3153 
3154 //*-*- get user-calculated first derivatives from FCN
3155  for (i = 1; i <= fNu; ++i) { fGin[i-1] = fUndefi; }
3156  mninex(fX);
3157 // Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
3158  Eval(nparx, fGin, fzero, m_userParameterValue, 2); ++fNfcn;
3159  mnderi();
3160  for (i = 1; i <= fNpar; ++i) { fGRADgf[i-1] = fGrd[i-1]; }
3161 //*-*- get MINUIT-calculated first derivatives
3162  fISW[2] = 0;
3163  istsav = fIstrat;
3164  fIstrat = 2;
3165  mnhes1();
3166  fIstrat = istsav;
3167  std::printf(" CHECK OF GRADIENT CALCULATION IN FCN\n");
3168  std::printf(" PARAMETER G(IN FCN) G(MINUIT) DG(MINUIT) AGREEMENT\n");
3169  fISW[2] = 1;
3170  lnone = kurFALSE;
3171  for (lc = 1; lc <= fNpar; ++lc) {
3172  i = fNexofi[lc-1];
3173  cwd = "GOOD";
3174  err = fDgrd[lc-1];
3175  if (URMath::Abs(fGRADgf[lc-1] - fGrd[lc-1]) > err) cwd = " BAD";
3176  if (fGin[i-1] == fUndefi) {
3177  cwd = "NONE";
3178  lnone = kurTRUE;
3179  fGRADgf[lc-1] = 0;
3180  }
3181  if (cwd != "GOOD") fISW[2] = 0;
3182 // std::printf(" %5d %10s%12.4e%12.4e%12.4e %s\n",i
3183 // ,(fCpnam[i-1]).c_str()
3184 // ,fGRADgf[lc-1],fGrd[lc-1],err,cwd.c_str());
3185  std::printf(" %5d %10s%12.4e%12.4e%12.4e %s\n",i
3186  ,(m_userParameterName[i]).c_str()
3187  ,fGRADgf[lc-1],fGrd[lc-1],err,cwd.c_str());
3188  }
3189  if (lnone) {
3190  std::printf(" AGREEMENT=NONE MEANS FCN DID NOT CALCULATE THE DERIVATIVE\n");
3191  }
3192  if (fISW[2] == 0) {
3193  std::printf(" MINUIT DOES NOT ACCEPT DERIVATIVE CALCULATIONS BY FCN\n");
3194  std::printf(" TO FORCE ACCEPTANCE, ENTER *SET GRAD 1*\n");
3195  }
3196 
3197 L2000:
3198  return;
3199 } /* mngrad_ */
3200 
3201 //______________________________________________________________________________
3203 {
3204  string comd = "";
3205  mnhelp(comd);
3206 }
3207 
3208 //______________________________________________________________________________
3209 void URMinuit::mnhelp(const string& comd_in)
3210 {
3211 //*-*-*-*-*-*-*-*HELP routine for MINUIT interactive commands*-*-*-*-*-*-*-*-*
3212 //*-* ============================================
3213 //*-*
3214 //*-* COMD ='*' or "" prints a global help for all commands
3215 //*-* COMD =Command_name: print detailed help for one command.
3216 //*-* Note that at least 3 characters must be given for the command
3217 //*-* name.
3218 //*-*
3219 //*-* Author: Rene Brun
3220 //*-* comments extracted from the MINUIT documentation file.
3221 //*-*
3222 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3223 
3224 //*-*.......................................................................
3225 //*-*
3226 //*-* Global HELP: Summary of all commands
3227 //*-* ====================================
3228 //*-*
3229  string comd = comd_in;
3230  int (*pf)(int)=toupper;
3231  transform(comd.begin(), comd.end(), comd.begin(), pf);
3232 // if( comd.length() == 0 || comd[0] == "*" || comd[0] == "?" || comd[0] == 0 || comd=="HELP" ) {
3233  if( comd.length() == 0 || comd.substr(0,1) == "*" || comd.substr(0,1) == "?" || comd=="HELP" ) {
3234  std::printf(" ==>List of MINUIT Interactive commands:\n");
3235  std::printf(" CLEar Reset all parameter names and values undefined\n");
3236  std::printf(" CONtour Make contour map of the user function\n");
3237  std::printf(" EXIT Exit from Interactive Minuit\n");
3238  std::printf(" FIX Cause parameter(s) to remain constant\n");
3239  std::printf(" HESse Calculate the Hessian or error matrix.\n");
3240  std::printf(" IMPROVE Search for a new minimum around current minimum\n");
3241  std::printf(" MIGrad Minimize by the method of Migrad\n");
3242  std::printf(" MINImize MIGRAD + SIMPLEX method if Migrad fails\n");
3243  std::printf(" MINOs Exact (non-linear) parameter error analysis\n");
3244  std::printf(" MNContour Calculate one MINOS function contour\n");
3245  std::printf(" PARameter Define or redefine new parameters and values\n");
3246  std::printf(" RELease Make previously FIXed parameters variable again\n");
3247  std::printf(" REStore Release last parameter fixed\n");
3248  std::printf(" SAVe Save current parameter values on a file\n");
3249  std::printf(" SCAn Scan the user function by varying parameters\n");
3250  std::printf(" SEEk Minimize by the method of Monte Carlo\n");
3251  std::printf(" SET Set various MINUIT constants or conditions\n");
3252  std::printf(" SHOw Show values of current constants or conditions\n");
3253  std::printf(" SIMplex Minimize by the method of Simplex\n");
3254  goto L99;
3255  }
3256 
3257 //*-* __________________________________________________________________
3258 //*-*
3259 //*-* -- Command CLEAR
3260 //*-* -- =============
3261 //*-*
3262  if( !strncmp(comd.c_str(),"CLE",3) ) {
3263  std::printf(" ***>CLEAR");
3264  std::printf(" Resets all parameter names and values to undefined.\n");
3265  std::printf(" Must normally be followed by a PARameters command or \n");
3266  std::printf(" equivalent, in order to define parameter values.\n");
3267  goto L99;
3268  }
3269 //*-* __________________________________________________________________
3270 //*-* --
3271 //*-* -- Command CONTOUR
3272 //*-* -- ===============
3273 //*-* .
3274  if( !strncmp(comd.c_str(),"CON",3) ) {
3275  std::printf(" ***>CONTOUR <par1> <par2> [devs] [ngrid]\n");
3276  std::printf(" Instructs Minuit to trace contour lines of the user function\n");
3277  std::printf(" with respect to the two parameters whose external numbers\n");
3278  std::printf(" are <par1> and <par2>.\n");
3279  std::printf(" Other variable parameters of the function, if any, will have\n");
3280  std::printf(" their values fixed at the current values during the contour\n");
3281  std::printf(" tracing. The optional parameter [devs] (default value 2.)\n");
3282  std::printf(" gives the number of standard deviations in each parameter\n");
3283  std::printf(" which should lie entirely within the plotting area.\n");
3284  std::printf(" Optional parameter [ngrid] (default value 25 unless page\n");
3285  std::printf(" size is too small) determines the resolution of the plot,\n");
3286  std::printf(" i.e. the number of rows and columns of the grid at which the\n");
3287  std::printf(" function will be evaluated. [See also MNContour.]\n");
3288  goto L99;
3289  }
3290 //*-* __________________________________________________________________
3291 //*-* --
3292 //*-* -- Command END
3293 //*-* -- ===========
3294 //*-* .
3295  if( !strncmp(comd.c_str(),"END",3) ) {
3296  std::printf(" ***>END\n");
3297  std::printf(" Signals the end of a data block (i.e., the end of a fit),\n");
3298  std::printf(" and implies that execution should continue, because another\n");
3299  std::printf(" Data Block follows. A Data Block is a set of Minuit data\n");
3300  std::printf(" consisting of\n");
3301  std::printf(" (1) A Title,\n");
3302  std::printf(" (2) One or more Parameter Definitions,\n");
3303  std::printf(" (3) A blank line, and\n");
3304  std::printf(" (4) A set of Minuit Commands.\n");
3305  std::printf(" The END command is used when more than one Data Block is to\n");
3306  std::printf(" be used with the same FCN function. It first causes Minuit\n");
3307  std::printf(" to issue a CALL FCN with IFLAG=3, in order to allow FCN to\n");
3308  std::printf(" perform any calculations associated with the final fitted\n");
3309  std::printf(" parameter values, unless a CALL FCN 3 command has already\n");
3310  std::printf(" been executed at the current FCN value.\n");
3311  goto L99;
3312  }
3313 //*-* __________________________________________________________________
3314 //*-* .
3315 //*-* --
3316 //*-* -- Command EXIT
3317 //*-* -- ============
3318  if( !strncmp(comd.c_str(),"EXI",3) ) {
3319  std::printf(" ***>EXIT\n");
3320  std::printf(" Signals the end of execution.\n");
3321  std::printf(" The EXIT command first causes Minuit to issue a CALL FCN\n");
3322  std::printf(" with IFLAG=3, to allow FCN to perform any calculations\n");
3323  std::printf(" associated with the final fitted parameter values, unless a\n");
3324  std::printf(" CALL FCN 3 command has already been executed.\n");
3325  goto L99;
3326  }
3327 //*-* __________________________________________________________________
3328 //*-* --
3329 //*-* -- Command FIX
3330 //*-* -- ===========
3331 //*-* .
3332  if( !strncmp(comd.c_str(),"FIX",3) ) {
3333  std::printf(" ***>FIX} <parno> [parno] ... [parno]\n");
3334  std::printf(" Causes parameter(s) <parno> to be removed from the list of\n");
3335  std::printf(" variable parameters, and their value(s) will remain constant\n");
3336  std::printf(" during subsequent minimizations, etc., until another command\n");
3337  std::printf(" changes their value(s) or status.\n");
3338  goto L99;
3339  }
3340 //*-* __________________________________________________________________
3341 //*-* --
3342 //*-* -- Command HESSE
3343 //*-* -- =============
3344 //*-* .
3345  if( !strncmp(comd.c_str(),"HES",3) ) {
3346  std::printf(" ***>HESse [maxcalls]");
3347  std::printf(" Calculate, by finite differences, the Hessian or error matrix.\n");
3348  std::printf(" That is, it calculates the full matrix of second derivatives\n");
3349  std::printf(" of the function with respect to the currently variable\n");
3350  std::printf(" parameters, and inverts it, printing out the resulting error\n");
3351  std::printf(" matrix. The optional argument [maxcalls] specifies the\n");
3352  std::printf(" (approximate) maximum number of function calls after which\n");
3353  std::printf(" the calculation will be stopped.\n");
3354  goto L99;
3355  }
3356 //*-* __________________________________________________________________
3357 //*-* --
3358 //*-* -- Command IMPROVE
3359 //*-* -- ===============
3360 //*-* .
3361  if( !strncmp(comd.c_str(),"IMP",3) ) {
3362  std::printf(" ***>IMPROVE [maxcalls]");
3363  std::printf(" If a previous minimization has converged, and the current\n");
3364  std::printf(" values of the parameters therefore correspond to a local\n");
3365  std::printf(" minimum of the function, this command requests a search for\n");
3366  std::printf(" additional distinct local minima.\n");
3367  std::printf(" The optional argument [maxcalls] specifies the (approximate\n");
3368  std::printf(" maximum number of function calls after which the calculation\n");
3369  std::printf(" will be stopped.\n");
3370  goto L99;
3371  }
3372 //*-* __________________________________________________________________
3373 //*-* --
3374 //*-* -- Command MIGRAD
3375 //*-* -- ==============
3376 //*-* .
3377  if( !strncmp(comd.c_str(),"MIG",3) ) {
3378  std::printf(" ***>MIGrad [maxcalls] [tolerance]\n");
3379  std::printf(" Causes minimization of the function by the method of Migrad,\n");
3380  std::printf(" the most efficient and complete single method, recommended\n");
3381  std::printf(" for general functions (see also MINImize).\n");
3382  std::printf(" The minimization produces as a by-product the error matrix\n");
3383  std::printf(" of the parameters, which is usually reliable unless warning\n");
3384  std::printf(" messages are produced.\n");
3385  std::printf(" The optional argument [maxcalls] specifies the (approximate)\n");
3386  std::printf(" maximum number of function calls after which the calculation\n");
3387  std::printf(" will be stopped even if it has not yet converged.\n");
3388  std::printf(" The optional argument [tolerance] specifies required tolerance\n");
3389  std::printf(" on the function value at the minimum.\n");
3390  std::printf(" The default tolerance is 0.1, and the minimization will stop\n");
3391  std::printf(" when the estimated vertical distance to the minimum (EDM) is\n");
3392  std::printf(" less than 0.001*[tolerance]*UP (see [SET ERRordef]).\n");
3393  goto L99;
3394  }
3395 //*-* __________________________________________________________________
3396 //*-* --
3397 //*-* -- Command MINIMIZE
3398 //*-* -- ================
3399 //*-* .
3400  if( !strncmp(comd.c_str(),"MINI",4) ) {
3401  std::printf(" ***>MINImize [maxcalls] [tolerance]\n");
3402  std::printf(" Causes minimization of the function by the method of Migrad,\n");
3403  std::printf(" as does the MIGrad command, but switches to the SIMplex method\n");
3404  std::printf(" if Migrad fails to converge. Arguments are as for MIGrad.\n");
3405  std::printf(" Note that command requires four characters to be unambiguous.\n");
3406  goto L99;
3407  }
3408 //*-* __________________________________________________________________
3409 //*-* --
3410 //*-* -- Command MINOS
3411 //*-* -- =============
3412 //*-* .
3413  if( !strncmp(comd.c_str(),"MIN0",4) ) {
3414  std::printf(" ***>MINOs [maxcalls] [parno] [parno] ...\n");
3415  std::printf(" Causes a Minos error analysis to be performed on the parameters\n");
3416  std::printf(" whose numbers [parno] are specified. If none are specified,\n");
3417  std::printf(" Minos errors are calculated for all variable parameters.\n");
3418  std::printf(" Minos errors may be expensive to calculate, but are very\n");
3419  std::printf(" reliable since they take account of non-linearities in the\n");
3420  std::printf(" problem as well as parameter correlations, and are in general\n");
3421  std::printf(" asymmetric.\n");
3422  std::printf(" The optional argument [maxcalls] specifies the (approximate)\n");
3423  std::printf(" maximum number of function calls per parameter requested,\n");
3424  std::printf(" after which the calculation will stop for that parameter.\n");
3425  goto L99;
3426  }
3427 //*-* __________________________________________________________________
3428 //*-* --
3429 //*-* -- Command MNCONTOUR
3430 //*-* -- =================
3431 //*-* .
3432  if( !strncmp(comd.c_str(),"MNC",3) ) {
3433  std::printf(" ***>MNContour <par1> <par2> [npts]\n");
3434  std::printf(" Calculates one function contour of FCN with respect to\n");
3435  std::printf(" parameters par1 and par2, with FCN minimized always with\n");
3436  std::printf(" respect to all other NPAR-2 variable parameters (if any).\n");
3437  std::printf(" Minuit will try to find npts points on the contour (default 20)\n");
3438  std::printf(" If only two parameters are variable at the time, it is not\n");
3439  std::printf(" necessary to specify their numbers. To calculate more than\n");
3440  std::printf(" one contour, it is necessary to SET ERRordef to the appropriate\n");
3441  std::printf(" value and issue the MNContour command for each contour.\n");
3442  goto L99;
3443  }
3444 //*-* __________________________________________________________________
3445 //*-* --
3446 //*-* -- Command PARAMETER
3447 //*-* -- =================
3448 //*-* .
3449  if( !strncmp(comd.c_str(),"PAR",3) ) {
3450  std::printf(" ***>PARameters\n");
3451  std::printf(" followed by one or more parameter definitions.\n");
3452  std::printf(" Parameter definitions are of the form:\n");
3453  std::printf(" <number> ''name'' <value> <step> [lolim] [uplim] \n");
3454  std::printf(" for example:\n");
3455  std::printf(" 3 ''K width'' 1.2 0.1\n");
3456  std::printf(" the last definition is followed by a blank line or a zero.\n");
3457  goto L99;
3458  }
3459 //*-* __________________________________________________________________
3460 //*-* --
3461 //*-* -- Command RELEASE
3462 //*-* -- ===============
3463 //*-* .
3464  if( !strncmp(comd.c_str(),"REL",3) ) {
3465  std::printf(" ***>RELease <parno> [parno] ... [parno]\n");
3466  std::printf(" If <parno> is the number of a previously variable parameter\n");
3467  std::printf(" which has been fixed by a command: FIX <parno>, then that\n");
3468  std::printf(" parameter will return to variable status. Otherwise a warning\n");
3469  std::printf(" message is printed and the command is ignored.\n");
3470  std::printf(" Note that this command operates only on parameters which were\n");
3471  std::printf(" at one time variable and have been FIXed. It cannot make\n");
3472  std::printf(" constant parameters variable; that must be done by redefining\n");
3473  std::printf(" the parameter with a PARameters command.\n");
3474  goto L99;
3475  }
3476 //*-* __________________________________________________________________
3477 //*-* --
3478 //*-* -- Command RESTORE
3479 //*-* -- ===============
3480 //*-* .
3481  if( !strncmp(comd.c_str(),"RES",3) ) {
3482  std::printf(" ***>REStore [code]\n");
3483  std::printf(" If no [code] is specified, this command restores all previously\n");
3484  std::printf(" FIXed parameters to variable status. If [code]=1, then only\n");
3485  std::printf(" the last parameter FIXed is restored to variable status.\n");
3486  std::printf(" If code is neither zero nor one, the command is ignored.\n");
3487  goto L99;
3488  }
3489 //*-* __________________________________________________________________
3490 //*-* --
3491 //*-* -- Command RETURN
3492 //*-* -- ==============
3493 //*-* .
3494  if( !strncmp(comd.c_str(),"RET",3) ) {
3495  std::printf(" ***>RETURN\n");
3496  std::printf(" Signals the end of a data block, and instructs Minuit to return\n");
3497  std::printf(" to the program which called it. The RETurn command first\n");
3498  std::printf(" causes Minuit to CALL FCN with IFLAG=3, in order to allow FCN\n");
3499  std::printf(" to perform any calculations associated with the final fitted\n");
3500  std::printf(" parameter values, unless a CALL FCN 3 command has already been\n");
3501  std::printf(" executed at the current FCN value.\n");
3502  goto L99;
3503  }
3504 //*-* __________________________________________________________________
3505 //*-* --
3506 //*-* -- Command SAVE
3507 //*-* -- ============
3508 //*-* .
3509  if( !strncmp(comd.c_str(),"SAV",3) ) {
3510  std::printf(" ***>SAVe\n");
3511  std::printf(" Causes the current parameter values to be saved on a file in\n");
3512  std::printf(" such a format that they can be read in again as Minuit\n");
3513  std::printf(" parameter definitions. If the covariance matrix exists, it is\n");
3514  std::printf(" also output in such a format. The unit number is by default 7,\n");
3515  std::printf(" or that specified by the user in his call to MINTIO or\n");
3516  std::printf(" MNINIT. The user is responsible for opening the file previous\n");
3517  std::printf(" to issuing the [SAVe] command (except where this can be done\n");
3518  std::printf(" interactively).\n");
3519  goto L99;
3520  }
3521 //*-* __________________________________________________________________
3522 //*-* --
3523 //*-* -- Command SCAN
3524 //*-* -- ============
3525 //*-* .
3526  if( !strncmp(comd.c_str(),"SCA",3) ) {
3527  std::printf(" ***>SCAn [parno] [numpts] [from] [to]\n");
3528  std::printf(" Scans the value of the user function by varying parameter\n");
3529  std::printf(" number [parno], leaving all other parameters fixed at the\n");
3530  std::printf(" current value. If [parno] is not specified, all variable\n");
3531  std::printf(" parameters are scanned in sequence.\n");
3532  std::printf(" The number of points [numpts] in the scan is 40 by default,\n");
3533  std::printf(" and cannot exceed 100. The range of the scan is by default\n");
3534  std::printf(" 2 standard deviations on each side of the current best value,\n");
3535  std::printf(" but can be specified as from [from] to [to].\n");
3536  std::printf(" After each scan, if a new minimum is found, the best parameter\n");
3537  std::printf(" values are retained as start values for future scans or\n");
3538  std::printf(" minimizations. The curve resulting from each scan is plotted\n");
3539  std::printf(" on the output unit in order to show the approximate behaviour\n");
3540  std::printf(" of the function.\n");
3541  std::printf(" This command is not intended for minimization, but is sometimes\n");
3542  std::printf(" useful for debugging the user function or finding a\n");
3543  std::printf(" reasonable starting point.\n");
3544  goto L99;
3545  }
3546 //*-* __________________________________________________________________
3547 //*-* --
3548 //*-* -- Command SEEK
3549 //*-* -- ============
3550 //*-* .
3551  if( !strncmp(comd.c_str(),"SEE",3) ) {
3552  std::printf(" ***>SEEk [maxcalls] [devs]\n");
3553  std::printf(" Causes a Monte Carlo minimization of the function, by choosing\n");
3554  std::printf(" random values of the variable parameters, chosen uniformly\n");
3555  std::printf(" over a hypercube centered at the current best value.\n");
3556  std::printf(" The region size is by default 3 standard deviations on each\n");
3557  std::printf(" side, but can be changed by specifying the value of [devs].\n");
3558  goto L99;
3559  }
3560 //*-* __________________________________________________________________
3561 //*-* --
3562 //*-* -- Command SET
3563 //*-* -- ===========
3564 //*-* .
3565  if( !strncmp(comd.c_str(),"SET",3) ) {
3566  std::printf(" ***>SET <option_name>\n");
3567  std::printf(" SET BATch\n");
3568  std::printf(" Informs Minuit that it is running in batch mode.\n");
3569 
3570  std::printf(" \n");
3571  std::printf(" SET EPSmachine <accuracy>\n");
3572  std::printf(" Informs Minuit that the relative floating point arithmetic\n");
3573  std::printf(" precision is <accuracy>. Minuit determines the nominal\n");
3574  std::printf(" precision itself, but the SET EPSmachine command can be\n");
3575  std::printf(" used to override Minuit own determination, when the user\n");
3576  std::printf(" knows that the FCN function value is not calculated to\n");
3577  std::printf(" the nominal machine accuracy. Typical values of <accuracy>\n");
3578  std::printf(" are between 10**-5 and 10**-14.\n");
3579 
3580  std::printf(" \n");
3581  std::printf(" SET ERRordef <up>\n");
3582  std::printf(" Sets the value of UP (default value= 1.), defining parameter\n");
3583  std::printf(" errors. Minuit defines parameter errors as the change\n");
3584  std::printf(" in parameter value required to change the function value\n");
3585  std::printf(" by UP. Normally, for chisquared fits UP=1, and for negative\n");
3586  std::printf(" log likelihood, UP=0.5.\n");
3587 
3588  std::printf(" ");
3589  std::printf(" SET GRAdient [force]\n");
3590  std::printf(" Informs Minuit that the user function is prepared to\n");
3591  std::printf(" calculate its own first derivatives and return their values\n");
3592  std::printf(" in the array GRAD when IFLAG=2 (see specs of FCN).\n");
3593  std::printf(" If [force] is not specified, Minuit will calculate\n");
3594  std::printf(" the FCN derivatives by finite differences at the current\n");
3595  std::printf(" point and compare with the user calculation at that point,\n");
3596  std::printf(" accepting the user values only if they agree.\n");
3597  std::printf(" If [force]=1, Minuit does not do its own derivative\n");
3598  std::printf(" calculation, and uses the derivatives calculated in FCN.\n");
3599 
3600  std::printf(" \n");
3601  std::printf(" SET INPut [unitno] [filename]\n");
3602  std::printf(" Causes Minuit, in data-driven mode only, to read subsequent\n");
3603  std::printf(" commands (or parameter definitions) from a different input\n");
3604  std::printf(" file. If no [unitno] is specified, reading reverts to the\n");
3605  std::printf(" previous input file, assuming that there was one.\n");
3606  std::printf(" If [unitno] is specified, and that unit has not been opened,\n");
3607  std::printf(" then Minuit attempts to open the file [filename]} if a\n");
3608  std::printf(" name is specified. If running in interactive mode and\n");
3609  std::printf(" [filename] is not specified and [unitno] is not opened,\n");
3610  std::printf(" Minuit prompts the user to enter a file name.\n");
3611  std::printf(" If the word REWIND is added to the command (note:no blanks\n");
3612  std::printf(" between INPUT and REWIND), the file is rewound before\n");
3613  std::printf(" reading. Note that this command is implemented in standard\n");
3614  std::printf(" Fortran 77 and the results may depend on the system;\n");
3615  std::printf(" for example, if a filename is given under VM/CMS, it must\n");
3616  std::printf(" be preceeded by a slash.\n");
3617 
3618  std::printf(" \n");
3619  std::printf(" SET INTeractive\n");
3620  std::printf(" Informs Minuit that it is running interactively.\n");
3621 
3622  std::printf(" \n");
3623  std::printf(" SET LIMits [parno] [lolim] [uplim]\n");
3624  std::printf(" Allows the user to change the limits on one or all\n");
3625  std::printf(" parameters. If no arguments are specified, all limits are\n");
3626  std::printf(" removed from all parameters. If [parno] alone is specified,\n");
3627  std::printf(" limits are removed from parameter [parno].\n");
3628  std::printf(" If all arguments are specified, then parameter [parno] will\n");
3629  std::printf(" be bounded between [lolim] and [uplim].\n");
3630  std::printf(" Limits can be specified in either order, Minuit will take\n");
3631  std::printf(" the smaller as [lolim] and the larger as [uplim].\n");
3632  std::printf(" However, if [lolim] is equal to [uplim], an error condition\n");
3633  std::printf(" results.\n");
3634 
3635  std::printf(" \n");
3636  std::printf(" SET LINesperpage\n");
3637  std::printf(" Sets the number of lines for one page of output.\n");
3638  std::printf(" Default value is 24 for interactive mode\n");
3639 
3640  std::printf(" \n");
3641  std::printf(" SET NOGradient");
3642  std::printf(" The inverse of SET GRAdient, instructs Minuit not to\n");
3643  std::printf(" use the first derivatives calculated by the user in FCN.\n");
3644 
3645  std::printf(" \n");
3646  std::printf(" SET NOWarnings\n");
3647  std::printf(" Supresses Minuit warning messages.\n");
3648 
3649  std::printf(" \n");
3650  std::printf(" SET OUTputfile <unitno>\n");
3651  std::printf(" Instructs Minuit to write further output to unit <unitno>.\n");
3652 
3653  std::printf(" \n");
3654  std::printf(" SET PAGethrow <integer>\n");
3655  std::printf(" Sets the carriage control character for ``new page'' to\n");
3656  std::printf(" <integer>. Thus the value 1 produces a new page, and 0\n");
3657  std::printf(" produces a blank line, on some devices (see TOPofpage)\n");
3658 
3659 
3660  std::printf(" \n");
3661  std::printf(" SET PARameter <parno> <value>\n");
3662  std::printf(" Sets the value of parameter <parno> to <value>.\n");
3663  std::printf(" The parameter in question may be variable, fixed, or\n");
3664  std::printf(" constant, but must be defined.\n");
3665 
3666  std::printf(" \n");
3667  std::printf(" SET PRIntout <level>\n");
3668  std::printf(" Sets the print level, determining how much output will be\n");
3669  std::printf(" produced. Allowed values and their meanings are displayed\n");
3670  std::printf(" after a SHOw PRInt command, and are currently <level>=:\n");
3671  std::printf(" [-1] no output except from SHOW commands\n");
3672  std::printf(" [0] minimum output\n");
3673  std::printf(" [1] default value, normal output\n");
3674  std::printf(" [2] additional output giving intermediate results.\n");
3675  std::printf(" [3] maximum output, showing progress of minimizations.\n");
3676  std::printf(" Note: See also the SET WARnings command.\n");
3677 
3678  std::printf(" \n");
3679  std::printf(" SET RANdomgenerator <seed>\n");
3680  std::printf(" Sets the seed of the random number generator used in SEEk.\n");
3681  std::printf(" This can be any integer between 10000 and 900000000, for\n");
3682  std::printf(" example one which was output from a SHOw RANdom command of\n");
3683  std::printf(" a previous run.\n");
3684 
3685  std::printf(" \n");
3686  std::printf(" SET STRategy <level>\n");
3687  std::printf(" Sets the strategy to be used in calculating first and second\n");
3688  std::printf(" derivatives and in certain minimization methods.\n");
3689  std::printf(" In general, low values of <level> mean fewer function calls\n");
3690  std::printf(" and high values mean more reliable minimization.\n");
3691  std::printf(" Currently allowed values are 0, 1 (default), and 2.\n");
3692 
3693  std::printf(" \n");
3694  std::printf(" SET TITle\n");
3695  std::printf(" Informs Minuit that the next input line is to be considered\n");
3696  std::printf(" the (new) title for this task or sub-task. This is for\n");
3697  std::printf(" the convenience of the user in reading his output.\n");
3698 
3699  std::printf(" \n");
3700  std::printf(" SET WARnings\n");
3701  std::printf(" Instructs Minuit to output warning messages when suspicious\n");
3702  std::printf(" conditions arise which may indicate unreliable results.\n");
3703  std::printf(" This is the default.\n");
3704 
3705  std::printf(" \n");
3706  std::printf(" SET WIDthpage\n");
3707  std::printf(" Informs Minuit of the output page width.\n");
3708  std::printf(" Default values are 80 for interactive jobs\n");
3709  goto L99;
3710  }
3711 //*-* __________________________________________________________________
3712 //*-* --
3713 //*-* -- Command SHOW
3714 //*-* -- ============
3715 //*-* .
3716  if( !strncmp(comd.c_str(),"SHO",3) ) {
3717  std::printf(" ***>SHOw <option_name>\n");
3718  std::printf(" All SET XXXX commands have a corresponding SHOw XXXX command.\n");
3719  std::printf(" In addition, the SHOw commands listed starting here have no\n");
3720  std::printf(" corresponding SET command for obvious reasons.\n");
3721 
3722  std::printf(" \n");
3723  std::printf(" SHOw CORrelations\n");
3724  std::printf(" Calculates and prints the parameter correlations from the\n");
3725  std::printf(" error matrix.\n");
3726 
3727  std::printf(" \n");
3728  std::printf(" SHOw COVariance\n");
3729  std::printf(" Prints the (external) covariance (error) matrix.\n");
3730 
3731  std::printf(" \n");
3732  std::printf(" SHOw EIGenvalues\n");
3733  std::printf(" Calculates and prints the eigenvalues of the covariance\n");
3734  std::printf(" matrix.");
3735 
3736  std::printf(" \n");
3737  std::printf(" SHOw FCNvalue\n");
3738  std::printf(" Prints the current value of FCN.\n");
3739  goto L99;
3740  }
3741 //*-* __________________________________________________________________
3742 //*-* --
3743 //*-* -- Command SIMPLEX
3744 //*-* -- ===============
3745 //*-* .
3746  if( !strncmp(comd.c_str(),"SIM",3) ) {
3747  std::printf(" ***>SIMplex [maxcalls] [tolerance]\n");
3748  std::printf(" Performs a function minimization using the simplex method of\n");
3749  std::printf(" Nelder and Mead. Minimization terminates either when the\n");
3750  std::printf(" function has been called (approximately) [maxcalls] times,\n");
3751  std::printf(" or when the estimated vertical distance to minimum (EDM) is\n");
3752  std::printf(" less than [tolerance].\n");
3753  std::printf(" The default value of [tolerance] is 0.1*UP(see SET ERRordef).\n");
3754  goto L99;
3755  }
3756 //*-* __________________________________________________________________
3757 //*-* --
3758 //*-* -- Command STANDARD
3759 //*-* -- ================
3760 //*-* .
3761  if( !strncmp(comd.c_str(),"STA",3) ) {
3762  std::printf(" ***>STAndard\n");
3763  goto L99;
3764  }
3765 //*-* __________________________________________________________________
3766 //*-* --
3767 //*-* -- Command STOP
3768 //*-* -- ============
3769 //*-* .
3770  if( !strncmp(comd.c_str(),"STO",3) ) {
3771  std::printf(" ***>STOP\n");
3772  std::printf(" Same as EXIT.\n");
3773  goto L99;
3774  }
3775 //*-* __________________________________________________________________
3776 //*-* --
3777 //*-* -- Command TOPOFPAGE
3778 //*-* -- =================
3779 //*-* .
3780  if( !strncmp(comd.c_str(),"TOP",3) ) {
3781  std::printf(" ***>TOPofpage\n");
3782  std::printf(" Causes Minuit to write the character specified in a\n");
3783  std::printf(" SET PAGethrow command (default = 1) to column 1 of the output\n");
3784  std::printf(" file, which may or may not position your output medium to\n");
3785  std::printf(" the top of a page depending on the device and system.\n");
3786  goto L99;
3787  }
3788 //*-* __________________________________________________________________
3789  std::printf(" Unknown MINUIT command. Type HELP for list of commands.\n");
3790 
3791 L99:
3792  return;
3793 } /* mnhelp_ */
3794 
3795 //______________________________________________________________________________
3797 {
3798 //*-*-*-*-*-*Calculates the full second-derivative matrix of FCN*-*-*-*-*-*-*-*
3799 //*-* ===================================================
3800 //*-* by taking finite differences. When calculating diagonal
3801 //*-* elements, it may iterate so that step size is nearly that
3802 //*-* which gives function change= UP/10. The first derivatives
3803 //*-* of course come as a free side effect, but with a smaller
3804 //*-* step size in order to obtain a known accuracy.
3805 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3806 
3807  /* Local variables */
3808  Double_urt dmin_, dxdi, elem, wint, tlrg2, d, dlast, ztemp, g2bfor;
3809  Double_urt df, aimsag, fs1, tlrstp, fs2, stpinm, g2i, sag=0, xtf, xti, xtj;
3810  Int_urt icyc, ncyc, ndex, idrv, iext, npar2, i, j, ifail, npard, nparx, id, multpy;
3811  Bool_urt ldebug;
3812 
3813  ldebug = fIdbg[3] >= 1;
3814  if (fAmin == fUndefi) {
3815  mnamin();
3816  }
3817  if (fIstrat <= 0) {
3818  ncyc = 3;
3819  tlrstp = .5;
3820  tlrg2 = .1;
3821  } else if (fIstrat == 1) {
3822  ncyc = 5;
3823  tlrstp = .3;
3824  tlrg2 = .05;
3825  } else {
3826  ncyc = 7;
3827  tlrstp = .1;
3828  tlrg2 = .02;
3829  }
3830  if (fISW[4] >= 2 || ldebug) {
3831  std::printf(" START COVARIANCE MATRIX CALCULATION.\n");
3832  }
3833  fCfrom = "HESSE ";
3834  fNfcnfr = fNfcn;
3835  fCstatu = "OK ";
3836  npard = fNpar;
3837 //*-*- make sure starting at the right place
3838  mninex(fX);
3839  nparx = fNpar;
3840 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
3841  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
3842  if (fs1 != fAmin) {
3843  df = fAmin - fs1;
3844  ostringstream warning;
3845  warning << "function value differs from AMIN by " << df;
3846  mnwarn("D", "MNHESS", warning.str().c_str());
3847  }
3848  fAmin = fs1;
3849  if (ldebug) {
3850  std::printf(" PAR D GSTEP D G2 GRD SAG \n");
3851  }
3852 //*-*- . . . . . . diagonal elements .
3853 
3854 //*-*- ISW(2) = 1 if approx, 2 if not posdef, 3 if ok
3855 //*-*- AIMSAG is the sagitta we are aiming for in second deriv calc.
3856 
3857  aimsag = URMath::Sqrt(fEpsma2)*(URMath::Abs(fAmin) + fUp);
3858 //*-*- Zero the second derivative matrix
3859  npar2 = fNpar*(fNpar + 1) / 2;
3860  for (i = 1; i <= npar2; ++i) { fVhmat[i-1] = 0; }
3861 
3862 //*-*- Loop over variable parameters for second derivatives
3863  idrv = 2;
3864  for (id = 1; id <= npard; ++id) {
3865  i = id + fNpar - npard;
3866  iext = fNexofi[i-1];
3867  if (fG2[i-1] == 0) {
3868  ostringstream warning;
3869  warning << "Second derivative enters zero, param " << iext;
3870  mnwarn("W", "HESSE", warning.str().c_str());
3871  wint = fWerr[i-1];
3872 // if (fNvarl[iext-1] > 1) {
3873  if (m_userParameterFlag[iext] > 1) {
3874  mndxdi(fX[i-1], i-1, dxdi);
3875  if (URMath::Abs(dxdi) < .001) wint = .01;
3876  else wint /= URMath::Abs(dxdi);
3877  }
3878  fG2[i-1] = fUp / (wint*wint);
3879  }
3880  xtf = fX[i-1];
3881  dmin_ = fEpsma2*8*URMath::Abs(xtf);
3882 
3883 //*-*- find step which gives sagitta = AIMSAG
3884  d = URMath::Abs(fGstep[i-1]);
3885  int skip50 = 0;
3886  for (icyc = 1; icyc <= ncyc; ++icyc) {
3887 //*-*- loop here only if SAG=0
3888  for (multpy = 1; multpy <= 5; ++multpy) {
3889 //*-*- take two steps
3890  fX[i-1] = xtf + d;
3891  mninex(fX);
3892  nparx = fNpar;
3893 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
3894  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
3895  fX[i-1] = xtf - d;
3896  mninex(fX);
3897 // Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
3898  Eval(nparx, fGin, fs2, m_userParameterValue, 4); ++fNfcn;
3899  fX[i-1] = xtf;
3900  sag = (fs1 + fs2 - fAmin*2)*.5;
3901  if (sag != 0) goto L30;
3902  if (fGstep[i-1] < 0) {
3903  if (d >= .5) goto L26;
3904  d *= 10;
3905  if (d > .5) d = .51;
3906  continue;
3907  }
3908  d *= 10;
3909  }
3910 L26:
3911  { ostringstream warning3;
3912  warning3 << "Second derivative zero for parameter " << iext;
3913  mnwarn("W", "HESSE", warning3.str().c_str()); }
3914  goto L390;
3915 //*-*- SAG is not zero
3916 L30:
3917  g2bfor = fG2[i-1];
3918  fG2[i-1] = sag*2 / (d*d);
3919  fGrd[i-1] = (fs1 - fs2) / (d*2);
3920  if (ldebug) {
3921  std::printf("%4d%2d%12.5g%12.5g%12.5g%12.5g\n",i,idrv,fGstep[i-1],fG2[i-1],fGrd[i-1],sag);
3922  }
3923  if (fGstep[i-1] > 0) fGstep[i-1] = URMath::Abs(d);
3924  else fGstep[i-1] = -URMath::Abs(d);
3925  fDirin[i-1] = d;
3926  fHESSyy[i-1]= fs1;
3927  dlast = d;
3928  d = URMath::Sqrt(aimsag*2 / URMath::Abs(fG2[i-1]));
3929 //*-*- if parameter has limits, max int step size = 0.5
3930  stpinm = .5;
3931  if (fGstep[i-1] < 0) d = URMath::Min(d,stpinm);
3932  if (d < dmin_) d = dmin_;
3933 //*-*- see if converged
3934  if (URMath::Abs((d - dlast) / d) < tlrstp ||
3935  URMath::Abs((fG2[i-1] - g2bfor) / fG2[i-1]) < tlrg2) {
3936  skip50 = 1;
3937  break;
3938  }
3939  d = URMath::Min(d,dlast*102);
3940  d = URMath::Max(d,dlast*.1);
3941  }
3942 //*-*- end of step size loop
3943  if (!skip50) {
3944  ostringstream warning;
3945  warning << "Second Deriv. SAG,AIM= " << iext << " " << sag << " " << aimsag;
3946  mnwarn("D", "MNHESS", warning.str().c_str());
3947  }
3948  ndex = i*(i + 1) / 2;
3949  fVhmat[ndex-1] = fG2[i-1];
3950  }
3951 //*-*- end of diagonal second derivative loop
3952  mninex(fX);
3953 //*-*- refine the first derivatives
3954  if (fIstrat > 0) mnhes1();
3955  fISW[1] = 3;
3956  fDcovar = 0;
3957 //*-*- . . . . off-diagonal elements
3958 
3959  if (fNpar == 1) goto L214;
3960  for (i = 1; i <= fNpar; ++i) {
3961  for (j = 1; j <= i-1; ++j) {
3962  xti = fX[i-1];
3963  xtj = fX[j-1];
3964  fX[i-1] = xti + fDirin[i-1];
3965  fX[j-1] = xtj + fDirin[j-1];
3966  mninex(fX);
3967 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
3968  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
3969  fX[i-1] = xti;
3970  fX[j-1] = xtj;
3971  elem = (fs1 + fAmin - fHESSyy[i-1] - fHESSyy[j-1]) / (
3972  fDirin[i-1]*fDirin[j-1]);
3973  ndex = i*(i-1) / 2 + j;
3974  fVhmat[ndex-1] = elem;
3975  }
3976  }
3977 L214:
3978  mninex(fX);
3979 //*-*- verify matrix positive-definite
3980  mnpsdf();
3981  for (i = 1; i <= fNpar; ++i) {
3982  for (j = 1; j <= i; ++j) {
3983  ndex = i*(i-1) / 2 + j;
3984  // factor of 0.5 here is based on observation not derivation
3985  // and noting that factor of 2 appears in setting fVhmat below
3986  // after inversion of fP (MRS)
3987  fSecDer[ndex-1] = fVhmat[ndex-1]*.5;
3988  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
3989  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
3990  }
3991  }
3992  mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
3993  if (ifail > 0) {
3994  mnwarn("W", "HESSE", "Matrix inversion fails.");
3995  goto L390;
3996  }
3997 //*-*- . . . . . . . calculate e d m
3998  fEDM = 0;
3999 
4000  for (i = 1; i <= fNpar; ++i) {
4001 //*-*- off-diagonal elements
4002  ndex = i*(i-1) / 2;
4003  for (j = 1; j <= i-1; ++j) {
4004  ++ndex;
4005  ztemp = fP[i + j*fMaxpar - fMaxpar-1]*2;
4006  fEDM += fGrd[i-1]*ztemp*fGrd[j-1];
4007  fVhmat[ndex-1] = ztemp;
4008  }
4009 //*-*- diagonal elements
4010  ++ndex;
4011  fVhmat[ndex-1] = fP[i + i*fMaxpar - fMaxpar-1]*2;
4012  fEDM += fP[i + i*fMaxpar - fMaxpar-1]*(fGrd[i-1]*fGrd[i-1]);
4013  }
4014  if (fISW[4] >= 1 && fISW[1] == 3 && fItaur == 0) {
4015  std::printf(" COVARIANCE MATRIX CALCULATED SUCCESSFULLY\n");
4016  }
4017  goto L900;
4018 //*-*- failure to invert 2nd deriv matrix
4019 L390:
4020  fISW[1] = 1;
4021  fDcovar = 1;
4022  fCstatu = "FAILED ";
4023  if (fISW[4] >= 0) {
4024  std::printf(" MNHESS FAILS AND WILL RETURN DIAGONAL MATRIX. \n");
4025  }
4026  for (i = 1; i <= fNpar; ++i) {
4027  ndex = i*(i-1) / 2;
4028  for (j = 1; j <= i-1; ++j) {
4029  ++ndex;
4030  fVhmat[ndex-1] = 0;
4031  }
4032  ++ndex;
4033  g2i = fG2[i-1];
4034  if (g2i <= 0) g2i = 1;
4035  fVhmat[ndex-1] = 2 / g2i;
4036  }
4037 L900:
4038  return;
4039 } /* mnhess_ */
4040 
4041 //______________________________________________________________________________
4043 {
4044 //*-*-*-*Calculate first derivatives (GRD) and uncertainties (DGRD)*-*-*-*-*-*
4045 //*-* ==========================================================
4046 //*-* and appropriate step sizes GSTEP
4047 //*-* Called from MNHESS and MNGRAD
4048 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4049 
4050  /* Local variables */
4051  Double_urt dmin_, d, dfmin, dgmin=0, change, chgold, grdold=0, epspri;
4052  Double_urt fs1, optstp, fs2, grdnew=0, sag, xtf;
4053  Int_urt icyc, ncyc=0, idrv, i, nparx;
4054  Bool_urt ldebug;
4055 
4056  ldebug = fIdbg[5] >= 1;
4057  if (fIstrat <= 0) ncyc = 1;
4058  if (fIstrat == 1) ncyc = 2;
4059  if (fIstrat > 1) ncyc = 6;
4060  idrv = 1;
4061  nparx = fNpar;
4062  dfmin = fEpsma2*4*(URMath::Abs(fAmin) + fUp);
4063 //*-*- main loop over parameters
4064  for (i = 1; i <= fNpar; ++i) {
4065  xtf = fX[i-1];
4066  dmin_ = fEpsma2*4*URMath::Abs(xtf);
4067  epspri = fEpsma2 + URMath::Abs(fGrd[i-1]*fEpsma2);
4068  optstp = URMath::Sqrt(dfmin / (URMath::Abs(fG2[i-1]) + epspri));
4069  d = URMath::Abs(fGstep[i-1])*.2;
4070  if (d > optstp) d = optstp;
4071  if (d < dmin_) d = dmin_;
4072  chgold = 1e4;
4073 //*-*- iterate reducing step size
4074  for (icyc = 1; icyc <= ncyc; ++icyc) {
4075  fX[i-1] = xtf + d;
4076  mninex(fX);
4077 // Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4078  Eval(nparx, fGin, fs1, m_userParameterValue, 4); ++fNfcn;
4079  fX[i-1] = xtf - d;
4080  mninex(fX);
4081 // Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
4082  Eval(nparx, fGin, fs2, m_userParameterValue, 4); ++fNfcn;
4083  fX[i-1] = xtf;
4084 //*-*- check if step sizes appropriate
4085  sag = (fs1 + fs2 - fAmin*2)*.5;
4086  grdold = fGrd[i-1];
4087  grdnew = (fs1 - fs2) / (d*2);
4088  dgmin = fEpsmac*(URMath::Abs(fs1) + URMath::Abs(fs2)) / d;
4089  if (ldebug) {
4090  std::printf("%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g\n",i,idrv,fGstep[i-1],d,fG2[i-1],grdnew,sag);
4091  }
4092  if (grdnew == 0) goto L60;
4093  change = URMath::Abs((grdold - grdnew) / grdnew);
4094  if (change > chgold && icyc > 1) goto L60;
4095  chgold = change;
4096  fGrd[i-1] = grdnew;
4097  if (fGstep[i-1] > 0) fGstep[i-1] = URMath::Abs(d);
4098  else fGstep[i-1] = -URMath::Abs(d);
4099 //*-*- decrease step until first derivative changes by <5%
4100  if (change < .05) goto L60;
4101  if (URMath::Abs(grdold - grdnew) < dgmin) goto L60;
4102  if (d < dmin_) {
4103  mnwarn("D", "MNHES1", "Step size too small for 1st drv.");
4104  goto L60;
4105  }
4106  d *= .2;
4107  }
4108 //*-*- loop satisfied = too many iter
4109  { std::ostringstream warning;
4110  warning << "Too many iterations on D1. " << grdold << " " << grdnew;
4111  mnwarn("D", "MNHES1", warning.str().c_str()); }
4112 L60:
4113  fDgrd[i-1] = URMath::Max(dgmin,URMath::Abs(grdold - grdnew));
4114  }
4115 //*-*- end of first deriv. loop
4116  mninex(fX);
4117 } /* mnhes1_ */
4118 
4119 //______________________________________________________________________________
4121 {
4122 //*-*-*-*-*-*-*Attempts to improve on a good local minimum*-*-*-*-*-*-*-*-*-*
4123 //*-* ===========================================
4124 //*-* Attempts to improve on a good local minimum by finding a
4125 //*-* better one. The quadratic part of FCN is removed by MNCALF
4126 //*-* and this transformed function is minimized using the simplex
4127 //*-* method from several random starting points.
4128 //*-* ref. -- Goldstein and Price, Math.Comp. 25, 569 (1971)
4129 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4130 
4131  /* Initialized data */
4132 
4133  static Double_urt rnum = 0;
4134 
4135  /* Local variables */
4136  Double_urt amax, ycalf, ystar, ystst;
4137  Double_urt pb, ep, wg, xi, sigsav, reg, sig2;
4138  Int_urt npfn, ndex, loop=0, i, j, ifail, iseed;
4139  Int_urt jhold, nloop, nparx, nparp1, jh, jl, iswtr;
4140 
4141  if (fNpar <= 0) return;
4142  if (fAmin == fUndefi) mnamin();
4143  fCstatu = "UNCHANGED ";
4144  fItaur = 1;
4145  fEpsi = fUp*.1;
4146  npfn = fNfcn;
4147  nloop = Int_urt(fWord7[1]);
4148  if (nloop <= 0) nloop = fNpar + 4;
4149  nparx = fNpar;
4150  nparp1 = fNpar + 1;
4151  wg = 1 / Double_urt(fNpar);
4152  sigsav = fEDM;
4153  fApsi = fAmin;
4154  iswtr = fISW[4] - 2*fItaur;
4155  for (i = 1; i <= fNpar; ++i) {
4156  fXt[i-1] = fX[i-1];
4157  fIMPRdsav[i-1] = fWerr[i-1];
4158  for (j = 1; j <= i; ++j) {
4159  ndex = i*(i-1) / 2 + j;
4160  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
4161  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
4162  }
4163  }
4164  mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
4165  if (ifail >= 1) goto L280;
4166 //*-*- Save inverted matrix in VT
4167  for (i = 1; i <= fNpar; ++i) {
4168  ndex = i*(i-1) / 2;
4169  for (j = 1; j <= i; ++j) {
4170  ++ndex;
4171  fVthmat[ndex-1] = fP[i + j*fMaxpar - fMaxpar-1];
4172  }
4173  }
4174  loop = 0;
4175 
4176 L20:
4177  for (i = 1; i <= fNpar; ++i) {
4178  fDirin[i-1] = fIMPRdsav[i-1]*2;
4179  mnrn15(rnum, iseed);
4180  fX[i-1] = fXt[i-1] + fDirin[i-1]*2*(rnum - .5);
4181  }
4182  ++loop;
4183  reg = 2;
4184  if (fISW[4] >= 0) {
4185  std::printf("START ATTEMPT NO.%2d TO FIND NEW MINIMUM\n",loop);
4186  }
4187 L30:
4188  mncalf(fX, ycalf);
4189  fAmin = ycalf;
4190 //*-*- . . . . set up random simplex
4191  jl = nparp1;
4192  jh = nparp1;
4193  fIMPRy[nparp1-1] = fAmin;
4194  amax = fAmin;
4195  for (i = 1; i <= fNpar; ++i) {
4196  xi = fX[i-1];
4197  mnrn15(rnum, iseed);
4198  fX[i-1] = xi - fDirin[i-1]*(rnum - .5);
4199  mncalf(fX, ycalf);
4200  fIMPRy[i-1] = ycalf;
4201  if (fIMPRy[i-1] < fAmin) {
4202  fAmin = fIMPRy[i-1];
4203  jl = i;
4204  } else if (fIMPRy[i-1] > amax) {
4205  amax = fIMPRy[i-1];
4206  jh = i;
4207  }
4208  for (j = 1; j <= fNpar; ++j) { fP[j + i*fMaxpar - fMaxpar-1] = fX[j-1]; }
4209  fP[i + nparp1*fMaxpar - fMaxpar-1] = xi;
4210  fX[i-1] = xi;
4211  }
4212 
4213  fEDM = fAmin;
4214  sig2 = fEDM;
4215 //*-*- . . . . . . . start main loop
4216 L50:
4217  if (fAmin < 0) goto L95;
4218  if (fISW[1] <= 2) goto L280;
4219  ep = fAmin*.1;
4220  if (sig2 < ep && fEDM < ep) goto L100;
4221  sig2 = fEDM;
4222  if (fNfcn - npfn > fNfcnmx) goto L300;
4223 //*-*- calculate new point * by reflection
4224  for (i = 1; i <= fNpar; ++i) {
4225  pb = 0;
4226  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
4227  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
4228  fPstar[i-1] = fPbar[i-1]*2 - fP[i + jh*fMaxpar - fMaxpar-1]*1;
4229  }
4230  mncalf(fPstar, ycalf);
4231  ystar = ycalf;
4232  if (ystar >= fAmin) goto L70;
4233 //*-*- point * better than jl, calculate new point **
4234  for (i = 1; i <= fNpar; ++i) {
4235  fPstst[i-1] = fPstar[i-1]*2 + fPbar[i- 1]*-1;
4236  }
4237  mncalf(fPstst, ycalf);
4238  ystst = ycalf;
4239  if (ystst < fIMPRy[jl-1]) goto L67;
4240  mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4241  goto L50;
4242 L67:
4243  mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4244  goto L50;
4245 //*-*- point * is not as good as jl
4246 L70:
4247  if (ystar >= fIMPRy[jh-1]) goto L73;
4248  jhold = jh;
4249  mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4250  if (jhold != jh) goto L50;
4251 //*-*- calculate new point **
4252 L73:
4253  for (i = 1; i <= fNpar; ++i) {
4254  fPstst[i-1] = fP[i + jh*fMaxpar - fMaxpar-1]*.5 + fPbar[i-1]*.5;
4255  }
4256  mncalf(fPstst, ycalf);
4257  ystst = ycalf;
4258  if (ystst > fIMPRy[jh-1]) goto L30;
4259 //*-*- point ** is better than jh
4260  if (ystst < fAmin) goto L67;
4261  mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4262  goto L50;
4263 //*-*- . . . . . . end main loop
4264 L95:
4265  if (fISW[4] >= 0) {
4266  std::printf(" AN IMPROVEMENT ON THE PREVIOUS MINIMUM HAS BEEN FOUND\n");
4267  }
4268  reg = .1;
4269 //*-*- . . . . . ask if point is new
4270 L100:
4271  mninex(fX);
4272 // Eval(nparx, fGin, fAmin, fU, 4); ++fNfcn;
4273  Eval(nparx, fGin, fAmin, m_userParameterValue, 4); ++fNfcn;
4274  for (i = 1; i <= fNpar; ++i) {
4275  fDirin[i-1] = reg*fIMPRdsav[i-1];
4276  if (URMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L150;
4277  }
4278  goto L230;
4279 L150:
4280  fNfcnmx = fNfcnmx + npfn - fNfcn;
4281  npfn = fNfcn;
4282  mnsimp();
4283  if (fAmin >= fApsi) goto L325;
4284  for (i = 1; i <= fNpar; ++i) {
4285  fDirin[i-1] = fIMPRdsav[i-1]*.1;
4286  if (URMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L250;
4287  }
4288 L230:
4289  if (fAmin < fApsi) goto L350;
4290  goto L325;
4291 /* . . . . . . truly new minimum */
4292 L250:
4293  fLnewmn = kurTRUE;
4294  if (fISW[1] >= 1) {
4295  fISW[1] = 1;
4296  fDcovar = URMath::Max(fDcovar,.5);
4297  } else fDcovar = 1;
4298  fItaur = 0;
4299  fNfcnmx = fNfcnmx + npfn - fNfcn;
4300  fCstatu = "NEW MINIMU";
4301  if (fISW[4] >= 0) {
4302  std::printf(" IMPROVE HAS FOUND A TRULY NEW MINIMUM\n");
4303  std::printf(" *************************************\n");
4304  }
4305  return;
4306 //*-*- . . . return to previous region
4307 L280:
4308  if (fISW[4] > 0) {
4309  std::printf(" COVARIANCE MATRIX WAS NOT POSITIVE-DEFINITE\n");
4310  }
4311  goto L325;
4312 L300:
4313  fISW[0] = 1;
4314 L325:
4315  for (i = 1; i <= fNpar; ++i) {
4316  fDirin[i-1] = fIMPRdsav[i-1]*.01;
4317  fX[i-1] = fXt[i-1];
4318  }
4319  fAmin = fApsi;
4320  fEDM = sigsav;
4321 L350:
4322  mninex(fX);
4323  if (fISW[4] > 0) {
4324  std::printf(" IMPROVE HAS RETURNED TO REGION OF ORIGINAL MINIMUM\n");
4325  }
4326  fCstatu = "UNCHANGED ";
4327  mnrset(0);
4328  if (fISW[1] < 2) goto L380;
4329  if (loop < nloop && fISW[0] < 1) goto L20;
4330 L380:
4331  if (iswtr >= 0) mnprin(5, fAmin);
4332  fItaur = 0;
4333 } /* mnimpr_ */
4334 
4335 //______________________________________________________________________________
4337 {
4338 //*-*-*-*-*Transforms from internal coordinates (PINT) to external (U)*-*-*-*
4339 //*-* ===========================================================
4340 //*-* The minimizing routines which work in
4341 //*-* internal coordinates call this routine before calling FCN.
4342 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4343 
4344  Int_urt i, j;
4345 
4346  for (j = 1; j <= fNpar; ++j) {
4347  i = fNexofi[j-1];
4348 // if (fNvarl[i-1] == 1) {
4349  if (m_userParameterFlag[i] == 1) {
4350 // fU[i-1] = pint[j-1];
4351  m_userParameterValue[i] = pint[j-1];
4352  } else {
4353 // fU[i-1] = fAlim[i-1] + (URMath::Sin(pint[j-1]) + 1)*.5*(fBlim[i-1] - fAlim[i-1]);
4354  m_userParameterValue[i] = fAlim[i-1] + (URMath::Sin(pint[j-1]) + 1)*.5*(fBlim[i-1] - fAlim[i-1]);
4355  }
4356  }
4357 } /* mninex_ */
4358 
4359 //______________________________________________________________________________
4361 {
4362 //*-*-*-*-*-*Main initialization member function for MINUIT*-*-*-*-*-*-*-*-*
4363 //*-* ==============================================
4364 //*-* It initializes some constants
4365 //*-* (including the logical I/O unit nos.),
4366 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4367 
4368  /* Local variables */
4369  Double_urt piby2, epsp1, epsbak, epstry, distnn;
4370  Int_urt i, idb;
4371 
4372 //*-*- I/O unit numbers
4373  fIsysrd = i1;
4374  fIsyswr = i2;
4375  fIstkwr[0] = fIsyswr;
4376  fNstkwr = 1;
4377  fIsyssa = i3;
4378  fNstkrd = 0;
4379 //*-*- version identifier
4380  fCvrsn = "95.03++ ";
4381 //*-*- some CONSTANT
4382  fMaxint = fMaxpar;
4383  fMaxext = 2*fMaxpar;
4384  fUndefi = -54321;
4385  fBigedm = 123456;
4386  fCundef = kUndefinedParameterName; // ")UNDEFINED";
4387  fCovmes[0] = "NO ERROR MATRIX ";
4388  fCovmes[1] = "ERR MATRIX APPROXIMATE";
4389  fCovmes[2] = "ERR MATRIX NOT POS-DEF";
4390  fCovmes[3] = "ERROR MATRIX ACCURATE ";
4391 //*-*- some starting values
4392  fNblock = 0;
4393  fIcomnd = 0;
4394  fCtitl = fCundef;
4395  fCfrom = "INPUT ";
4396  fNfcn = 0;
4397  fNfcnfr = fNfcn;
4398  fCstatu = "INITIALIZE";
4399  fISW[2] = 0;
4400  fISW[3] = 0;
4401  fISW[4] = 1;
4402 //*-*- ISW(6)=0 for batch jobs, =1 for interactive jobs
4403 //*-*- =-1 for originally interactive temporarily batch
4404 
4405  fISW[5] = 0;
4406 // if (intrac(&dummy)) fISW[5] = 1;
4407 //*-*- DEBUG options set to default values
4408  for (idb = 0; idb <= 10; ++idb) { fIdbg[idb] = 0; }
4409  fLrepor = kurFALSE;
4410  fLwarn = kurTRUE;
4411  fLimset = kurFALSE;
4412  fLnewmn = kurFALSE;
4413  fIstrat = 1;
4414  fItaur = 0;
4415 //*-*- default page dimensions and 'new page' carriage control integer
4416  fNpagwd = 120;
4417  fNpagln = 56;
4418  fNewpag = 1;
4419  if (fISW[5] > 0) {
4420  fNpagwd = 80;
4421  fNpagln = 30;
4422  fNewpag = 0;
4423  }
4424  fUp = 1;
4425  fUpdflt = fUp;
4426 //*-*- determine machine accuracy epsmac
4427  epstry = .5;
4428  for (i = 1; i <= 100; ++i) {
4429  epstry *= .5;
4430  epsp1 = epstry + 1;
4431  mntiny(epsp1, epsbak);
4432  if (epsbak < epstry) goto L35;
4433  }
4434  epstry = 1e-7;
4435  fEpsmac = epstry*4;
4436  std::printf(" MNINIT UNABLE TO DETERMINE ARITHMETIC PRECISION. WILL ASSUME:%g\n",fEpsmac);
4437 L35:
4438  fEpsmac = epstry*8;
4440 //*-*- the vlims are a non-negligible distance from pi/2
4441 //*-*- used by MNPINT to set variables "near" the physical limits
4442  piby2 = URMath::ATan(1)*2;
4443  distnn = URMath::Sqrt(fEpsma2)*8;
4444  fVlimhi = piby2 - distnn;
4445  fVlimlo = -piby2 + distnn;
4446  // *m_logStream << "size of m_userParameterName: " << m_userParameterName.size() << endl;
4447  mncler();
4448 // std::printf(" MINUIT RELEASE %s INITIALIZED. DIMENSIONS 100/50 EPSMAC=%g",(const char*)fCvrsn,fEpsmac);
4449 } /* mninit_ */
4450 
4451 //______________________________________________________________________________
4453 {
4454 //*-*-*-*Interprets the SET LIM command, to reset the parameter limits*-*-*-*
4455 //*-* =============================================================
4456 //*-* Called from MNSET
4457 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4458 
4459  /* Local variables */
4460  Double_urt dxdi, snew;
4461  Int_urt kint, i2, newcod, ifx=0, inu;
4462 
4463  fCfrom = "SET LIM ";
4464  fNfcnfr = fNfcn;
4465  fCstatu = "NO CHANGE ";
4466  i2 = Int_urt(fWord7[0]);
4467  if (i2 > fMaxext || i2 < 0) goto L900;
4468  if (i2 > 0) goto L30;
4469 //*-*- set limits on all parameters
4470  newcod = 4;
4471  if (fWord7[1] == fWord7[2]) newcod = 1;
4472  for (inu = 1; inu <= fNu; ++inu) {
4473 // if (fNvarl[inu-1] <= 0) continue;
4474  if (m_userParameterFlag[inu] <= 0) continue;
4475 // if (fNvarl[inu-1] == 1 && newcod == 1) continue;
4476  if (m_userParameterFlag[inu] == 1 && newcod == 1) continue;
4477 // kint = fNiofex[inu-1];
4478  kint = m_userParameterIdToInternalId[inu];
4479 //*-*- see if parameter has been fixed
4480  if (kint <= 0) {
4481  if (fISW[4] >= 0) {
4482  std::printf(" LIMITS NOT CHANGED FOR FIXED PARAMETER:%4d\n",inu);
4483  }
4484  continue;
4485  }
4486  if (newcod == 1) {
4487 //*-*- remove limits from parameter
4488  if (fISW[4] > 0) {
4489  std::printf(" LIMITS REMOVED FROM PARAMETER :%3d\n",inu);
4490  }
4491  fCstatu = "NEW LIMITS";
4492  mndxdi(fX[kint-1], kint-1, dxdi);
4493  snew = fGstep[kint-1]*dxdi;
4494  fGstep[kint-1] = URMath::Abs(snew);
4495 // fNvarl[inu-1] = 1;
4496  m_userParameterFlag[inu] = 1;
4497  } else {
4498 //*-*- put limits on parameter
4499  fAlim[inu-1] = URMath::Min(fWord7[1],fWord7[2]);
4500  fBlim[inu-1] = URMath::Max(fWord7[1],fWord7[2]);
4501  if (fISW[4] > 0) {
4502  std::printf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g\n",inu,fAlim[inu-1],fBlim[inu-1]);
4503  }
4504 // fNvarl[inu-1] = 4;
4505  m_userParameterFlag[inu] = 4;
4506  fCstatu = "NEW LIMITS";
4507  fGstep[kint-1] = -.1;
4508  }
4509  }
4510  goto L900;
4511 //*-*- set limits on one parameter
4512 L30:
4513  //if (fNvarl[i2-1] <= 0) {
4514  if (m_userParameterFlag[i2] <= 0) {
4515  std::printf(" PARAMETER %3d IS NOT VARIABLE.\n", i2);
4516  goto L900;
4517  }
4518 // kint = fNiofex[i2-1];
4519  kint = m_userParameterIdToInternalId[i2];
4520 //*-*- see if parameter was fixed
4521  if (kint == 0) {
4522  std::printf(" REQUEST TO CHANGE LIMITS ON FIXED PARAMETER:%3d\n",i2);
4523  for (ifx = 1; ifx <= fNpfix; ++ifx) {
4524  if (i2 == fIpfix[ifx-1]) goto L92;
4525  }
4526  std::printf(" MINUIT BUG IN MNLIMS. SEE F. JAMES\n");
4527 L92:
4528  ;
4529  }
4530  if (fWord7[1] != fWord7[2]) goto L235;
4531 //*-*- remove limits
4532 // if (fNvarl[i2-1] != 1) {
4533  if (m_userParameterFlag[i2] != 1) {
4534  if (fISW[4] > 0) {
4535  std::printf(" LIMITS REMOVED FROM PARAMETER %2d\n",i2);
4536  }
4537  fCstatu = "NEW LIMITS";
4538  if (kint <= 0) {
4539  fGsteps[ifx-1] = URMath::Abs(fGsteps[ifx-1]);
4540  } else {
4541  mndxdi(fX[kint-1], kint-1, dxdi);
4542  if (URMath::Abs(dxdi) < .01) dxdi = .01;
4543  fGstep[kint-1] = URMath::Abs(fGstep[kint-1]*dxdi);
4544  fGrd[kint-1] *= dxdi;
4545  }
4546 // fNvarl[i2-1] = 1;
4547  m_userParameterFlag[i2] = 1;
4548  } else {
4549  std::printf(" NO LIMITS SPECIFIED. PARAMETER %3d IS ALREADY UNLIMITED. NO CHANGE.\n",i2);
4550  }
4551  goto L900;
4552 //*-*- put on limits
4553 L235:
4554  fAlim[i2-1] = URMath::Min(fWord7[1],fWord7[2]);
4555  fBlim[i2-1] = URMath::Max(fWord7[1],fWord7[2]);
4556 // fNvarl[i2-1] = 4;
4557  m_userParameterFlag[i2] = 4;
4558  if (fISW[4] > 0) {
4559  std::printf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g\n",i2,fAlim[i2-1],fBlim[i2-1]);
4560  }
4561  fCstatu = "NEW LIMITS";
4562  if (kint <= 0) fGsteps[ifx-1] = -.1;
4563  else fGstep[kint-1] = -.1;
4564 
4565 L900:
4566  if (fCstatu != "NO CHANGE ") {
4567  mnexin(fX);
4568  mnrset(1);
4569  }
4570 } /* mnlims_ */
4571 
4572 //______________________________________________________________________________
4573 void URMinuit::mnline(Double_urt *start, Double_urt fstart, Double_urt *step, Double_urt slope, Double_urt toler)
4574 {
4575 //*-*-*-*-*-*-*-*-*-*Perform a line search from position START*-*-*-*-*-*-*-*
4576 //*-* =========================================
4577 //*-* along direction STEP, where the length of vector STEP
4578 //*-* gives the expected position of minimum.
4579 //*-* FSTART is value of function at START
4580 //*-* SLOPE (if non-zero) is df/dx along STEP at START
4581 //*-* TOLER is initial tolerance of minimum in direction STEP
4582 //*-*
4583 //*-* SLAMBG and ALPHA control the maximum individual steps allowed.
4584 //*-* The first step is always =1. The max length of second step is SLAMBG.
4585 //*-* The max size of subsequent steps is the maximum previous successful
4586 //*-* step multiplied by ALPHA + the size of most recent successful step,
4587 //*-* but cannot be smaller than SLAMBG.
4588 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4589 
4590  /* Local variables */
4591  Double_urt xpq[12], ypq[12], slam, sdev, coeff[3], denom, flast;
4592  Double_urt fvals[3], xvals[3], f1, fvmin, xvmin, ratio, f2, f3, fvmax;
4593  Double_urt toler8, toler9, overal, undral, slamin, slamax, slopem;
4594  Int_urt i, nparx=0, nvmax=0, nxypt, kk, ipt;
4595  Bool_urt ldebug;
4596  string cmess;
4597  char chpq[13];
4598  int l65, l70, l80;
4599 
4600  /* Function Body */
4601  l65 = 0; l70 = 0; l80 = 0;
4602  ldebug = fIdbg[1] >= 1;
4603 //*-*- starting values for overall limits on total step SLAM
4604  overal = 1e3;
4605  undral = -100;
4606 //*-*- debug check if start is ok
4607  if (ldebug) {
4608  mninex(&start[0]);
4609 // Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4610  Eval(nparx, fGin, f1, m_userParameterValue, 4); ++fNfcn;
4611  if (f1 != fstart) {
4612  std::printf(" MNLINE start point not consistent, F values, parameters=\n");
4613  for (kk = 1; kk <= fNpar; ++kk) {
4614  std::printf(" %14.5e\n",fX[kk-1]);
4615  }
4616  }
4617  }
4618 //*-*- . set up linear search along STEP
4619  fvmin = fstart;
4620  xvmin = 0;
4621  nxypt = 1;
4622  chpq[0] = charal[0];
4623  xpq[0] = 0;
4624  ypq[0] = fstart;
4625 //*-*- SLAMIN = smallest possible value of ABS(SLAM)
4626  slamin = 0;
4627  for (i = 1; i <= fNpar; ++i) {
4628  if (step[i-1] != 0) {
4629  ratio = URMath::Abs(start[i-1] / step[i-1]);
4630  if (slamin == 0) slamin = ratio;
4631  if (ratio < slamin) slamin = ratio;
4632  }
4633  fX[i-1] = start[i-1] + step[i-1];
4634  }
4635  if (slamin == 0) slamin = fEpsmac;
4636  slamin *= fEpsma2;
4637  nparx = fNpar;
4638 
4639  mninex(fX);
4640 // Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4641  Eval(nparx, fGin, f1, m_userParameterValue, 4); ++fNfcn;
4642  ++nxypt;
4643  chpq[nxypt-1] = charal[nxypt-1];
4644  xpq[nxypt-1] = 1;
4645  ypq[nxypt-1] = f1;
4646  if (f1 < fstart) {
4647  fvmin = f1;
4648  xvmin = 1;
4649  }
4650 //*-*- . quadr interp using slope GDEL and two points
4651  slam = 1;
4652  toler8 = toler;
4653  slamax = 5;
4654  flast = f1;
4655 //*-*- can iterate on two-points (cut) if no imprvmnt
4656 
4657  do {
4658  denom = (flast - fstart - slope*slam)*2 / (slam*slam);
4659  slam = 1;
4660  if (denom != 0) slam = -slope / denom;
4661  if (slam < 0) slam = slamax;
4662  if (slam > slamax) slam = slamax;
4663  if (slam < toler8) slam = toler8;
4664  if (slam < slamin) {
4665  l80 = 1;
4666  break;
4667  }
4668  if (URMath::Abs(slam - 1) < toler8 && f1 < fstart) {
4669  l70 = 1;
4670  break;
4671  }
4672  if (URMath::Abs(slam - 1) < toler8) slam = toler8 + 1;
4673  if (nxypt >= 12) {
4674  l65 = 1;
4675  break;
4676  }
4677  for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4678  mninex(fX);
4679  nparx = fNpar;
4680 // Eval(nparx, fGin, f2, fU, 4); ++fNfcn;
4681  Eval(nparx, fGin, f2, m_userParameterValue, 4); ++fNfcn;
4682  ++nxypt;
4683  chpq[nxypt-1] = charal[nxypt-1];
4684  xpq[nxypt-1] = slam;
4685  ypq[nxypt-1] = f2;
4686  if (f2 < fvmin) {
4687  fvmin = f2;
4688  xvmin = slam;
4689  }
4690  if (fstart == fvmin) {
4691  flast = f2;
4692  toler8 = toler*slam;
4693  overal = slam - toler8;
4694  slamax = overal;
4695  }
4696  } while (fstart == fvmin);
4697 
4698  if (!l65 && !l70 && !l80) {
4699 //*-*- . quadr interp using 3 points
4700  xvals[0] = xpq[0];
4701  fvals[0] = ypq[0];
4702  xvals[1] = xpq[nxypt-2];
4703  fvals[1] = ypq[nxypt-2];
4704  xvals[2] = xpq[nxypt-1];
4705  fvals[2] = ypq[nxypt-1];
4706 //*-*- begin iteration, calculate desired step
4707  do {
4708  slamax = URMath::Max(slamax,URMath::Abs(xvmin)*2);
4709  mnpfit(xvals, fvals, 3, coeff, sdev);
4710  if (coeff[2] <= 0) {
4711  slopem = coeff[2]*2*xvmin + coeff[1];
4712  if (slopem <= 0) slam = xvmin + slamax;
4713  else slam = xvmin - slamax;
4714  } else {
4715  slam = -coeff[1] / (coeff[2]*2);
4716  if (slam > xvmin + slamax) slam = xvmin + slamax;
4717  if (slam < xvmin - slamax) slam = xvmin - slamax;
4718  }
4719  if (slam > 0) { if (slam > overal) slam = overal; }
4720  else { if (slam < undral) slam = undral; }
4721 
4722 //*-*- come here if step was cut below
4723  do {
4724  toler9 = URMath::Max(toler8,URMath::Abs(toler8*slam));
4725  for (ipt = 1; ipt <= 3; ++ipt) {
4726  if (URMath::Abs(slam - xvals[ipt-1]) < toler9) {
4727  l70 = 1;
4728  break;
4729  }
4730  }
4731  if (l70) break;
4732 //*-*- take the step
4733  if (nxypt >= 12) {
4734  l65 = 1;
4735  break;
4736  }
4737  for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4738  mninex(fX);
4739 // Eval(nparx, fGin, f3, fU, 4); ++fNfcn;
4740  Eval(nparx, fGin, f3, m_userParameterValue, 4); ++fNfcn;
4741  ++nxypt;
4742  chpq[nxypt-1] = charal[nxypt-1];
4743  xpq[nxypt-1] = slam;
4744  ypq[nxypt-1] = f3;
4745 //*-*- find worst previous point out of three
4746  fvmax = fvals[0];
4747  nvmax = 1;
4748  if (fvals[1] > fvmax) {
4749  fvmax = fvals[1];
4750  nvmax = 2;
4751  }
4752  if (fvals[2] > fvmax) {
4753  fvmax = fvals[2];
4754  nvmax = 3;
4755  }
4756 //*-*- if latest point worse than all three previous, cut step
4757  if (f3 >= fvmax) {
4758  if (nxypt >= 12) {
4759  l65 = 1;
4760  break;
4761  }
4762  if (slam > xvmin) overal = URMath::Min(overal,slam - toler8);
4763  if (slam < xvmin) undral = URMath::Max(undral,slam + toler8);
4764  slam = (slam + xvmin)*.5;
4765  }
4766  } while (f3 >= fvmax);
4767 
4768 //*-*- prepare another iteration, replace worst previous point
4769  if (l65 || l70) break;
4770 
4771  xvals[nvmax-1] = slam;
4772  fvals[nvmax-1] = f3;
4773  if (f3 < fvmin) {
4774  fvmin = f3;
4775  xvmin = slam;
4776  } else {
4777  if (slam > xvmin) overal = URMath::Min(overal,slam - toler8);
4778  if (slam < xvmin) undral = URMath::Max(undral,slam + toler8);
4779  }
4780  } while (nxypt < 12);
4781  }
4782 
4783 //*-*- . . end of iteration . . .
4784 //*-*- stop because too many iterations
4785  if (!l70 && !l80) {
4786  cmess = " LINE SEARCH HAS EXHAUSTED THE LIMIT OF FUNCTION CALLS ";
4787  if (ldebug) {
4788  std::printf(" MNLINE DEBUG: steps=\n");
4789  for (kk = 1; kk <= fNpar; ++kk) {
4790  std::printf(" %12.4g\n",step[kk-1]);
4791  }
4792  }
4793  }
4794 //*-*- stop because within tolerance
4795  if (l70) cmess = " LINE SEARCH HAS ATTAINED TOLERANCE ";
4796  if (l80) cmess = " STEP SIZE AT ARITHMETICALLY ALLOWED MINIMUM";
4797 
4798  fAmin = fvmin;
4799  for (i = 1; i <= fNpar; ++i) {
4800  fDirin[i-1] = step[i-1]*xvmin;
4801  fX[i-1] = start[i-1] + fDirin[i-1];
4802  }
4803  mninex(fX);
4804  if (xvmin < 0) {
4805  mnwarn("D", "MNLINE", " LINE MINIMUM IN BACKWARDS DIRECTION");
4806  }
4807  if (fvmin == fstart) {
4808  mnwarn("D", "MNLINE", " LINE SEARCH FINDS NO IMPROVEMENT ");
4809  }
4810  if (ldebug) {
4811  std::printf(" AFTER%3d POINTS,%s\n",nxypt,cmess.c_str());
4812  mnplot(xpq, ypq, chpq, nxypt, fNpagwd, fNpagln);
4813  }
4814 } /* mnline_ */
4815 
4816 //______________________________________________________________________________
4818 {
4819 //*-*-*-*-*-*-*-*Prints the covariance matrix v when KODE=1*-*-*-*-*-*-*-*-*
4820 //*-* ==========================================
4821 //*-* always prints the global correlations, and
4822 //*-* calculates and prints the individual correlation coefficients
4823 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4824 
4825  /* Local variables */
4826  Int_urt ndex, i, j, m, n, ncoef, nparm, id, it, ix;
4827  Int_urt nsofar, ndi, ndj, iso, isw2, isw5;
4828  string ctemp;
4829 
4830  isw2 = fISW[1];
4831  if (isw2 < 1) {
4832  std::printf("%s\n",(fCovmes[isw2]).c_str());
4833  return;
4834  }
4835  if (fNpar == 0) {
4836  std::printf(" MNMATU: NPAR=0\n");
4837  return;
4838  }
4839 //*-*- . . . . .external error matrix
4840  if (kode == 1) {
4841  isw5 = fISW[4];
4842  fISW[4] = 2;
4843  mnemat(fP, fMaxint);
4844  if (isw2 < 3) {
4845  std::printf("%s\n",(fCovmes[isw2]).c_str());
4846  }
4847  fISW[4] = isw5;
4848  }
4849 //*-*- . . . . . correlation coeffs. .
4850  if (fNpar <= 1) return;
4851  mnwerr();
4852 //*-*- NCOEF is number of coeff. that fit on one line, not to exceed 20
4853  ncoef = (fNpagwd - 19) / 6;
4854  ncoef = URMath::Min(ncoef,20);
4855  nparm = URMath::Min(fNpar,ncoef);
4856  std::printf(" PARAMETER CORRELATION COEFFICIENTS \n");
4857  ctemp = " NO. GLOBAL";
4858  for (id = 1; id <= nparm; ++id) {
4859  ostringstream localTemp;
4860  localTemp << setw(7) << right << fNexofi[id-1];
4861  ctemp += localTemp.str(); // Form(" %6d",);
4862  }
4863  std::printf("%s\n",ctemp.c_str());
4864  for (i = 1; i <= fNpar; ++i) {
4865  ix = fNexofi[i-1];
4866  ndi = i*(i + 1) / 2;
4867  for (j = 1; j <= fNpar; ++j) {
4868  m = URMath::Max(i,j);
4869  n = URMath::Min(i,j);
4870  ndex = m*(m-1) / 2 + n;
4871  ndj = j*(j + 1) / 2;
4872  fMATUvline[j-1] = fVhmat[ndex-1] / URMath::Sqrt(URMath::Abs(fVhmat[ndi-1]*fVhmat[ndj-1]));
4873  }
4874  nparm = URMath::Min(fNpar,ncoef);
4875  ostringstream octemp;
4876  octemp << setw(7) << right << ix << ": " << fixed << setw(9) << setprecision(3) << fGlobcc[i-1];
4877  ctemp = octemp.str();
4878  for (it = 1; it <= nparm; ++it) {
4879  ostringstream localTemp;
4880  localTemp << fixed << setw(7) << setprecision(3) << fMATUvline[it-1];
4881  ctemp += localTemp.str(); //Form(" %6.3f",);
4882  }
4883  std::printf("%s\n",ctemp.c_str());
4884  if (i <= nparm) continue;
4885  for (iso = 1; iso <= 10; ++iso) {
4886  ctemp = " ";
4887  nsofar = nparm;
4888  nparm = URMath::Min(fNpar,nsofar + ncoef);
4889  for (it = nsofar + 1; it <= nparm; ++it) {
4890  ostringstream localTemp;
4891  localTemp << fixed << setw(7) << setprecision(3) << fMATUvline[it-1];
4892  ctemp = ctemp + localTemp.str(); // Form(" %6.3f",fMATUvline[it-1]);
4893  }
4894  std::printf("%s\n",ctemp.c_str());
4895  if (i <= nparm) break;
4896  }
4897  }
4898  if (isw2 < 3) {
4899  std::printf(" %s\n",(fCovmes[isw2]).c_str());
4900  }
4901 } /* mnmatu_ */
4902 
4903 //______________________________________________________________________________
4905 {
4906 //*-*-*-*-*-*-*-*-*Performs a local function minimization*-*-*-*-*-*-*-*-*-*
4907 //*-* ======================================
4908 //*-* Performs a local function minimization using basically the
4909 //*-* method of Davidon-Fletcher-Powell as modified by Fletcher
4910 //*-* ref. -- Fletcher, Comp.J. 13,317 (1970) "switching method"
4911 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4912 
4913  /* Local variables */
4914  Double_urt gdel, gami, vlen, dsum, gssq, vsum, d;
4915  Double_urt fzero, fs, ri, delgam, rhotol;
4916  Double_urt gdgssq, gvg, vgi;
4917  Int_urt npfn, ndex, iext, i, j, m, n, npsdf, nparx;
4918  Int_urt iswtr, lined2, kk, nfcnmg, nrstrt,iter;
4919  Bool_urt ldebug;
4920  Double_urt toler = 0.05;
4921 
4922  if (fNpar <= 0) return;
4923  if (fAmin == fUndefi) mnamin();
4924  ldebug = kurFALSE; if ( fIdbg[4] >= 1) ldebug = kurTRUE;
4925  fCfrom = "MIGRAD ";
4926  fNfcnfr = fNfcn;
4927  nfcnmg = fNfcn;
4928  fCstatu = "INITIATE ";
4929  iswtr = fISW[4] - 2*fItaur;
4930  npfn = fNfcn;
4931  nparx = fNpar;
4932  vlen = (Double_urt) (fNpar*(fNpar + 1) / 2);
4933  nrstrt = 0;
4934  npsdf = 0;
4935  lined2 = 0;
4936  fISW[3] = -1;
4937  rhotol = fApsi*.001;
4938  if (iswtr >= 1) {
4939  std::printf(" START MIGRAD MINIMIZATION. STRATEGY%2d. CONVERGENCE WHEN EDM .LT.%9.2e\n",fIstrat,rhotol);
4940  }
4941 //*-*- initialization strategy
4942  if (fIstrat < 2 || fISW[1] >= 3) goto L2;
4943 //*-*- come (back) here to restart completely
4944 L1:
4945  if (nrstrt > fIstrat) {
4946  fCstatu = "FAILED ";
4947  fISW[3] = -1;
4948  goto L230;
4949  }
4950 //*-*- . get full covariance and gradient
4951  mnhess();
4952  mnwerr();
4953  npsdf = 0;
4954  if (fISW[1] >= 1) goto L10;
4955 //*-*- . get gradient at start point
4956 L2:
4957  mninex(fX);
4958  if (fISW[2] == 1) {
4959 // Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
4960  Eval(nparx, fGin, fzero, m_userParameterValue, 2); ++fNfcn;
4961  }
4962  mnderi();
4963  if (fISW[1] >= 1) goto L10;
4964 //*-*- sometimes start with diagonal matrix
4965  for (i = 1; i <= fNpar; ++i) {
4966  fMIGRxxs[i-1] = fX[i-1];
4967  fMIGRstep[i-1] = 0;
4968  }
4969 //*-*- do line search if second derivative negative
4970  ++lined2;
4971  if (lined2 < (fIstrat + 1)*fNpar) {
4972  for (i = 1; i <= fNpar; ++i) {
4973  if (fG2[i-1] > 0) continue;
4974  if (fGrd[i-1] > 0) fMIGRstep[i-1] = -URMath::Abs(fGstep[i-1]);
4975  else fMIGRstep[i-1] = URMath::Abs(fGstep[i-1]);
4976  gdel = fMIGRstep[i-1]*fGrd[i-1];
4977  fs = fAmin;
4978  mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
4979  mnwarn("D", "MNMIGR", "Negative G2 line search");
4980  iext = fNexofi[i-1];
4981  if (ldebug) {
4982  std::printf(" Negative G2 line search, param %3d %13.3g%13.3g\n",iext,fs,fAmin);
4983  }
4984  goto L2;
4985  }
4986  }
4987 //*-*- make diagonal error matrix
4988  for (i = 1; i <= fNpar; ++i) {
4989  ndex = i*(i-1) / 2;
4990  for (j = 1; j <= i-1; ++j) {
4991  ++ndex;
4992  fVhmat[ndex-1] = 0;
4993  }
4994  ++ndex;
4995  if (fG2[i-1] <= 0) fG2[i-1] = 1;
4996  fVhmat[ndex-1] = 2 / fG2[i-1];
4997  }
4998  fDcovar = 1;
4999  if (ldebug) {
5000  std::printf(" DEBUG MNMIGR, STARTING MATRIX DIAGONAL, VHMAT=\n");
5001  for (kk = 1; kk <= Int_urt(vlen); ++kk) {
5002  std::printf(" %10.2g\n",fVhmat[kk-1]);
5003  }
5004  }
5005 //*-*- ready to start first iteration
5006 L10:
5007  ++nrstrt;
5008  if (nrstrt > fIstrat + 1) {
5009  fCstatu = "FAILED ";
5010  goto L230;
5011  }
5012  fs = fAmin;
5013 //*-*- . . . get EDM and set up loop
5014  fEDM = 0;
5015  for (i = 1; i <= fNpar; ++i) {
5016  fMIGRgs[i-1] = fGrd[i-1];
5017  fMIGRxxs[i-1] = fX[i-1];
5018  ndex = i*(i-1) / 2;
5019  for (j = 1; j <= i-1; ++j) {
5020  ++ndex;
5021  fEDM += fMIGRgs[i-1]*fVhmat[ndex-1]*fMIGRgs[j-1];
5022  }
5023  ++ndex;
5024  fEDM += fMIGRgs[i-1]*fMIGRgs[i-1]*.5*fVhmat[ndex-1];
5025  }
5026  fEDM = fEDM*.5*(fDcovar*3 + 1);
5027  if (fEDM < 0) {
5028  mnwarn("W", "MIGRAD", "STARTING MATRIX NOT POS-DEFINITE.");
5029  fISW[1] = 0;
5030  fDcovar = 1;
5031  goto L2;
5032  }
5033  if (fISW[1] == 0) fEDM = fBigedm;
5034  iter = 0;
5035  mninex(fX);
5036  mnwerr();
5037  if (iswtr >= 1) mnprin(3, fAmin);
5038  if (iswtr >= 2) mnmatu(0);
5039 //*-*- . . . . . start main loop
5040 L24:
5041  if (fNfcn - npfn >= fNfcnmx) goto L190;
5042  gdel = 0;
5043  gssq = 0;
5044  for (i = 1; i <= fNpar; ++i) {
5045  ri = 0;
5046  gssq += fMIGRgs[i-1]*fMIGRgs[i-1];
5047  for (j = 1; j <= fNpar; ++j) {
5048  m = URMath::Max(i,j);
5049  n = URMath::Min(i,j);
5050  ndex = m*(m-1) / 2 + n;
5051  ri += fVhmat[ndex-1]*fMIGRgs[j-1];
5052  }
5053  fMIGRstep[i-1] = ri*-.5;
5054  gdel += fMIGRstep[i-1]*fMIGRgs[i-1];
5055  }
5056  if (gssq == 0) {
5057  mnwarn("D", "MIGRAD", " FIRST DERIVATIVES OF FCN ARE ALL ZERO");
5058  goto L300;
5059  }
5060 //*-*- if gdel positive, V not posdef
5061  if (gdel >= 0) {
5062  mnwarn("D", "MIGRAD", " NEWTON STEP NOT DESCENT.");
5063  if (npsdf == 1) goto L1;
5064  mnpsdf();
5065  npsdf = 1;
5066  goto L24;
5067  }
5068 //*-*- . . . . do line search
5069  mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
5070  if (fAmin == fs) goto L200;
5071  fCfrom = "MIGRAD ";
5072  fNfcnfr = nfcnmg;
5073  fCstatu = "PROGRESS ";
5074 //*-*- . get gradient at new point
5075  mninex(fX);
5076  if (fISW[2] == 1) {
5077 // Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
5078  Eval(nparx, fGin, fzero, m_userParameterValue, 2); ++fNfcn;
5079  }
5080  mnderi();
5081 //*-*- . calculate new EDM
5082  npsdf = 0;
5083 L81:
5084  fEDM = 0;
5085  gvg = 0;
5086  delgam = 0;
5087  gdgssq = 0;
5088  for (i = 1; i <= fNpar; ++i) {
5089  ri = 0;
5090  vgi = 0;
5091  for (j = 1; j <= fNpar; ++j) {
5092  m = URMath::Max(i,j);
5093  n = URMath::Min(i,j);
5094  ndex = m*(m-1) / 2 + n;
5095  vgi += fVhmat[ndex-1]*(fGrd[j-1] - fMIGRgs[j-1]);
5096  ri += fVhmat[ndex-1]*fGrd[j-1];
5097  }
5098  fMIGRvg[i-1] = vgi*.5;
5099  gami = fGrd[i-1] - fMIGRgs[i-1];
5100  gdgssq += gami*gami;
5101  gvg += gami*fMIGRvg[i-1];
5102  delgam += fDirin[i-1]*gami;
5103  fEDM += fGrd[i-1]*ri*.5;
5104  }
5105  fEDM = fEDM*.5*(fDcovar*3 + 1);
5106 //*-*- . if EDM negative, not positive-definite
5107  if (fEDM < 0 || gvg <= 0) {
5108  mnwarn("D", "MIGRAD", "NOT POS-DEF. EDM OR GVG NEGATIVE.");
5109  fCstatu = "NOT POSDEF";
5110  if (npsdf == 1) goto L230;
5111  mnpsdf();
5112  npsdf = 1;
5113  goto L81;
5114  }
5115 //*-*- print information about this iteration
5116  ++iter;
5117  if (iswtr >= 3 || ( iswtr == 2 && iter % 10 == 1 ) ) {
5118  mnwerr();
5119  mnprin(3, fAmin);
5120  }
5121  if (gdgssq == 0) {
5122  mnwarn("D", "MIGRAD", "NO CHANGE IN FIRST DERIVATIVES OVER LAST STEP");
5123  }
5124  if (delgam < 0) {
5125  mnwarn("D", "MIGRAD", "FIRST DERIVATIVES INCREASING ALONG SEARCH LINE");
5126  }
5127 //*-*- . update covariance matrix
5128  fCstatu = "IMPROVEMNT";
5129  if (ldebug) {
5130  std::printf(" VHMAT 1 =\n");
5131  for (kk = 1; kk <= 10; ++kk) {
5132  std::printf(" %10.2g\n",fVhmat[kk-1]);
5133  }
5134  }
5135  dsum = 0;
5136  vsum = 0;
5137  for (i = 1; i <= fNpar; ++i) {
5138  for (j = 1; j <= i; ++j) {
5139  if(delgam == 0 || gvg == 0) d = 0;
5140  else d = fDirin[i-1]*fDirin[j-1] / delgam - fMIGRvg[i-1]*fMIGRvg[j-1] / gvg;
5141  dsum += URMath::Abs(d);
5142  ndex = i*(i-1) / 2 + j;
5143  fVhmat[ndex-1] += d*2;
5144  vsum += URMath::Abs(fVhmat[ndex-1]);
5145  }
5146  }
5147 //*-*- smooth local fluctuations by averaging DCOVAR
5148  fDcovar = (fDcovar + dsum / vsum)*.5;
5149  if (iswtr >= 3 || ldebug) {
5150  std::printf(" RELATIVE CHANGE IN COV. MATRIX=%5.1f per cent\n",fDcovar*100);
5151  }
5152  if (ldebug) {
5153  std::printf(" VHMAT 2 =\n");
5154  for (kk = 1; kk <= 10; ++kk) {
5155  std::printf(" %10.3g\n",fVhmat[kk-1]);
5156  }
5157  }
5158  if (delgam <= gvg) goto L135;
5159  for (i = 1; i <= fNpar; ++i) {
5160  fMIGRflnu[i-1] = fDirin[i-1] / delgam - fMIGRvg[i-1] / gvg;
5161  }
5162  for (i = 1; i <= fNpar; ++i) {
5163  for (j = 1; j <= i; ++j) {
5164  ndex = i*(i-1) / 2 + j;
5165  fVhmat[ndex-1] += gvg*2*fMIGRflnu[i-1]*fMIGRflnu[j-1];
5166  }
5167  }
5168 L135:
5169 //*-*- and see if converged
5170  if (fEDM < rhotol*.1) goto L300;
5171 //*-*- if not, prepare next iteration
5172  for (i = 1; i <= fNpar; ++i) {
5173  fMIGRxxs[i-1] = fX[i-1];
5174  fMIGRgs[i-1] = fGrd[i-1];
5175  }
5176  fs = fAmin;
5177  if (fISW[1] == 0 && fDcovar < .5) fISW[1] = 1;
5178  if (fISW[1] == 3 && fDcovar > .1) fISW[1] = 1;
5179  if (fISW[1] == 1 && fDcovar < .05) fISW[1] = 3;
5180  goto L24;
5181 //*-*- . . . . . end main loop
5182 //*-*- . . call limit in MNMIGR
5183 L190:
5184  fISW[0] = 1;
5185  if (fISW[4] >= 0) {
5186  std::printf(" CALL LIMIT EXCEEDED IN MIGRAD.\n");
5187  }
5188  fCstatu = "CALL LIMIT";
5189  goto L230;
5190 //*-*- . . fails to improve . .
5191 L200:
5192  if (iswtr >= 1) {
5193  std::printf(" MIGRAD FAILS TO FIND IMPROVEMENT\n");
5194  }
5195  for (i = 1; i <= fNpar; ++i) { fX[i-1] = fMIGRxxs[i-1]; }
5196  if (fEDM < rhotol) goto L300;
5197  if (fEDM < URMath::Abs(fEpsma2*fAmin)) {
5198  if (iswtr >= 0) {
5199  std::printf(" MACHINE ACCURACY LIMITS FURTHER IMPROVEMENT.\n");
5200  }
5201  goto L300;
5202  }
5203  if (fIstrat < 1) {
5204  if (fISW[4] >= 0) {
5205  std::printf(" MIGRAD FAILS WITH STRATEGY=0. WILL TRY WITH STRATEGY=1.\n");
5206  }
5207  fIstrat = 1;
5208  }
5209  goto L1;
5210 //*-*- . . fails to converge
5211 L230:
5212  if (iswtr >= 0) {
5213  std::printf(" MIGRAD TERMINATED WITHOUT CONVERGENCE.\n");
5214  }
5215  if (fISW[1] == 3) fISW[1] = 1;
5216  fISW[3] = -1;
5217  goto L400;
5218 //*-*- . . apparent convergence
5219 L300:
5220  if (iswtr >= 0) {
5221  std::printf(" MIGRAD MINIMIZATION HAS CONVERGED.\n");
5222  }
5223  if (fItaur == 0) {
5224  if (fIstrat >= 2 || (fIstrat == 1 && fISW[1] < 3)) {
5225  if (fISW[4] >= 0) {
5226  std::printf(" MIGRAD WILL VERIFY CONVERGENCE AND ERROR MATRIX.\n");
5227  }
5228  mnhess();
5229  mnwerr();
5230  npsdf = 0;
5231  if (fEDM > rhotol) goto L10;
5232  }
5233  }
5234  fCstatu = "CONVERGED ";
5235  fISW[3] = 1;
5236 //*-*- come here in any case
5237 L400:
5238  fCfrom = "MIGRAD ";
5239  fNfcnfr = nfcnmg;
5240  mninex(fX);
5241  mnwerr();
5242  if (iswtr >= 0) mnprin(3, fAmin);
5243  if (iswtr >= 1) mnmatu(1);
5244 } /* mnmigr_ */
5245 
5246 //______________________________________________________________________________
5248 {
5249 //*-*-*-*-*-*-*-*-*-*-*Performs a MINOS error analysis*-*-*-*-*-*-*-*-*-*-*-*
5250 //*-* ===============================
5251 //*-* Performs a MINOS error analysis on those parameters for
5252 //*-* which it is requested on the MINOS command by calling
5253 //*-* MNMNOT for each parameter requested.
5254 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5255 
5256  /* Local variables */
5257  Double_urt val2mi, val2pl;
5258  Int_urt nbad, ilax, ilax2, ngood, nfcnmi, iin, knt;
5259 
5260  if (fNpar <= 0) goto L700;
5261  ngood = 0;
5262  nbad = 0;
5263  nfcnmi = fNfcn;
5264 //*-*- . loop over parameters requested
5265  for (knt = 1; knt <= fNpar; ++knt) {
5266  if (Int_urt(fWord7[1]) == 0) {
5267  ilax = fNexofi[knt-1];
5268  } else {
5269  if (knt >= 7) break;
5270  ilax = Int_urt(fWord7[knt]);
5271  if (ilax == 0) break;
5272  if (ilax > 0 && ilax <= fNu) {
5273 // if (fNiofex[ilax-1] > 0) goto L565;
5274  if (m_userParameterIdToInternalId[ilax] > 0) goto L565;
5275  }
5276  std::printf(" PARAMETER NUMBER %3d NOT VARIABLE. IGNORED.\n",ilax);
5277  continue;
5278  }
5279 L565:
5280 //*-*- calculate one pair of M E s
5281  ilax2 = 0;
5282  mnmnot(ilax, ilax2, val2pl, val2mi);
5283  if (fLnewmn) goto L650;
5284 //*-*- update NGOOD and NBAD
5285 // iin = fNiofex[ilax-1];
5286  iin = m_userParameterIdToInternalId[ilax];
5287  if (fErp[iin-1] > 0) ++ngood;
5288  else ++nbad;
5289  if (fErn[iin-1] < 0) ++ngood;
5290  else ++nbad;
5291  }
5292 //*-*- end of loop . . . . . . .
5293 //*-*- . . . . printout final values .
5294  fCfrom = "MINOS ";
5295  fNfcnfr = nfcnmi;
5296  fCstatu = "UNCHANGED ";
5297  if (ngood == 0 && nbad == 0) goto L700;
5298  if (ngood > 0 && nbad == 0) fCstatu = "SUCCESSFUL";
5299  if (ngood == 0 && nbad > 0) fCstatu = "FAILURE ";
5300  if (ngood > 0 && nbad > 0) fCstatu = "PROBLEMS ";
5301  if (fISW[4] >= 0) mnprin(4, fAmin);
5302  if (fISW[4] >= 2) mnmatu(0);
5303  return;
5304 //*-*- . . . new minimum found . . . .
5305 L650:
5306  fCfrom = "MINOS ";
5307  fNfcnfr = nfcnmi;
5308  fCstatu = "NEW MINIMU";
5309  if (fISW[4] >= 0) mnprin(4, fAmin);
5310  std::printf(" NEW MINIMUM FOUND. GO BACK TO MINIMIZATION STEP.\n");
5311  std::printf(" =================================================\n");
5312  std::printf(" V\n");
5313  std::printf(" V\n");
5314  std::printf(" V\n");
5315  std::printf(" VVVVVVV\n");
5316  std::printf(" VVVVV\n");
5317  std::printf(" VVV\n");
5318  std::printf(" V\n");
5319  std::printf("\n");
5320  return;
5321 L700:
5322  std::printf(" THERE ARE NO MINOS ERRORS TO CALCULATE.\n");
5323 } /* mnmnos_ */
5324 
5325 //______________________________________________________________________________
5326 void URMinuit::mnmnot(Int_urt ilax, Int_urt ilax2, Double_urt &val2pl, Double_urt &val2mi)
5327 {
5328 //*-*-*-*-*-*Performs a MINOS error analysis on one parameter*-*-*-*-*-*-*-*-*
5329 //*-* ================================================
5330 //*-* The parameter ILAX is varied, and the minimum of the
5331 //*-* function with respect to the other parameters is followed
5332 //*-* until it crosses the value FMIN+UP.
5333 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5334 
5335  /* System generated locals */
5336  Int_urt i__1;
5337 
5338  /* Local variables */
5339  Double_urt delu, aopt, eros;
5340  Double_urt abest, xunit, dc, ut, sigsav, du1;
5341  Double_urt fac, sig, sav;
5342  Int_urt marc, isig, mpar, ndex, imax, indx, ierr, i, j;
5343  Int_urt iercr, it, istrav, nfmxin, nlimit, isw2, isw4;
5344  string csig;
5345 
5346 //*-*- . . save and prepare start vals
5347  isw2 = fISW[1];
5348  isw4 = fISW[3];
5349  sigsav = fEDM;
5350  istrav = fIstrat;
5351  dc = fDcovar;
5352  fLnewmn = kurFALSE;
5353  fApsi = fEpsi*.5;
5354  abest = fAmin;
5355  mpar = fNpar;
5356  nfmxin = fNfcnmx;
5357  for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
5358  i__1 = mpar*(mpar + 1) / 2;
5359  for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
5360  for (i = 1; i <= mpar; ++i) {
5361  fMNOTgcc[i-1] = fGlobcc[i-1];
5362  fMNOTw[i-1] = fWerr[i-1];
5363  }
5364 // it = fNiofex[ilax-1];
5365  it = m_userParameterIdToInternalId[ilax];
5366  fErp[it-1] = 0;
5367  fErn[it-1] = 0;
5368  mninex(fXt);
5369 // ut = fU[ilax-1];
5370 // if (fNvarl[ilax-1] == 1) {
5371  ut = m_userParameterValue[ilax];
5372  if (m_userParameterFlag[ilax] == 1) {
5373  fAlim[ilax-1] = ut - fMNOTw[it-1]*100;
5374  fBlim[ilax-1] = ut + fMNOTw[it-1]*100;
5375  }
5376  ndex = it*(it + 1) / 2;
5377  xunit = URMath::Sqrt(fUp / fVthmat[ndex-1]);
5378  marc = 0;
5379  for (i = 1; i <= mpar; ++i) {
5380  if (i == it) continue;
5381  ++marc;
5382  imax = URMath::Max(it,i);
5383  indx = imax*(imax-1) / 2 + URMath::Min(it,i);
5384  fMNOTxdev[marc-1] = xunit*fVthmat[indx-1];
5385  }
5386 //*-*- fix the parameter in question
5387  mnfixp(it-1, ierr);
5388  if (ierr > 0) {
5389  std::printf(" MINUIT ERROR. CANNOT FIX PARAMETER%4d INTERNAL%3d\n",ilax,it);
5390  goto L700;
5391  }
5392 //*-*- . . . . . Nota Bene: from here on, NPAR=MPAR-1
5393 //*-*- Remember: MNFIXP squeezes IT out of X, XT, WERR, and VHMAT,
5394 //*-*- not W, VTHMAT
5395  for (isig = 1; isig <= 2; ++isig) {
5396  if (isig == 1) {
5397  sig = 1;
5398  csig = "POSI";
5399  } else {
5400  sig = -1;
5401  csig = "NEGA";
5402  }
5403 //*-*- . sig=sign of error being calcd
5404  if (fISW[4] > 1) {
5405 // std::printf(" DETERMINATION OF %sTIVE MINOS ERROR FOR PARAMETER%d\n"
5406 // ,csig.c_str(),ilax
5407 // ,(fCpnam[ilax-1]).c_str());
5408 
5409  std::printf(" DETERMINATION OF %sTIVE MINOS ERROR FOR PARAMETER%d (%s)\n"
5410  ,csig.c_str(),ilax
5411  ,(m_userParameterName[ilax]).c_str());
5412  }
5413  if (fISW[1] <= 0) {
5414  mnwarn("D", "MINOS", "NO COVARIANCE MATRIX.");
5415  }
5416  nlimit = fNfcn + nfmxin;
5417  fIstrat = URMath::Max(istrav-1,0);
5418  du1 = fMNOTw[it-1];
5419 // fU[ilax-1] = ut + sig*du1;
5420 // fU[ilax-1] = URMath::Min(fU[ilax-1],fBlim[ilax-1]);
5421 // fU[ilax-1] = URMath::Max(fU[ilax-1],fAlim[ilax-1]);
5422  m_userParameterValue[ilax] = ut + sig*du1;
5423  m_userParameterValue[ilax] = URMath::Min(m_userParameterValue[ilax],fBlim[ilax-1]);
5424  m_userParameterValue[ilax] = URMath::Max(m_userParameterValue[ilax],fAlim[ilax-1]);
5425 // delu = fU[ilax-1] - ut;
5426  delu = m_userParameterValue[ilax] - ut;
5427 //*-*- stop if already at limit with negligible step size
5428 // if (URMath::Abs(delu) / (URMath::Abs(ut) + URMath::Abs(fU[ilax-1])) < fEpsmac) goto L440;
5429  if (URMath::Abs(delu) / (URMath::Abs(ut) + URMath::Abs(m_userParameterValue[ilax])) < fEpsmac) goto L440;
5430  fac = delu / fMNOTw[it-1];
5431  for (i = 1; i <= fNpar; ++i) {
5432  fX[i-1] = fXt[i-1] + fac*fMNOTxdev[i-1];
5433  }
5434  if (fISW[4] > 1) {
5435 // std::printf(" PARAMETER%4d SET TO%11.3e + %10.3e = %12.3e\n",ilax,ut,delu,fU[ilax-1]);
5436  std::printf(" PARAMETER%4d SET TO%11.3e + %10.3e = %12.3e\n",ilax,ut,delu,m_userParameterValue[ilax]);
5437  }
5438 //*-*- loop to hit AMIN+UP
5439  fKe1cr = ilax;
5440  fKe2cr = 0;
5441 // fXmidcr = fU[ilax-1];
5442  fXmidcr = m_userParameterValue[ilax];
5443  fXdircr = delu;
5444 
5445  fAmin = abest;
5446  fNfcnmx = nlimit - fNfcn;
5447  mncros(aopt, iercr);
5448  if (abest - fAmin > fUp*.01) goto L650;
5449  if (iercr == 1) goto L440;
5450  if (iercr == 2) goto L450;
5451  if (iercr == 3) goto L460;
5452 //*-*- . error successfully calculated
5453  eros = fXmidcr - ut + aopt*fXdircr;
5454  if (fISW[4] > 1) {
5455 // std::printf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d %10s, IS %12.4e\n"
5456 // ,csig.c_str(),ilax
5457 // ,(fCpnam[ilax-1]).c_str(),eros);
5458  std::printf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d %10s, IS %12.4e\n"
5459  ,csig.c_str(),ilax
5460  ,(m_userParameterName[ilax]).c_str(),eros);
5461  }
5462  goto L480;
5463 //*-*- . . . . . . . . failure returns
5464 L440:
5465  if (fISW[4] >= 1) {
5466 // std::printf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d, %s EXCEEDS ITS LIMIT.\n"
5467 // ,csig.c_str(),ilax
5468 // ,(fCpnam[ilax-1]).c_str());
5469  std::printf(" THE %4sTIVE MINOS ERROR OF PARAMETER%3d, %s EXCEEDS ITS LIMIT.\n"
5470  ,csig.c_str(),ilax
5471  ,(m_userParameterName[ilax]).c_str());
5472  }
5473  eros = fUndefi;
5474  goto L480;
5475 L450:
5476  if (fISW[4] >= 1) {
5477  std::printf(" THE %4sTIVE MINOS ERROR%4d REQUIRES MORE THAN%5d FUNCTION CALLS.\n"
5478  ,csig.c_str(),ilax,nfmxin);
5479  }
5480  eros = 0;
5481  goto L480;
5482 L460:
5483  if (fISW[4] >= 1) {
5484  std::printf(" %4sTIVE MINOS ERROR NOT CALCULATED FOR PARAMETER%d\n"
5485  ,csig.c_str(),ilax);
5486  }
5487  eros = 0;
5488 
5489 L480:
5490  if (fISW[4] > 1) {
5491  std::printf(" **************************************************************************\n");
5492  }
5493  if (sig < 0) {
5494  fErn[it-1] = eros;
5495 // if (ilax2 > 0 && ilax2 <= fNu) val2mi = fU[ilax2-1];
5496  if (ilax2 > 0 && ilax2 <= fNu) val2mi = m_userParameterValue[ilax2];
5497  } else {
5498  fErp[it-1] = eros;
5499 // if (ilax2 > 0 && ilax2 <= fNu) val2pl = fU[ilax2-1];
5500  if (ilax2 > 0 && ilax2 <= fNu) val2pl = m_userParameterValue[ilax2];
5501  }
5502  }
5503 //*-*- . . parameter finished. reset v
5504 //*-*- normal termination */
5505  fItaur = 1;
5506  mnfree(1);
5507  i__1 = mpar*(mpar + 1) / 2;
5508  for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
5509  for (i = 1; i <= mpar; ++i) {
5510  fWerr[i-1] = fMNOTw[i-1];
5511  fGlobcc[i-1] = fMNOTgcc[i-1];
5512  fX[i-1] = fXt[i-1];
5513  }
5514  mninex(fX);
5515  fEDM = sigsav;
5516  fAmin = abest;
5517  fISW[1] = isw2;
5518  fISW[3] = isw4;
5519  fDcovar = dc;
5520  goto L700;
5521 //*-*- new minimum
5522 L650:
5523  fLnewmn = kurTRUE;
5524  fISW[1] = 0;
5525  fDcovar = 1;
5526  fISW[3] = 0;
5527 // sav = fU[ilax-1];
5528  sav = m_userParameterValue[ilax];
5529  fItaur = 1;
5530  mnfree(1);
5531 // fU[ilax-1] = sav;
5532  m_userParameterValue[ilax] = sav;
5533  mnexin(fX);
5534  fEDM = fBigedm;
5535 //*-*- in any case
5536 L700:
5537  fItaur = 0;
5538  fNfcnmx = nfmxin;
5539  fIstrat = istrav;
5540 } /* mnmnot_ */
5541 
5542 //______________________________________________________________________________
5543 void URMinuit::mnparm(Int_urt k1, const string& cnamj, Double_urt uk, Double_urt wk, Double_urt a, Double_urt b, Int_urt &ierflg)
5544 {
5545 //*-*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-*
5546 //*-* ===================================
5547 //*-* Called from MNPARS and user-callable
5548 //*-* Implements one parameter definition, that is:
5549 //*-* K (external) parameter number
5550 //*-* CNAMK parameter name
5551 //*-* UK starting value
5552 //*-* WK starting step size or uncertainty
5553 //*-* A, B lower and upper physical parameter limits
5554 //*-* and sets up (updates) the parameter lists.
5555 //*-* Output: IERFLG=0 if no problems
5556 //*-* >0 if MNPARM unable to implement definition
5557 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5558 
5559  /* Local variables */
5560  Double_urt vplu, a_small, gsmin, pinti, vminu, danger, sav, sav2;
5561  Int_urt ierr, kint, in, ix, ktofix, lastin, kinfix, nvl;
5562  string cnamk, chbufi;
5563 
5564 // Int_urt k = k1+1;
5565  Int_urt k = k1;
5566  cnamk = cnamj;
5567  kint = fNpar;
5568  if (k < 1 || k > fMaxext) {
5569 //*-*- parameter number exceeds allowed maximum value
5570  //std::printf(" MINUIT USER ERROR. PARAMETER NUMBER IS %3d ALLOWED RANGE IS ONE TO %4d\n",k,fMaxext);
5571  *m_logStream << " MINUIT USER ERROR. PARAMETER NUMBER IS " << setw(3) << k
5572  << " ALLOWED RANGE IS ONE TO " << setw(4) << fMaxext << '\n';
5573  goto L800;
5574  }
5575 //*-*- normal parameter request
5576  ktofix = 0;
5577 // if (fNvarl[k-1] < 0) goto L50;
5578  if (m_userParameterFlag[k] < 0) goto L50;
5579 //*-*- previously defined parameter is being redefined
5580 //*-*- find if parameter was fixed
5581  for (ix = 1; ix <= fNpfix; ++ix) {
5582  if (fIpfix[ix-1] == k) ktofix = k;
5583  }
5584  if (ktofix > 0) {
5585  mnwarn("W", "PARAM DEF", "REDEFINING A FIXED PARAMETER.");
5586  if (kint >= fMaxint) {
5587  //std::printf(" CANNOT RELEASE. MAX NPAR EXCEEDED.\n");
5588  *m_logStream << " CANNOT RELEASE. MAX NPAR EXCEEDED.\n";
5589  goto L800;
5590  }
5591  mnfree(-k);
5592  }
5593 //*-*- if redefining previously variable parameter
5594 // if (fNiofex[k-1] > 0) kint = fNpar - 1;
5595  if (m_userParameterIdToInternalId[k] > 0) kint = fNpar - 1;
5596 L50:
5597 
5598 //*-*- . . .print heading
5599  if (fLphead && fISW[4] >= 0) {
5600  //std::printf(" PARAMETER DEFINITIONS:\n");
5601  //std::printf(" NO. NAME VALUE STEP SIZE LIMITS\n");
5602  *m_logStream << " PARAMETER DEFINITIONS:\n";
5603  *m_logStream << " NO. NAME VALUE STEP SIZE LIMITS\n";
5604  fLphead = kurFALSE;
5605  }
5606  if (wk > 0) goto L122;
5607 //*-*- . . .constant parameter . . . .
5608  if (fISW[4] >= 0) {
5609  //std::printf(" %5d %-10s %13.5e constant\n",k,cnamk.c_str(),uk);
5610  *m_logStream << setw(6) << k << " " << setw(20) << cnamk << setw(13) << setprecision(5) << uk << " constant\n";
5611  }
5612  nvl = 0;
5613  goto L200;
5614 L122:
5615  if (a == 0 && b == 0) {
5616 //*-*- variable parameter without limits
5617  nvl = 1;
5618  if (fISW[4] >= 0) {
5619  //std::printf(" %5d %-10s %13.5e%13.5e no limits\n",k,cnamk.c_str(),uk,wk);
5620  *m_logStream << setw(6) << k << " " << setw(20) << cnamk
5621  << setw(13) << setprecision(5) << uk
5622  << setw(13) << setprecision(5) << wk << " no limits\n";
5623  }
5624  } else {
5625 //*-*- variable parameter with limits
5626  nvl = 4;
5627  fLnolim = kurFALSE;
5628  if (fISW[4] >= 0) {
5629  //std::printf(" %5d %-10s %13.5e%13.5e %13.5e%13.5e\n",k,cnamk.c_str(),uk,wk,a,b);
5630  *m_logStream << setw(6) << k << " " << setw(20) << cnamk
5631  << setw(13) << setprecision(5) << uk
5632  << setw(13) << setprecision(5) << wk
5633  << setw(13) << setprecision(5) << a
5634  << setw(13) << setprecision(5) << b << '\n';
5635  }
5636  }
5637 //*-*- . . request for another variable parameter
5638  ++kint;
5639  if (kint > fMaxint) {
5640  //std::printf(" MINUIT USER ERROR. TOO MANY VARIABLE PARAMETERS.\n");
5641  *m_logStream << " MINUIT USER ERROR. TOO MANY VARIABLE PARAMETERS.\n";
5642  goto L800;
5643  }
5644  if (nvl == 1) goto L200;
5645  if (a == b) {
5646  std::printf(" USER ERROR IN MINUIT PARAMETER\n");
5647  std::printf(" DEFINITION\n");
5648  std::printf(" UPPER AND LOWER LIMITS EQUAL.\n");
5649  *m_logStream << " USER ERROR IN MINUIT PARAMETER\n" << " DEFINITION\n" << " UPPER AND LOWER LIMITS EQUAL.\n";
5650  goto L800;
5651  }
5652  if (b < a) {
5653  sav = b;
5654  b = a;
5655  a = sav;
5656  mnwarn("W", "PARAM DEF", "PARAMETER LIMITS WERE REVERSED.");
5657  if (fLwarn) fLphead = kurTRUE;
5658  }
5659  if (b - a > 1e7) {
5660  ostringstream warning;
5661  warning << "LIMITS ON PARAM " << k << " TOO FAR APART.";
5662  mnwarn("W", "PARAM DEF", warning.str().c_str());
5663  if (fLwarn) fLphead = kurTRUE;
5664  }
5665  danger = (b - uk)*(uk - a);
5666  if (danger < 0) {
5667  mnwarn("W", "PARAM DEF", "STARTING VALUE OUTSIDE LIMITS.");
5668  }
5669  if (danger == 0) {
5670  mnwarn("W", "PARAM DEF", "STARTING VALUE IS AT LIMIT.");
5671  }
5672 L200:
5673 //*-*- . . . input OK, set values, arrange lists,
5674 //*-*- calculate step sizes GSTEP, DIRIN
5675  fCfrom = "PARAMETR";
5676  fNfcnfr = fNfcn;
5677  fCstatu = "NEW VALUES";
5678  fNu = URMath::Max(fNu,k);
5679 // fCpnam[k-1] = cnamk;
5680 // fU[k-1] = uk;
5681  m_userParameterName[k] = cnamk;
5682  m_userParameterValue[k] = uk;
5683  fAlim[k-1] = a;
5684  fBlim[k-1] = b;
5685 // fNvarl[k-1] = nvl;
5686  m_userParameterFlag[k] = nvl;
5687  mnrset(1);
5688 //*-*- K is external number of new parameter
5689 //*-*- LASTIN is the number of var. params with ext. param. no.< K
5690  lastin = 0;
5691 // for (ix = 1; ix <= k-1; ++ix) { if (fNiofex[ix-1] > 0) ++lastin; }
5692  for (ix = 1; ix <= k-1; ++ix) { if (m_userParameterIdToInternalId[ix] > 0) ++lastin; }
5693 //*-*- KINT is new number of variable params, NPAR is old
5694  if (kint == fNpar) goto L280;
5695  if (kint > fNpar) {
5696 //*-*- insert new variable parameter in list
5697  for (in = fNpar; in >= lastin + 1; --in) {
5698  ix = fNexofi[in-1];
5699 // fNiofex[ix-1] = in + 1;
5700  m_userParameterIdToInternalId[ix] = in + 1;
5701  fNexofi[in] = ix;
5702  fX[in] = fX[in-1];
5703  fXt[in] = fXt[in-1];
5704  fDirin[in] = fDirin[in-1];
5705  fG2[in] = fG2[in-1];
5706  fGstep[in] = fGstep[in-1];
5707  }
5708  } else {
5709 //*-*- remove variable parameter from list
5710  for (in = lastin + 1; in <= kint; ++in) {
5711  ix = fNexofi[in];
5712 // fNiofex[ix-1] = in;
5713  m_userParameterIdToInternalId[ix] = in;
5714  fNexofi[in-1] = ix;
5715  fX[in-1] = fX[in];
5716  fXt[in-1] = fXt[in];
5717  fDirin[in-1] = fDirin[in];
5718  fG2[in-1] = fG2[in];
5719  fGstep[in-1] = fGstep[in];
5720  }
5721  }
5722 L280:
5723  ix = k;
5724 // fNiofex[ix-1] = 0;
5725  m_userParameterIdToInternalId[ix] = 0;
5726  fNpar = kint;
5727 //*-*- lists are now arranged . . . .
5728  if (nvl > 0) {
5729  in = lastin + 1;
5730  fNexofi[in-1] = ix;
5731 // fNiofex[ix-1] = in;
5732  m_userParameterIdToInternalId[ix] = in;
5733 // sav = fU[ix-1];
5734 // mnpint(sav, ix-1, pinti);
5735  sav = m_userParameterValue[ix];
5736  mnpint(sav, ix, pinti);
5737  fX[in-1] = pinti;
5738  fXt[in-1] = fX[in-1];
5739  fWerr[in-1] = wk;
5740  sav2 = sav + wk;
5741 // mnpint(sav2, ix-1, pinti);
5742  mnpint(sav2, ix, pinti);
5743  vplu = pinti - fX[in-1];
5744  sav2 = sav - wk;
5745 // mnpint(sav2, ix-1, pinti);
5746  mnpint(sav2, ix, pinti);
5747  vminu = pinti - fX[in-1];
5748  fDirin[in-1] = (URMath::Abs(vplu) + URMath::Abs(vminu))*.5;
5749  fG2[in-1] = fUp*2 / (fDirin[in-1]*fDirin[in-1]);
5750  gsmin = fEpsma2*8*URMath::Abs(fX[in-1]);
5751  fGstep[in-1] = URMath::Max(gsmin,fDirin[in-1]*.1);
5752  if (fAmin != fUndefi) {
5753  a_small = URMath::Sqrt(fEpsma2*(fAmin + fUp) / fUp);
5754  fGstep[in-1] = URMath::Max(gsmin,a_small*fDirin[in-1]);
5755  }
5756  fGrd[in-1] = fG2[in-1]*fDirin[in-1];
5757 //*-*- if parameter has limits
5758 // if (fNvarl[k-1] > 1) {
5759  if (m_userParameterFlag[k] > 1) {
5760  if (fGstep[in-1] > .5) fGstep[in-1] = .5;
5761  fGstep[in-1] = -fGstep[in-1];
5762  }
5763  }
5764  if (ktofix > 0) {
5765 // kinfix = fNiofex[ktofix-1];
5766  kinfix = m_userParameterIdToInternalId[ktofix];
5767  if (kinfix > 0) mnfixp(kinfix-1, ierr);
5768  if (ierr > 0) goto L800;
5769  }
5770  ierflg = 0;
5771  return;
5772  *m_logStream << endl;
5773 //*-*- error on input, unable to implement request . . . .
5774 L800:
5775  ierflg = 1;
5776  *m_logStream << endl;
5777 } /* mnparm_ */
5778 
5779 //______________________________________________________________________________
5780 void URMinuit::mnpars(const string &crdbuf, Int_urt &icondn)
5781 {
5782 //*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-*-*
5783 //*-* =========== =======================
5784 //*-* Called from MNREAD and user-callable
5785 //*-* Implements one parameter definition, that is:
5786 //*-* parses the string CRDBUF and calls MNPARM
5787 //*-*
5788 //*-* output conditions:
5789 //*-* ICONDN = 0 all OK
5790 //*-* ICONDN = 1 error, attempt to define parameter is ignored
5791 //*-* ICONDN = 2 end of parameter definitions
5792 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5793 
5794  /* Local variables */
5795  Double_urt a=0, b=0, fk=0, uk=0, wk=0, xk=0;
5796  Int_urt ierr, kapo1, kapo2;
5797  Int_urt k, llist, ibegin, lenbuf, istart, lnc, icy;
5798  string cnamk, comand, celmnt, ctemp;
5799  char stmp[128];
5800 
5801  lenbuf = strlen(crdbuf.c_str());
5802 //*-*- find out whether fixed or free-field format
5803  kapo1 = strspn(crdbuf.c_str(), "'");
5804  if (kapo1 == 0) goto L150;
5805  kapo2 = strspn(crdbuf.c_str() + kapo1, "'");
5806  if (kapo2 == 0) goto L150;
5807 //*-*- new (free-field) format
5808  kapo2 += kapo1;
5809 //*-*- skip leading blanks if any
5810  for (istart = 1; istart <= kapo1-1; ++istart) {
5811  if (crdbuf.substr(istart-1,1) != " ") goto L120;
5812  }
5813  goto L210;
5814 L120:
5815 //*-*- parameter number integer
5816  celmnt = crdbuf.substr(istart-1, kapo1-istart);
5817  scanf(celmnt.c_str(),fk);
5818  k = Int_urt(fk);
5819  if (k <= 0) goto L210;
5820  cnamk = "PARAM " + celmnt;
5821  if (kapo2 - kapo1 > 1) {
5822  cnamk = crdbuf.substr(kapo1, kapo2-1-kapo1);
5823  }
5824 //*-* special handling if comma or blanks and a comma follow 'name'
5825  for (icy = kapo2 + 1; icy <= lenbuf; ++icy) {
5826  if (crdbuf.substr(icy-1,1) == ",") goto L139;
5827  if (crdbuf.substr(icy-1,1) != " ") goto L140;
5828  }
5829  uk = 0;
5830  wk = 0;
5831  a = 0;
5832  b = 0;
5833  goto L170;
5834 L139:
5835  ++icy;
5836 L140:
5837  ibegin = icy;
5838  ctemp = crdbuf.substr(ibegin-1,lenbuf-ibegin);
5839  mncrck(ctemp, 20, comand, lnc, fMaxpar, fPARSplist, llist, ierr, fIsyswr);
5840  if (ierr > 0) goto L180;
5841  uk = fPARSplist[0];
5842  wk = 0;
5843  if (llist >= 2) wk = fPARSplist[1];
5844  a = 0;
5845  if (llist >= 3) a = fPARSplist[2];
5846  b = 0;
5847  if (llist >= 4) b = fPARSplist[3];
5848  goto L170;
5849 //*-*- old (fixed-field) format
5850 L150:
5851  scanf(crdbuf.c_str(),xk,stmp,uk,wk,a,b);
5852  cnamk = stmp;
5853  k = Int_urt(xk);
5854  if (k == 0) goto L210;
5855 //*-*- parameter format cracked, implement parameter definition
5856 L170:
5857 // mnparm(k-1, cnamk, uk, wk, a, b, ierr);
5858  mnparm(k, cnamk, uk, wk, a, b, ierr);
5859  icondn = ierr;
5860  return;
5861 //*-*- format or other error
5862 L180:
5863  icondn = 1;
5864  return;
5865 //*-*- end of data
5866 L210:
5867  icondn = 2;
5868 } /* mnpars_ */
5869 
5870 //______________________________________________________________________________
5871 void URMinuit::mnpfit(Double_urt *parx2p, Double_urt *pary2p, Int_urt npar2p, Double_urt *coef2p, Double_urt &sdev2p)
5872 {
5873 //*-*-*-*-*-*-*-*-*-*To fit a parabola to npar2p points*-*-*-*-*-*-*-*-*-*-*
5874 //*-* ==================================
5875 //*-* npar2p no. of points
5876 //*-* parx2p(i) x value of point i
5877 //*-* pary2p(i) y value of point i
5878 //*-*
5879 //*-* coef2p(1...3) coefficients of the fitted parabola
5880 //*-* y=coef2p(1) + coef2p(2)*x + coef2p(3)*x**2
5881 //*-* sdev2p= variance
5882 //*-* method : chi**2 = min equation solved explicitly
5883 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5884 
5885  /* Local variables */
5886  Double_urt a, f, s, t, y, s2, x2, x3, x4, y2, cz[3], xm, xy, x2y;
5887  x2 = x3 = 0;
5888  Int_urt i;
5889 
5890  /* Parameter adjustments */
5891  --coef2p;
5892  --pary2p;
5893  --parx2p;
5894 
5895  /* Function Body */
5896  for (i = 1; i <= 3; ++i) { cz[i-1] = 0; }
5897  sdev2p = 0;
5898  if (npar2p < 3) goto L10;
5899  f = (Double_urt) (npar2p);
5900 //*-* --- center x values for reasons of machine precision
5901  xm = 0;
5902  for (i = 1; i <= npar2p; ++i) { xm += parx2p[i]; }
5903  xm /= f;
5904  x2 = 0;
5905  x3 = 0;
5906  x4 = 0;
5907  y = 0;
5908  y2 = 0;
5909  xy = 0;
5910  x2y = 0;
5911  for (i = 1; i <= npar2p; ++i) {
5912  s = parx2p[i] - xm;
5913  t = pary2p[i];
5914  s2 = s*s;
5915  x2 += s2;
5916  x3 += s*s2;
5917  x4 += s2*s2;
5918  y += t;
5919  y2 += t*t;
5920  xy += s*t;
5921  x2y += s2*t;
5922  }
5923  a = (f*x4 - x2*x2)*x2 - f*(x3*x3);
5924  if (a == 0) goto L10;
5925  cz[2] = (x2*(f*x2y - x2*y) - f*x3*xy) / a;
5926  cz[1] = (xy - x3*cz[2]) / x2;
5927  cz[0] = (y - x2*cz[2]) / f;
5928  if (npar2p == 3) goto L6;
5929  sdev2p = y2 - (cz[0]*y + cz[1]*xy + cz[2]*x2y);
5930  if (sdev2p < 0) sdev2p = 0;
5931  sdev2p /= f - 3;
5932 L6:
5933  cz[0] += xm*(xm*cz[2] - cz[1]);
5934  cz[1] -= xm*2*cz[2];
5935 L10:
5936  for (i = 1; i <= 3; ++i) { coef2p[i] = cz[i-1]; }
5937 } /* mnpfit_ */
5938 
5939 //______________________________________________________________________________
5941 {
5942 //*-*-*-*-*-*-*Calculates the internal parameter value PINTI*-*-*-*-*-*-*-*
5943 //*-* =============================================
5944 //*-* corresponding to the external value PEXTI for parameter I.
5945 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5946 
5947  /* Local variables */
5948  Double_urt a, alimi, blimi, yy, yy2;
5949  Int_urt igo;
5950  string chbuf2, chbufi;
5951 
5952 // Int_urt i = i1+1;
5953  Int_urt i = i1;
5954  pinti = pexti;
5955 // igo = fNvarl[i-1];
5956  igo = m_userParameterFlag[i];
5957  if (igo == 4) {
5958 //*-* -- there are two limits
5959  alimi = fAlim[i-1];
5960  blimi = fBlim[i-1];
5961  yy = (pexti - alimi)*2 / (blimi - alimi) - 1;
5962  yy2 = yy*yy;
5963  if (yy2 >= 1 - fEpsma2) {
5964  if (yy < 0) {
5965  a = fVlimlo;
5966  chbuf2 = " IS AT ITS LOWER ALLOWED LIMIT.";
5967  } else {
5968  a = fVlimhi;
5969  chbuf2 = " IS AT ITS UPPER ALLOWED LIMIT.";
5970  }
5971  pinti = a;
5972  pexti = alimi + (blimi - alimi)*.5*(URMath::Sin(a) + 1);
5973  fLimset = kurTRUE;
5974  if (yy2 > 1) chbuf2 = " BROUGHT BACK INSIDE LIMITS.";
5975  ostringstream warning;
5976  warning << "VARIABLE " << i << " " << chbuf2;
5977  mnwarn("W", fCfrom.c_str(), warning.str().c_str());
5978  } else {
5979  pinti = URMath::ASin(yy);
5980  }
5981  }
5982 } /* mnpint_ */
5983 
5984 //______________________________________________________________________________
5985 void URMinuit::mnplot(Double_urt *xpt, Double_urt *ypt, char* chpt, Int_urt nxypt, Int_urt npagwd, Int_urt npagln)
5986 {
5987  //*-*-*-*Plots points in array xypt onto one page with labelled axes*-*-*-*-*
5988  //*-* ===========================================================
5989  //*-* NXYPT is the number of points to be plotted
5990  //*-* XPT(I) = x-coord. of ith point
5991  //*-* YPT(I) = y-coord. of ith point
5992  //*-* CHPT(I) = character to be plotted at this position
5993  //*-* the input point arrays XPT, YPT, CHPT are destroyed.
5994  //*-*
5995  //*-*
5996  //*-*
5997  //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5998 
5999  static string cdot = ".";
6000  static string cslash = "/";
6001 
6002  /* Local variables */
6003  Double_urt xmin, ymin, xmax, ymax, savx, savy, yprt;
6004  Double_urt bwidx, bwidy, xbest, ybest, ax, ay, bx, by;
6005  Double_urt xvalus[12], any, dxx, dyy;
6006  Int_urt iten, i, j, k, maxnx, maxny, iquit, ni, linodd;
6007  Int_urt nxbest, nybest, km1, ibk, isp1, nx, ny, ks, ix;
6008  string chmess, ctemp;
6009  Bool_urt overpr;
6010  char cline[120];
6011  char chsav, chbest;
6012 
6013  /* Function Body */
6014  //*-* Computing MIN
6015  maxnx = URMath::Min(npagwd-20,100);
6016  if (maxnx < 10) maxnx = 10;
6017  maxny = npagln;
6018  if (maxny < 10) maxny = 10;
6019  if (nxypt <= 1) return;
6020  xbest = xpt[0];
6021  ybest = ypt[0];
6022  chbest = chpt[0];
6023  //*-*- order the points by decreasing y
6024  km1 = nxypt - 1;
6025  for (i = 1; i <= km1; ++i) {
6026  iquit = 0;
6027  ni = nxypt - i;
6028  for (j = 1; j <= ni; ++j) {
6029  if (ypt[j-1] > ypt[j]) continue;
6030  savx = xpt[j-1];
6031  xpt[j-1] = xpt[j];
6032  xpt[j] = savx;
6033  savy = ypt[j-1];
6034  ypt[j-1] = ypt[j];
6035  ypt[j] = savy;
6036  chsav = chpt[j-1];
6037  chpt[j-1]= chpt[j];
6038  chpt[j] = chsav;
6039  iquit = 1;
6040  }
6041  if (iquit == 0) break;
6042  }
6043  //*-*- find extreme values
6044  xmax = xpt[0];
6045  xmin = xmax;
6046  for (i = 1; i <= nxypt; ++i) {
6047  if (xpt[i-1] > xmax) xmax = xpt[i-1];
6048  if (xpt[i-1] < xmin) xmin = xpt[i-1];
6049  }
6050  dxx = (xmax - xmin)*.001;
6051  xmax += dxx;
6052  xmin -= dxx;
6053  mnbins(xmin, xmax, maxnx, xmin, xmax, nx, bwidx);
6054  ymax = ypt[0];
6055  ymin = ypt[nxypt-1];
6056  if (ymax == ymin) ymax = ymin + 1;
6057  dyy = (ymax - ymin)*.001;
6058  ymax += dyy;
6059  ymin -= dyy;
6060  mnbins(ymin, ymax, maxny, ymin, ymax, ny, bwidy);
6061  any = (Double_urt) ny;
6062  //*-*- if first point is blank, it is an 'origin'
6063  if (chbest == ' ') goto L50;
6064  xbest = (xmax + xmin)*.5;
6065  ybest = (ymax + ymin)*.5;
6066  L50:
6067  //*-*- find scale constants
6068  ax = 1 / bwidx;
6069  ay = 1 / bwidy;
6070  bx = -ax*xmin + 2;
6071  by = -ay*ymin - 2;
6072  //*-*- convert points to grid positions
6073  for (i = 1; i <= nxypt; ++i) {
6074  xpt[i-1] = ax*xpt[i-1] + bx;
6075  ypt[i-1] = any - ay*ypt[i-1] - by;
6076  }
6077  nxbest = Int_urt((ax*xbest + bx));
6078  nybest = Int_urt((any - ay*ybest - by));
6079  //*-*- print the points
6080  ny += 2;
6081  nx += 2;
6082  isp1 = 1;
6083  linodd = 1;
6084  overpr = kurFALSE;
6085  for (i = 1; i <= ny; ++i) {
6086  for (ibk = 1; ibk <= nx; ++ibk) { cline[ibk-1] = ' '; }
6087  cline[nx] = '\0';
6088  cline[nx+1] = '\0';
6089  cline[0] = '.';
6090  cline[nx-1] = '.';
6091  cline[nxbest-1] = '.';
6092  if (i != 1 && i != nybest && i != ny) goto L320;
6093  for (j = 1; j <= nx; ++j) { cline[j-1] = '.'; }
6094  L320:
6095  yprt = ymax - Double_urt(i-1)*bwidy;
6096  if (isp1 > nxypt) goto L350;
6097  //*-*- find the points to be plotted on this line
6098  for (k = isp1; k <= nxypt; ++k) {
6099  ks = Int_urt(ypt[k-1]);
6100  if (ks > i) goto L345;
6101  ix = Int_urt(xpt[k-1]);
6102  if (cline[ix-1] == '.') goto L340;
6103  if (cline[ix-1] == ' ') goto L340;
6104  if (cline[ix-1] == chpt[k-1]) continue;
6105  overpr = kurTRUE;
6106  //*-*- OVERPR is true if one or more positions contains more than
6107  //*-*- one point
6108  cline[ix-1] = '&';
6109  continue;
6110  L340:
6111  cline[ix-1] = chpt[k-1];
6112  }
6113  isp1 = nxypt + 1;
6114  goto L350;
6115  L345:
6116  isp1 = k;
6117  L350:
6118  if (linodd == 1 || i == ny) goto L380;
6119  linodd = 1;
6120  ctemp = cline;
6121  std::printf(" %s\n",ctemp.c_str());
6122  goto L400;
6123  L380:
6124  ctemp = cline;
6125  std::printf(" %14.7g ..%s\n",yprt,ctemp.c_str());
6126  linodd = 0;
6127  L400:
6128  ;
6129  }
6130  //*-*- print labels on x-axis every ten columns
6131  for (ibk = 1; ibk <= nx; ++ibk) {
6132  cline[ibk-1] = ' ';
6133  if (ibk % 10 == 1) cline[ibk-1] = '/';
6134  }
6135  std::printf(" %s\n",cline);
6136 
6137  for (ibk = 1; ibk <= 12; ++ibk) {
6138  xvalus[ibk-1] = xmin + Double_urt(ibk-1)*10*bwidx;
6139  }
6140  std::printf(" ");
6141  iten = (nx + 9) / 10;
6142  for (ibk = 1; ibk <= iten; ++ibk) {
6143  std::printf(" %9.4g", xvalus[ibk-1]);
6144  }
6145  chmess = " ";
6146  if (overpr) chmess = " Overprint character is &";
6147  std::printf(" ONE COLUMN=%13.7g%s\n",bwidx,chmess.c_str());
6148 } /* mnplot_ */
6149 
6150 //______________________________________________________________________________
6151 void URMinuit::mnpout(Int_urt iuext1, string &chnam, Double_urt &val, Double_urt &err, Double_urt &xlolim, Double_urt &xuplim, Int_urt &iuint) const
6152 {
6153 //*-*-*-*Provides the user with information concerning the current status*-*-*
6154 //*-* ================================================================
6155 //*-* of parameter number IUEXT. Namely, it returns:
6156 //*-* CHNAM: the name of the parameter
6157 //*-* VAL: the current (external) value of the parameter
6158 //*-* ERR: the current estimate of the parameter uncertainty
6159 //*-* XLOLIM: the lower bound (or zero if no limits)
6160 //*-* XUPLIM: the upper bound (or zero if no limits)
6161 //*-* IUINT: the internal parameter number (or zero if not variable,
6162 //*-* or negative if undefined).
6163 //*-* Note also: If IUEXT is negative, then it is -internal parameter
6164 //*-* number, and IUINT is returned as the EXTERNAL number.
6165 //*-* Except for IUINT, this is exactly the inverse of MNPARM
6166 //*-* User-called
6167 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6168 
6169  /* Local variables */
6170  Int_urt iint, iext, nvl;
6171 
6172 // Int_urt iuext = iuext1 + 1;
6173  Int_urt iuext = iuext1;
6174  xlolim = 0;
6175  xuplim = 0;
6176  err = 0;
6177  if (iuext == 0) goto L100;
6178  if (iuext < 0) {
6179 //*-*- internal parameter number specified
6180  iint = -(iuext);
6181  if (iint > fNpar) goto L100;
6182  iext = fNexofi[iint-1];
6183  iuint = iext;
6184  } else {
6185 //*-*- external parameter number specified
6186  iext = iuext;
6187  if (iext == 0) goto L100;
6188  if (iext > fNu) goto L100;
6189 // iint = fNiofex[iext-1];
6190  iint = m_userParameterIdToInternalId[iext];
6191  iuint = iint;
6192  }
6193 //*-*- in both cases
6194 // nvl = fNvarl[iext-1];
6195  nvl = m_userParameterFlag[iext];
6196  if (nvl < 0) goto L100;
6197 // chnam = fCpnam[iext-1];
6198 // val = fU[iext-1];
6199  chnam = m_userParameterName[iext];
6200  val = m_userParameterValue[iext];
6201  if (iint > 0) err = fWerr[iint-1];
6202  if (nvl == 4) {
6203  xlolim = fAlim[iext-1];
6204  xuplim = fBlim[iext-1];
6205  }
6206  return;
6207 //*-*- parameter is undefined
6208 L100:
6209  iuint = -1;
6210  chnam = "undefined";
6211  val = 0;
6212 } /* mnpout_ */
6213 
6214 //______________________________________________________________________________
6216 {
6217 //*-*-*-*Prints the values of the parameters at the time of the call*-*-*-*-*
6218 //*-* ===========================================================
6219 //*-* also prints other relevant information such as function value,
6220 //*-* estimated distance to minimum, parameter errors, step sizes.
6221 //*-*
6222 //*-* According to the value of IKODE, the printout is:/
6223 //*-* IKODE=INKODE= 0 only info about function value
6224 //*-* 1 parameter values, errors, limits
6225 //*-* 2 values, errors, step sizes, internal values
6226 //*-* 3 values, errors, step sizes, first derivs.
6227 //*-* 4 values, parabolic errors, MINOS errors
6228 //*-* when INKODE=5, MNPRIN chooses IKODE=1,2, or 3, according to ISW(2)
6229 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6230 
6231  /* Initialized data */
6232 
6233  static string cblank = " ";
6234  static string cnambf = " ";
6235 
6236  /* Local variables */
6237  Double_urt dcmax, x1, x2, x3, dc;
6238  x2 = x3 = 0;
6239  Int_urt nadd, i, k, l, m, ikode, ic, nc, ntrail, lbl;
6240  string chedm;
6241  string colhdl[6], colhdu[6], cx2, cx3, cheval;
6242 
6243  if (fNu == 0) {
6244  //std::printf(" THERE ARE CURRENTLY NO PARAMETERS DEFINED\n");
6245  *m_logStream << " THERE ARE CURRENTLY NO PARAMETERS DEFINED" << endl;
6246  return;
6247  }
6248 //*-*- get value of IKODE based in INKODE, ISW(2)
6249  ikode = inkode;
6250  if (inkode == 5) {
6251  ikode = fISW[1] + 1;
6252  if (ikode > 3) ikode = 3;
6253  }
6254 //*-*- set 'default' column headings
6255  for (k = 1; k <= 6; ++k) {
6256  colhdu[k-1] = "UNDEFINED";
6257  colhdl[k-1] = "COLUMN HEAD";
6258  }
6259 //*-*- print title if Minos errors, and title exists.
6260  if (ikode == 4 && fCtitl != fCundef) {
6261  //std::printf(" MINUIT TASK: %s\n",fCtitl.c_str());
6262  *m_logStream << " MINUIT TASK: " << fCtitl << '\n';
6263  }
6264 //*-*- report function value and status
6265  if (fval == fUndefi) cheval = " unknown ";
6266  else {
6267  ostringstream och;
6268  och << fval;
6269  cheval = och.str();
6270 // = Form("%g",fval);
6271  }
6272  if (fEDM == fBigedm) chedm = " unknown ";
6273  else {
6274  ostringstream och;
6275  och << fEDM;
6276  chedm = och.str();
6277 // chedm = Form("%g",fEDM);
6278  }
6279  nc = fNfcn - fNfcnfr;
6280  //std::printf(" FCN=%s FROM %8s STATUS=%10s %6d CALLS %9d TOTAL\n"
6281  // ,cheval.c_str()
6282  // ,fCfrom.c_str()
6283  // ,fCstatu.c_str(),nc,fNfcn);
6284  *m_logStream << " FCN=" << cheval << " FROM " << setw(8) << fCfrom << " STATUS="
6285  << setw(10) << fCstatu << setw(7) << nc << " " << setw(9) << fNfcn << " TOTAL\n" << endl;
6286  m = fISW[1];
6287  if (m == 0 || m == 2 || fDcovar == 0) {
6288  // std::printf(" EDM=%s STRATEGY=%2d %s\n"
6289  // ,chedm.c_str(),fIstrat
6290  // ,fCovmes[m].c_str());
6291  *m_logStream << " EDM=" << chedm << " STRATEGY=" << setw(2)
6292  << fIstrat << " " << fCovmes[m] << '\n';
6293  } else {
6294  dcmax = 1;
6295  dc = URMath::Min(fDcovar,dcmax)*100;
6296  //std::printf(" EDM=%s STRATEGY=%2d ERROR MATRIX UNCERTAINTY %5.1f per cent\n"
6297  // ,chedm.c_str(),fIstrat,dc);
6298  *m_logStream << " EDM=" << chedm
6299  << " STRATEGY=" << setw(2) << fIstrat << " ERROR MATRIX UNCERTAINTY "
6300  << setw(5) << setprecision(1) << dc << " per cent\n";
6301  }
6302 
6303  if (ikode == 0) return;
6304 //*-*- find longest name (for Rene!)
6305  ntrail = 10;
6306  for (i = 1; i <= fNu; ++i) {
6308  if (m_userParameterFlag[i] < 0) continue;
6309 // uint lastChar = fCpnam[i-1].size();
6310  uint lastChar = m_userParameterName[i].size();
6311  uint icMax = (lastChar < 10 ) ? lastChar : 10;
6312  for (ic = icMax; ic >= 1; --ic) {
6313 // if (fCpnam[i-1].substr(ic-1,1) != " ") goto L16;
6314  if (m_userParameterName[i].substr(ic-1,1) != " ") goto L16;
6315  }
6316  ic = 1;
6317 L16:
6318  lbl = 10 - ic;
6319  if (lbl < ntrail) ntrail = lbl;
6320  }
6321  nadd = ntrail / 2 + 1;
6322  if (ikode == 1) {
6323  colhdu[0] = " ";
6324  colhdl[0] = " ERROR ";
6325  colhdu[1] = " PHYSICAL";
6326  colhdu[2] = " LIMITS ";
6327  colhdl[1] = " NEGATIVE ";
6328  colhdl[2] = " POSITIVE ";
6329  }
6330  if (ikode == 2) {
6331  colhdu[0] = " ";
6332  colhdl[0] = " ERROR ";
6333  colhdu[1] = " INTERNAL ";
6334  colhdl[1] = " STEP SIZE ";
6335  colhdu[2] = " INTERNAL ";
6336  colhdl[2] = " VALUE ";
6337  }
6338  if (ikode == 3) {
6339  colhdu[0] = " ";
6340  colhdl[0] = " ERROR ";
6341  colhdu[1] = " STEP ";
6342  colhdl[1] = " SIZE ";
6343  colhdu[2] = " FIRST ";
6344  colhdl[2] = " DERIVATIVE ";
6345  }
6346  if (ikode == 4) {
6347  colhdu[0] = " PARABOLIC ";
6348  colhdl[0] = " ERROR ";
6349  colhdu[1] = " MINOS ";
6350  colhdu[2] = "ERRORS ";
6351  colhdl[1] = " NEGATIVE ";
6352  colhdl[2] = " POSITIVE ";
6353  }
6354 
6355  if (ikode != 4) {
6356  if (fISW[1] < 3) colhdu[0] = " APPROXIMATE ";
6357  if (fISW[1] < 1) colhdu[0] = " CURRENT GUESS";
6358  }
6359  // get the maximum parameter name length
6360  int maxNameSize = 0;
6361  for ( vector<string>::iterator name = m_userParameterName.begin();
6362  name != m_userParameterName.end();
6363  ++name ) {
6364  int nameSize = name->size();
6365  maxNameSize = max(maxNameSize,nameSize);
6366  }
6367  maxNameSize = max(maxNameSize,9);
6368 // *m_logStream << "maxNameSize = " << maxNameSize << endl;
6369 
6370  *m_logStream << " EXT " << setw(maxNameSize) << left << "PARAMETER" << " "
6371  << setw(14) << colhdu[0].c_str() << setw(14) << colhdu[1].c_str() << setw(14) << colhdu[2].c_str()
6372  << endl;
6373  *m_logStream << " NO. " << setw(maxNameSize) << left << " NAME " << " VALUE "
6374  << setw(14) << colhdl[0].c_str() << setw(14) << colhdl[1].c_str() << setw(14) << colhdl[2].c_str()
6375  << endl;
6376 // std::printf(" EXT PARAMETER %-14s%-14s%-14s\n",colhdu[0].c_str()
6377 // ,colhdu[1].c_str()
6378 // ,colhdu[2].c_str());
6379 // std::printf(" NO. NAME VALUE %-14s%-14s%-14s\n",colhdl[0].c_str()
6380 // ,colhdl[1].c_str()
6381 // ,colhdl[2].c_str());
6382 //*-*- . . . loop over parameters . .
6383  for (i = 1; i <= fNu; ++i) {
6384 // if (fNvarl[i-1] < 0) continue;
6385  if (m_userParameterFlag[i] < 0) continue;
6386 // l = fNiofex[i-1];
6387  l = m_userParameterIdToInternalId[i];
6388 // cnambf = cblank.substr(0,nadd) + fCpnam[i-1];
6389  cnambf = cblank.substr(0,nadd) + m_userParameterName[i];
6390  if (l == 0) goto L55;
6391 //*-*- variable parameter.
6392  x1 = fWerr[l-1];
6393  cx2 = "PLEASE GET X..";
6394  cx3 = "PLEASE GET X..";
6395  if (ikode == 1) {
6396 // if (fNvarl[i-1] <= 1) {
6397  if (m_userParameterFlag[i] <= 1) {
6398 // std::printf("%4d %-11s%14.5e%14.5e\n",i,cnambf.c_str(),fU[i-1],x1);
6399 // std::printf("%4d %-11s%14.5e%14.5e\n",i,cnambf.c_str(),m_userParameterValue[i],x1);
6400  *m_logStream << setw(5) << right << i << " " << setw(maxNameSize) << m_userParameterName[i]
6401  << setw(14) << setprecision(5) << m_userParameterValue[i]
6402  << setw(14) << setprecision(5) << x1 << endl;
6403  continue;
6404  } else {
6405  x2 = fAlim[i-1];
6406  x3 = fBlim[i-1];
6407  }
6408  }
6409  if (ikode == 2) {
6410  x2 = fDirin[l-1];
6411  x3 = fX[l-1];
6412  }
6413  if (ikode == 3) {
6414  x2 = fDirin[l-1];
6415  x3 = fGrd[l-1];
6416 // if (fNvarl[i-1] > 1 && URMath::Abs(URMath::Cos(fX[l-1])) < .001) {
6417  if (m_userParameterFlag[i] > 1 && URMath::Abs(URMath::Cos(fX[l-1])) < .001) {
6418  cx3 = "** at limit **";
6419  }
6420  }
6421  if (ikode == 4) {
6422  x2 = fErn[l-1];
6423  if (x2 == 0) cx2 = " ";
6424  if (x2 == fUndefi) cx2 = " at limit ";
6425  x3 = fErp[l-1];
6426  if (x3 == 0) cx3 = " ";
6427  if (x3 == fUndefi) cx3 = " at limit ";
6428  }
6429  if (cx2 == "PLEASE GET X..") {
6430  ostringstream ocx;
6431  ocx << setw(14) << setprecision(5) << x2;
6432  cx2 = ocx.str();
6433 // cx2 = Form("%14.5e",x2);
6434  }
6435  if (cx3 == "PLEASE GET X..") {
6436  ostringstream ocx;
6437  ocx << setw(14) << setprecision(5) << x3;
6438  cx3 = ocx.str();
6439  // cx3 = Form("%14.5e",x3);
6440  }
6441 // std::printf("%4d %-11s%14.5e%14.5e%-14s%-14s\n",i
6442 // ,cnambf.c_str(),fU[i-1],x1
6443 // ,cx2.c_str(),cx3.c_str());
6444 // std::printf("%4d %-11s%14.5e%14.5e%-14s%-14s\n",i
6445 // ,cnambf.c_str(),m_userParameterValue[i],x1
6446 // ,cx2.c_str(),cx3.c_str());
6447  *m_logStream << setw(5) << right << i << " " << setw(maxNameSize) << m_userParameterName[i]
6448  << setw(14) << setprecision(5) << m_userParameterValue[i]
6449  << setw(14) << setprecision(5) << x1
6450  << cx2 << cx3 << endl;
6451 
6452 //*-*- check if parameter is at limit
6453 // if (fNvarl[i-1] <= 1 || ikode == 3) continue;
6454  if (m_userParameterFlag[i] <= 1 || ikode == 3) continue;
6455  if (URMath::Abs(URMath::Cos(fX[l-1])) < .001) {
6456  //std::printf(" WARNING - - ABOVE PARAMETER IS AT LIMIT.\n");
6457  *m_logStream << " WARNING - - ABOVE PARAMETER IS AT LIMIT.\n";
6458  }
6459  continue;
6460 
6461 //*-*- print constant or fixed parameter.
6462 L55:
6463  colhdu[0] = " constant ";
6464 // if (fNvarl[i-1] > 0) colhdu[0] = " fixed ";
6465  if (m_userParameterFlag[i] > 0) colhdu[0] = " fixed ";
6466 // if (fNvarl[i-1] == 4 && ikode == 1) {
6467  if (m_userParameterFlag[i] == 4 && ikode == 1) {
6468  // std::printf("%4d %-11s%14.5e%-14s%14.5e%14.5e\n",i
6469  // ,cnambf.c_str(),fU[i-1]
6470  // ,colhdu[0].c_str(),fAlim[i-1],fBlim[i-1]);
6471  //std::printf("%4d %-11s%14.5e%-14s%14.5e%14.5e\n",i
6472  // ,cnambf.c_str(),m_userParameterValue[i]
6473  // ,colhdu[0].c_str(),fAlim[i-1],fBlim[i-1]);
6474  *m_logStream << setw(5) << right << i << " " << setw(maxNameSize) << m_userParameterName[i]
6475  << setw(14) << setprecision(5) << m_userParameterValue[i]
6476  << setw(14) << colhdu[0].c_str()
6477  << setw(14) << setprecision(5) << fAlim[i-1]
6478  << setw(14) << setprecision(5) << fBlim[i-1]
6479  << endl;
6480  } else {
6481 // std::printf("%4d %-11s%14.5e%s\n",i
6482 // ,cnambf.c_str(),fU[i-1],colhdu[0].c_str());
6483 // std::printf("%4d %-11s%14.5e%s\n",i
6484 // ,cnambf.c_str(),m_userParameterValue[i],colhdu[0].c_str());
6485  *m_logStream << setw(5) << right << i << " " << setw(maxNameSize) << m_userParameterName[i]
6486  << setw(14) << setprecision(5) << m_userParameterValue[i]
6487  << setw(14) << colhdu[0].c_str()
6488  << endl;
6489  }
6490  }
6491 
6492  if (fUp != fUpdflt) {
6493  std::printf(" ERR DEF= %g\n",fUp);
6494  *m_logStream << " ERR DEF= " << fUp;
6495  }
6496  *m_logStream << endl;
6497  return;
6498 } /* mnprin_ */
6499 
6500 //______________________________________________________________________________
6502 {
6503 //*-*-*-*-*-*Calculates the eigenvalues of v to see if positive-def*-*-*-*-*
6504 //*-* ======================================================
6505 //*-* if not, adds constant along diagonal to make positive.
6506 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6507 
6508  /* Local variables */
6509  Double_urt dgmin, padd, pmin, pmax, dg, epspdf, epsmin;
6510  Int_urt ndex, i, j, ndexd, ip, ifault;
6511  string chbuff, ctemp;
6512 
6513  epsmin = 1e-6;
6514  epspdf = URMath::Max(epsmin,fEpsma2);
6515  dgmin = fVhmat[0];
6516 //*-*- Check if negative or zero on diagonal
6517  for (i = 1; i <= fNpar; ++i) {
6518  ndex = i*(i + 1) / 2;
6519  if (fVhmat[ndex-1] <= 0) {
6520  ostringstream warning;
6521  warning << "Negative diagonal element " << i << " in Error Matrix";
6522  mnwarn("W", fCfrom.c_str(), warning.str().c_str());
6523  }
6524  if (fVhmat[ndex-1] < dgmin) dgmin = fVhmat[ndex-1];
6525  }
6526  if (dgmin <= 0) {
6527  dg = epspdf + 1 - dgmin;
6528  ostringstream warning;
6529  warning << dg << " added to diagonal of error matrix";
6530  mnwarn("W", fCfrom.c_str(), warning.str().c_str());
6531  } else {
6532  dg = 0;
6533  }
6534 //*-*- Store VHMAT in P, make sure diagonal pos.
6535  for (i = 1; i <= fNpar; ++i) {
6536  ndex = i*(i-1) / 2;
6537  ndexd = ndex + i;
6538  fVhmat[ndexd-1] += dg;
6539  fPSDFs[i-1] = 1 / URMath::Sqrt(fVhmat[ndexd-1]);
6540  for (j = 1; j <= i; ++j) {
6541  ++ndex;
6542  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1]*fPSDFs[i-1]*fPSDFs[j-1];
6543  }
6544  }
6545 //*-*- call eigen (p,p,maxint,npar,pstar,-npar)
6546  mneig(fP, fMaxint, fNpar, fMaxint, fPstar, epspdf, ifault);
6547  pmin = fPstar[0];
6548  pmax = fPstar[0];
6549  for (ip = 2; ip <= fNpar; ++ip) {
6550  if (fPstar[ip-1] < pmin) pmin = fPstar[ip-1];
6551  if (fPstar[ip-1] > pmax) pmax = fPstar[ip-1];
6552  }
6553  pmax = URMath::Max(URMath::Abs(pmax),Double_urt(1));
6554  if ( ( pmin <= 0 && fLwarn ) || fISW[4] >= 2) {
6555  std::printf(" EIGENVALUES OF SECOND-DERIVATIVE MATRIX:\n");
6556  ctemp = " ";
6557  for (ip = 1; ip <= fNpar; ++ip) {
6558  ostringstream localTemp;
6559  localTemp << fPstar[ip-1];
6560  ctemp += localTemp.str(); //Form(" %11.4e",);
6561  }
6562  std::printf("%s",ctemp.c_str());
6563  }
6564  if (pmin > epspdf*pmax) return;
6565  if (fISW[1] == 3) fISW[1] = 2;
6566  padd = pmax*.001 - pmin;
6567  for (ip = 1; ip <= fNpar; ++ip) {
6568  ndex = ip*(ip + 1) / 2;
6569  fVhmat[ndex-1] *= padd + 1;
6570  }
6571  fCstatu = "NOT POSDEF";
6572  ostringstream warning;
6573  warning << "MATRIX FORCED POS-DEF BY ADDING %f TO DIAGONAL. " << padd;
6574  mnwarn("W", fCfrom.c_str(), warning.str().c_str());
6575 
6576 } /* mnpsdf_ */
6577 
6578 //______________________________________________________________________________
6580 {
6581 //*-*-*-*-*Called only by MNSIMP (and MNIMPR) to add a new point*-*-*-*-*-*-*
6582 //*-* =====================================================
6583 //*-* and remove an old one from the current simplex, and get the
6584 //*-* estimated distance to minimum.
6585 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6586 
6587  /* Local variables */
6588  Double_urt pbig, plit;
6589  Int_urt i, j, nparp1;
6590 
6591  /* Function Body */
6592  for (i = 1; i <= fNpar; ++i) { fP[i + jh*fMaxpar - fMaxpar-1] = pnew[i-1]; }
6593  y[jh-1] = ynew;
6594  if (ynew < fAmin) {
6595  for (i = 1; i <= fNpar; ++i) { fX[i-1] = pnew[i-1]; }
6596  mninex(fX);
6597  fAmin = ynew;
6598  fCstatu = "PROGRESS ";
6599  jl = jh;
6600  }
6601  jh = 1;
6602  nparp1 = fNpar + 1;
6603  for (j = 2; j <= nparp1; ++j) { if (y[j-1] > y[jh-1]) jh = j; }
6604  fEDM = y[jh-1] - y[jl-1];
6605  if (fEDM <= 0) goto L45;
6606  for (i = 1; i <= fNpar; ++i) {
6607  pbig = fP[i-1];
6608  plit = pbig;
6609  for (j = 2; j <= nparp1; ++j) {
6610  if (fP[i + j*fMaxpar - fMaxpar-1] > pbig) pbig = fP[i + j*fMaxpar - fMaxpar-1];
6611  if (fP[i + j*fMaxpar - fMaxpar-1] < plit) plit = fP[i + j*fMaxpar - fMaxpar-1];
6612  }
6613  fDirin[i-1] = pbig - plit;
6614  }
6615 L40:
6616  return;
6617 L45:
6618  std::printf(" FUNCTION VALUE DOES NOT SEEM TO DEPEND ON ANY OF THE%d VARIABLE PARAMETERS.\n",fNpar);
6619  std::printf(" VERIFY THAT STEP SIZES ARE BIG ENOUGH AND CHECK FCN LOGIC.\n");
6620  std::printf(" *******************************************************************************\n");
6621  std::printf(" *******************************************************************************\n");
6622  goto L40;
6623 } /* mnrazz_ */
6624 
6625 //______________________________________________________________________________
6627 {
6628 //*-*-*-*-*-*-*This is a super-portable random number generator*-*-*-*-*-*-*
6629 //*-* ================================================
6630 //*-* It should not overflow on any 32-bit machine.
6631 //*-* The cycle is only ~10**9, so use with care!
6632 //*-* Note especially that VAL must not be undefined on input.
6633 //*-* Set Default Starting Seed
6634 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6635 
6636  /* Initialized data */
6637 
6638  static Int_urt iseed = 12345;
6639 
6640  Int_urt k;
6641 
6642  if (val == 3) goto L100;
6643  inseed = iseed;
6644  k = iseed / 53668;
6645  iseed = (iseed - k*53668)*40014 - k*12211;
6646  if (iseed < 0) iseed += 2147483563;
6647  val = Double_urt(iseed*4.656613e-10);
6648  return;
6649 //*-* "entry" to set seed, flag is VAL=3
6650 L100:
6651  iseed = inseed;
6652 } /* mnrn15_ */
6653 
6654 //______________________________________________________________________________
6656 {
6657 //*-*-*-*-*-*-*-*Resets function value and errors to UNDEFINED*-*-*-*-*-*-*-*
6658 //*-* =============================================
6659 //*-* If IOPT=1,
6660 //*-* If IOPT=0, sets only MINOS errors to undefined
6661 //*-* Called from MNCLER and whenever problem changes, for example
6662 //*-* after SET LIMITS, SET PARAM, CALL FCN 6
6663 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6664 
6665  Int_urt iext, i;
6666 
6667  fCstatu = "RESET ";
6668  if (iopt >= 1) {
6669  fAmin = fUndefi;
6670  fFval3 = URMath::Abs(fAmin)*2 + 1;
6671  fEDM = fBigedm;
6672  fISW[3] = 0;
6673  fISW[1] = 0;
6674  fDcovar = 1;
6675  fISW[0] = 0;
6676  }
6677  fLnolim = kurTRUE;
6678  for (i = 1; i <= fNpar; ++i) {
6679  iext = fNexofi[i-1];
6680 // if (fNvarl[iext-1] >= 4) fLnolim = kurFALSE;
6681  if (m_userParameterFlag[iext] >= 4) fLnolim = kurFALSE;
6682  fErp[i-1] = 0;
6683  fErn[i-1] = 0;
6684  fGlobcc[i-1] = 0;
6685  }
6686  if (fISW[1] >= 1) {
6687  fISW[1] = 1;
6688  fDcovar = URMath::Max(fDcovar,.5);
6689  }
6690 } /* mnrset_ */
6691 
6692 //______________________________________________________________________________
6694 {
6695 //*-*-*-*Writes current parameter values and step sizes onto file ISYSSA*-*-*
6696 //*-* ===============================================================
6697 //*-* in format which can be reread by Minuit for restarting.
6698 //*-* The covariance matrix is also output if it exists.
6699 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6700 
6701  std::printf("mnsave is dummy in the base class URMinuit: Use URMinuitOld\n");
6702 
6703 } /* mnsave_ */
6704 
6705 //______________________________________________________________________________
6707 {
6708 //*-*-*-*-*Scans the values of FCN as a function of one parameter*-*-*-*-*-*
6709 //*-* ======================================================
6710 //*-* and plots the resulting values as a curve using MNPLOT.
6711 //*-* It may be called to scan one parameter or all parameters.
6712 //*-* retains the best function and parameter values found.
6713 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6714 
6715  /* Local variables */
6716  Double_urt step, uhigh, xhreq, xlreq, ubest, fnext, unext, xh, xl;
6717  Int_urt ipar, iint, icall, ncall, nbins, nparx;
6718  Int_urt nxypt, nccall, iparwd;
6719 
6720  xlreq = URMath::Min(fWord7[2],fWord7[3]);
6721  xhreq = URMath::Max(fWord7[2],fWord7[3]);
6722  ncall = Int_urt((fWord7[1] + .01));
6723  if (ncall <= 1) ncall = 41;
6724  if (ncall > 101) ncall = 101;
6725  nccall = ncall;
6726  if (fAmin == fUndefi) mnamin();
6727  iparwd = Int_urt((fWord7[0] + .1));
6728  ipar = URMath::Max(iparwd,0);
6729 // iint = fNiofex[ipar-1];
6730  iint = m_userParameterIdToInternalId[ipar];
6731  fCstatu = "NO CHANGE";
6732  if (iparwd > 0) goto L200;
6733 
6734 //*-*- equivalent to a loop over parameters requested
6735 L100:
6736  ++ipar;
6737  if (ipar > fNu) goto L900;
6738 // iint = fNiofex[ipar-1];
6739  iint = m_userParameterIdToInternalId[ipar];
6740  if (iint <= 0) goto L100;
6741 //*-*- set up range for parameter IPAR
6742 L200:
6743 // ubest = fU[ipar-1];
6744  ubest = m_userParameterValue[ipar];
6745  fXpt[0] = ubest;
6746  fYpt[0] = fAmin;
6747  fChpt[0] = ' ';
6748  fXpt[1] = ubest;
6749  fYpt[1] = fAmin;
6750  fChpt[1] = 'X';
6751  nxypt = 2;
6752 // if (fNvarl[ipar-1] > 1) goto L300;
6753  if (m_userParameterFlag[ipar] > 1) goto L300;
6754 
6755 //*-*- no limits on parameter
6756  if (xlreq == xhreq) goto L250;
6757  unext = xlreq;
6758  step = (xhreq - xlreq) / Double_urt(ncall-1);
6759  goto L500;
6760 L250:
6761  xl = ubest - fWerr[iint-1];
6762  xh = ubest + fWerr[iint-1];
6763  mnbins(xl, xh, ncall, unext, uhigh, nbins, step);
6764  nccall = nbins + 1;
6765  goto L500;
6766 //*-*- limits on parameter
6767 L300:
6768  if (xlreq == xhreq) goto L350;
6769 //*-* Computing MAX
6770  xl = URMath::Max(xlreq,fAlim[ipar-1]);
6771 //*-* Computing MIN
6772  xh = URMath::Min(xhreq,fBlim[ipar-1]);
6773  if (xl >= xh) goto L700;
6774  unext = xl;
6775  step = (xh - xl) / Double_urt(ncall-1);
6776  goto L500;
6777 L350:
6778  unext = fAlim[ipar-1];
6779  step = (fBlim[ipar-1] - fAlim[ipar-1]) / Double_urt(ncall-1);
6780 //*-*- main scanning loop over parameter IPAR
6781 L500:
6782  for (icall = 1; icall <= nccall; ++icall) {
6783 // fU[ipar-1] = unext;
6784  m_userParameterValue[ipar] = unext;
6785  nparx = fNpar;
6786 // Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
6787  Eval(nparx, fGin, fnext, m_userParameterValue, 4); ++fNfcn;
6788  ++nxypt;
6789  fXpt[nxypt-1] = unext;
6790  fYpt[nxypt-1] = fnext;
6791  fChpt[nxypt-1] = '*';
6792  if (fnext < fAmin) {
6793  fAmin = fnext;
6794  ubest = unext;
6795  fCstatu = "IMPROVED ";
6796  }
6797  unext += step;
6798  }
6799  fChpt[nccall] = 0;
6800 
6801 //*-*- finished with scan of parameter IPAR
6802 // fU[ipar-1] = ubest;
6803  m_userParameterValue[ipar] = ubest;
6804  mnexin(fX);
6805 // std::printf("%dSCAN OF PARAMETER NO. %d, %s\n"
6806 // ,fNewpag,ipar,fCpnam[ipar-1].c_str());
6807  std::printf("%dSCAN OF PARAMETER NO. %d, %s\n"
6808  ,fNewpag,ipar,m_userParameterName[ipar].c_str());
6809  mnplot(fXpt, fYpt, fChpt, nxypt, fNpagwd, fNpagln);
6810  goto L800;
6811 L700:
6812  std::printf(" REQUESTED RANGE OUTSIDE LIMITS FOR PARAMETER %d\n",ipar);
6813 L800:
6814  if (iparwd <= 0) goto L100;
6815 //*-*- finished with all parameters
6816 L900:
6817  mnprin(5, fAmin);
6818 } /* mnscan_ */
6819 
6820 //______________________________________________________________________________
6822 {
6823 //*-*-*-*Performs a rough (but global) minimization by monte carlo search*-*
6824 //*-* ================================================================
6825 //*-* Each time a new minimum is found, the search area is shifted
6826 //*-* to be centered at the best value. Random points are chosen
6827 //*-* uniformly over a hypercube determined by current step sizes.
6828 //*-* The Metropolis algorithm accepts a worse point with probability
6829 //*-* exp(-d/UP), where d is the degradation. Improved points
6830 //*-* are of course always accepted. Actual steps are random
6831 //*-* multiples of the nominal steps (DIRIN).
6832 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6833 
6834  /* Local variables */
6835  Double_urt dxdi, rnum, ftry, rnum1, rnum2, alpha;
6836  Double_urt flast, bar;
6837  Int_urt ipar, iext, j, ifail, iseed, nparx, istep, ib, mxfail, mxstep;
6838 
6839  mxfail = Int_urt(fWord7[0]);
6840  if (mxfail <= 0) mxfail = fNpar*20 + 100;
6841  mxstep = mxfail*10;
6842  if (fAmin == fUndefi) mnamin();
6843  alpha = fWord7[1];
6844  if (alpha <= 0) alpha = 3;
6845  if (fISW[4] >= 1) {
6846  std::printf(" MNSEEK: MONTE CARLO MINIMIZATION USING METROPOLIS ALGORITHM\n");
6847  std::printf(" TO STOP AFTER %6d SUCCESSIVE FAILURES, OR %7d STEPS\n",mxfail,mxstep);
6848  std::printf(" MAXIMUM STEP SIZE IS %9.3f ERROR BARS.\n",alpha);
6849  }
6850  fCstatu = "INITIAL ";
6851  if (fISW[4] >= 2) mnprin(2, fAmin);
6852  fCstatu = "UNCHANGED ";
6853  ifail = 0;
6854  rnum = 0;
6855  rnum1 = 0;
6856  rnum2 = 0;
6857  nparx = fNpar;
6858  flast = fAmin;
6859 //*-*- set up step sizes, starting values
6860  for (ipar = 1; ipar <= fNpar; ++ipar) {
6861  iext = fNexofi[ipar-1];
6862  fDirin[ipar-1] = alpha*2*fWerr[ipar-1];
6863 // if (fNvarl[iext-1] > 1) {
6864  if (m_userParameterFlag[iext] > 1) {
6865 //*-*- parameter with limits
6866  mndxdi(fX[ipar-1], ipar-1, dxdi);
6867  if (dxdi == 0) dxdi = 1;
6868  fDirin[ipar-1] = alpha*2*fWerr[ipar-1] / dxdi;
6869  if (URMath::Abs(fDirin[ipar-1]) > 6.2831859999999997) {
6870  fDirin[ipar-1] = 6.2831859999999997;
6871  }
6872  }
6873  fSEEKxmid[ipar-1] = fX[ipar-1];
6874  fSEEKxbest[ipar-1] = fX[ipar-1];
6875  }
6876 //*-*- search loop
6877  for (istep = 1; istep <= mxstep; ++istep) {
6878  if (ifail >= mxfail) break;
6879  for (ipar = 1; ipar <= fNpar; ++ipar) {
6880  mnrn15(rnum1, iseed);
6881  mnrn15(rnum2, iseed);
6882  fX[ipar-1] = fSEEKxmid[ipar-1] + (rnum1 + rnum2 - 1)*.5*fDirin[ipar-1];
6883  }
6884  mninex(fX);
6885 // Eval(nparx, fGin, ftry, fU, 4); ++fNfcn;
6886  Eval(nparx, fGin, ftry, m_userParameterValue, 4); ++fNfcn;
6887  if (ftry < flast) {
6888  if (ftry < fAmin) {
6889  fCstatu = "IMPROVEMNT";
6890  fAmin = ftry;
6891  for (ib = 1; ib <= fNpar; ++ib) { fSEEKxbest[ib-1] = fX[ib-1]; }
6892  ifail = 0;
6893  if (fISW[4] >= 2) mnprin(2, fAmin);
6894  }
6895  goto L300;
6896  } else {
6897  ++ifail;
6898 //*-*- Metropolis algorithm
6899  bar = (fAmin - ftry) / fUp;
6900  mnrn15(rnum, iseed);
6901  if (bar < URMath::Log(rnum)) continue;
6902  }
6903 //*-*- Accept new point, move there
6904 L300:
6905  for (j = 1; j <= fNpar; ++j) { fSEEKxmid[j-1] = fX[j-1]; }
6906  flast = ftry;
6907  }
6908 //*-*- end search loop
6909  if (fISW[4] > 1) {
6910  std::printf(" MNSEEK: %5d SUCCESSIVE UNSUCCESSFUL TRIALS.\n",ifail);
6911  }
6912  for (ib = 1; ib <= fNpar; ++ib) { fX[ib-1] = fSEEKxbest[ib-1]; }
6913  mninex(fX);
6914  if (fISW[4] >= 1) mnprin(2, fAmin);
6915  if (fISW[4] == 0) mnprin(0, fAmin);
6916 } /* mnseek_ */
6917 
6918 //______________________________________________________________________________
6920 {
6921 //*-*-*-*-*Interprets the commands that start with SET and SHOW*-*-*-*-*-*-*
6922 //*-* ====================================================
6923 //*-* Called from MNEXCM
6924 //*-* file characteristics for SET INPUT
6925 //*-* 'SET ' or 'SHOW', 'ON ' or 'OFF', 'SUPPRESSED' or 'REPORTED '
6926 //*-* explanation of print level numbers -1:3 and strategies 0:2
6927 //*-* identification of debug options
6928 //*-* things that can be set or shown
6929 //*-* options not intended for normal users
6930 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6931 
6932  /* Initialized data */
6933 
6934  const char *cname[30] = {
6935  "FCN value ",
6936  "PARameters",
6937  "LIMits ",
6938  "COVariance",
6939  "CORrelatio",
6940  "PRInt levl",
6941  "NOGradient",
6942  "GRAdient ",
6943  "ERRor def ",
6944  "INPut file",
6945  "WIDth page",
6946  "LINes page",
6947  "NOWarnings",
6948  "WARnings ",
6949  "RANdom gen",
6950  "TITle ",
6951  "STRategy ",
6952  "EIGenvalue",
6953  "PAGe throw",
6954  "MINos errs",
6955  "EPSmachine",
6956  "OUTputfile",
6957  "BATch ",
6958  "INTeractiv",
6959  "VERsion ",
6960  "reserve ",
6961  "NODebug ",
6962  "DEBug ",
6963  "SHOw ",
6964  "SET "};
6965 
6966  static Int_urt nname = 25;
6967  static Int_urt nntot = 30;
6968  static string cprlev[5] = {
6969  "-1: NO OUTPUT EXCEPT FROM SHOW ",
6970  " 0: REDUCED OUTPUT ",
6971  " 1: NORMAL OUTPUT ",
6972  " 2: EXTRA OUTPUT FOR PROBLEM CASES",
6973  " 3: MAXIMUM OUTPUT "};
6974 
6975  static string cstrat[3] = {
6976  " 0: MINIMIZE THE NUMBER OF CALLS TO FUNCTION",
6977  " 1: TRY TO BALANCE SPEED AGAINST RELIABILITY",
6978  " 2: MAKE SURE MINIMUM TRUE, ERRORS CORRECT "};
6979 
6980  static string cdbopt[7] = {
6981  "REPORT ALL EXCEPTIONAL CONDITIONS ",
6982  "MNLINE: LINE SEARCH MINIMIZATION ",
6983  "MNDERI: FIRST DERIVATIVE CALCULATIONS ",
6984  "MNHESS: SECOND DERIVATIVE CALCULATIONS ",
6985  "MNMIGR: COVARIANCE MATRIX UPDATES ",
6986  "MNHES1: FIRST DERIVATIVE UNCERTAINTIES ",
6987  "MNCONT: MNCONTOUR PLOT (MNCROS SEARCH) "};
6988 
6989  /* System generated locals */
6990 // Int_urt f_inqu();
6991 
6992  /* Local variables */
6993  Double_urt val;
6994  Int_urt iset, iprm, i, jseed, kname, iseed, iunit, id, ii, kk;
6995  Int_urt ikseed, idbopt, igrain, iswsav, isw2;
6996  string cfname, cmode, ckind, cwarn, copt, ctemp, ctemp2;
6997  Bool_urt lname=kurFALSE;
6998 
6999  for (i = 1; i <= nntot; ++i) {
7000  ctemp = cname[i-1];
7001  ckind = ctemp.substr(0,3);
7002  ctemp2 = fCword.substr(4,6);
7003  if (strstr(ctemp2.c_str(),ckind.c_str())) goto L5;
7004  }
7005  i = 0;
7006 L5:
7007  kname = i;
7008 
7009 //*-*- Command could be SET xxx, SHOW xxx, HELP SET or HELP SHOW
7010  ctemp2 = fCword.substr(0,3);
7011  if ( ctemp2.find("HEL") != string::npos) goto L2000;
7012  if ( ctemp2.find("SHO") != string::npos) goto L1000;
7013  if ( ctemp2.find("SET") == string::npos) goto L1900;
7014 //*-*- ---
7015  ckind = "SET ";
7016 //*-*- . . . . . . . . . . set unknown
7017  if (kname <= 0) goto L1900;
7018 //*-*- . . . . . . . . . . set known
7019  switch ((int)kname) {
7020  case 1: goto L3000;
7021  case 2: goto L20;
7022  case 3: goto L30;
7023  case 4: goto L40;
7024  case 5: goto L3000;
7025  case 6: goto L60;
7026  case 7: goto L70;
7027  case 8: goto L80;
7028  case 9: goto L90;
7029  case 10: goto L100;
7030  case 11: goto L110;
7031  case 12: goto L120;
7032  case 13: goto L130;
7033  case 14: goto L140;
7034  case 15: goto L150;
7035  case 16: goto L160;
7036  case 17: goto L170;
7037  case 18: goto L3000;
7038  case 19: goto L190;
7039  case 20: goto L3000;
7040  case 21: goto L210;
7041  case 22: goto L220;
7042  case 23: goto L230;
7043  case 24: goto L240;
7044  case 25: goto L3000;
7045  case 26: goto L1900;
7046  case 27: goto L270;
7047  case 28: goto L280;
7048  case 29: goto L290;
7049  case 30: goto L300;
7050  }
7051 
7052 //*-*- . . . . . . . . . . set param
7053 L20:
7054  iprm = Int_urt(fWord7[0]);
7055  if (iprm > fNu) goto L25;
7056  if (iprm <= 0) goto L25;
7057 // if (fNvarl[iprm-1] < 0) goto L25;
7058  if (m_userParameterFlag[iprm] < 0) goto L25;
7059 // fU[iprm-1] = fWord7[1];
7060  m_userParameterValue[iprm] = fWord7[1];
7061  mnexin(fX);
7062  isw2 = fISW[1];
7063  mnrset(1);
7064 //*-*- Keep approximate covariance matrix, even if new param value
7065  fISW[1] = URMath::Min(isw2,1);
7066  fCfrom = "SET PARM";
7067  fNfcnfr = fNfcn;
7068  fCstatu = "NEW VALUES";
7069  return;
7070 L25:
7071  std::printf(" UNDEFINED PARAMETER NUMBER. IGNORED.\n");
7072  return;
7073 //*-*- . . . . . . . . . . set limits
7074 L30:
7075  mnlims();
7076  return;
7077 //*-*- . . . . . . . . . . set covar
7078 L40:
7079 //*-* this command must be handled by MNREAD, and is not Fortran-callable
7080  goto L3000;
7081 //*-*- . . . . . . . . . . set print
7082 L60:
7083  fISW[4] = Int_urt(fWord7[0]);
7084  return;
7085 //*-*- . . . . . . . . . . set nograd
7086 L70:
7087  fISW[2] = 0;
7088  return;
7089 //*-*- . . . . . . . . . . set grad
7090 L80:
7091  mngrad();
7092  return;
7093 //*-*- . . . . . . . . . . set errdef
7094 L90:
7095  if (fWord7[0] == fUp) return;
7096  if (fWord7[0] <= 0) {
7097  if (fUp == fUpdflt) return;
7098  fUp = fUpdflt;
7099  } else {
7100  fUp = fWord7[0];
7101  }
7102  for (i = 1; i <= fNpar; ++i) {
7103  fErn[i-1] = 0;
7104  fErp[i-1] = 0;
7105  }
7106  mnwerr();
7107  return;
7108 //*-*- . . . . . . . . . . set input
7109 //*-* This command must be handled by MNREAD. If it gets this far,
7110 //*-*- it is illegal.
7111 L100:
7112  goto L3000;
7113 //*-*- . . . . . . . . . . set width
7114 L110:
7115  fNpagwd = Int_urt(fWord7[0]);
7116  fNpagwd = URMath::Max(fNpagwd,50);
7117  return;
7118 
7119 L120:
7120  fNpagln = Int_urt(fWord7[0]);
7121  return;
7122 //*-*- . . . . . . . . . . set nowarn
7123 
7124 L130:
7125  fLwarn = kurFALSE;
7126  return;
7127 //*-*- . . . . . . . . . . set warn
7128 L140:
7129  fLwarn = kurTRUE;
7130  mnwarn("W", "SHO", "SHO");
7131  return;
7132 //*-*- . . . . . . . . . . set random
7133 L150:
7134  jseed = Int_urt(fWord7[0]);
7135  val = 3;
7136  mnrn15(val, jseed);
7137  if (fISW[4] > 0) {
7138  std::printf(" MINUIT RANDOM NUMBER SEED SET TO %d\n",jseed);
7139  }
7140  return;
7141 //*-*- . . . . . . . . . . set title
7142 L160:
7143 //*-* this command must be handled by MNREAD, and is not Fortran-callable
7144  goto L3000;
7145 //*-*- . . . . . . . . . set strategy
7146 L170:
7147  fIstrat = Int_urt(fWord7[0]);
7150  if (fISW[4] > 0) goto L1172;
7151  return;
7152 //*-*- . . . . . . . . . set page throw
7153 L190:
7154  fNewpag = Int_urt(fWord7[0]);
7155  goto L1190;
7156 //*-*- . . . . . . . . . . set epsmac
7157 L210:
7158  if (fWord7[0] > 0 && fWord7[0] < .1) {
7159  fEpsmac = fWord7[0];
7160  }
7162  goto L1210;
7163 //*-*- . . . . . . . . . . set outputfile
7164 L220:
7165  iunit = Int_urt(fWord7[0]);
7166  fIsyswr = iunit;
7167  fIstkwr[0] = iunit;
7168  if (fISW[4] >= 0) goto L1220;
7169  return;
7170 //*-*- . . . . . . . . . . set batch
7171 L230:
7172  fISW[5] = 0;
7173  if (fISW[4] >= 0) goto L1100;
7174  return;
7175 //*-*- . . . . . . . . . . set interactive
7176 L240:
7177  fISW[5] = 1;
7178  if (fISW[4] >= 0) goto L1100;
7179  return;
7180 //*-*- . . . . . . . . . . set nodebug
7181 L270:
7182  iset = 0;
7183  goto L281;
7184 //*-*- . . . . . . . . . . set debug
7185 L280:
7186  iset = 1;
7187 L281:
7188  idbopt = Int_urt(fWord7[0]);
7189  if (idbopt > 6) goto L288;
7190  if (idbopt >= 0) {
7191  fIdbg[idbopt] = iset;
7192  if (iset == 1) fIdbg[0] = 1;
7193  } else {
7194 //*-*- SET DEBUG -1 sets all debug options
7195  for (id = 0; id <= 6; ++id) { fIdbg[id] = iset; }
7196  }
7197  fLrepor = fIdbg[0] >= 1;
7198  mnwarn("D", "SHO", "SHO");
7199  return;
7200 L288:
7201  std::printf(" UNKNOWN DEBUG OPTION %d REQUESTED. IGNORED\n",idbopt);
7202  return;
7203 //*-*- . . . . . . . . . . set show
7204 L290:
7205 //*-*- . . . . . . . . . . set set
7206 L300:
7207  goto L3000;
7208 //*-*- -----------------------------------------------------
7209 L1000:
7210 //*-*- at this point, CWORD must be 'SHOW'
7211  ckind = "SHOW";
7212  if (kname <= 0) goto L1900;
7213 
7214  switch ((int)kname) {
7215  case 1: goto L1010;
7216  case 2: goto L1020;
7217  case 3: goto L1030;
7218  case 4: goto L1040;
7219  case 5: goto L1050;
7220  case 6: goto L1060;
7221  case 7: goto L1070;
7222  case 8: goto L1070;
7223  case 9: goto L1090;
7224  case 10: goto L1100;
7225  case 11: goto L1110;
7226  case 12: goto L1120;
7227  case 13: goto L1130;
7228  case 14: goto L1130;
7229  case 15: goto L1150;
7230  case 16: goto L1160;
7231  case 17: goto L1170;
7232  case 18: goto L1180;
7233  case 19: goto L1190;
7234  case 20: goto L1200;
7235  case 21: goto L1210;
7236  case 22: goto L1220;
7237  case 23: goto L1100;
7238  case 24: goto L1100;
7239  case 25: goto L1250;
7240  case 26: goto L1900;
7241  case 27: goto L1270;
7242  case 28: goto L1270;
7243  case 29: goto L1290;
7244  case 30: goto L1300;
7245  }
7246 
7247 //*-*- . . . . . . . . . . show fcn
7248 L1010:
7249  if (fAmin == fUndefi) mnamin();
7250  mnprin(0, fAmin);
7251  return;
7252 //*-*- . . . . . . . . . . show param
7253 L1020:
7254  if (fAmin == fUndefi) mnamin();
7255  mnprin(5, fAmin);
7256  return;
7257 //*-*- . . . . . . . . . . show limits
7258 L1030:
7259  if (fAmin == fUndefi) mnamin();
7260  mnprin(1, fAmin);
7261  return;
7262 //*-*- . . . . . . . . . . show covar
7263 L1040:
7264  mnmatu(1);
7265  return;
7266 //*-*- . . . . . . . . . . show corre
7267 L1050:
7268  mnmatu(0);
7269  return;
7270 //*-*- . . . . . . . . . . show print
7271 L1060:
7272  if (fISW[4] < -1) fISW[4] = -1;
7273  if (fISW[4] > 3) fISW[4] = 3;
7274  std::printf(" ALLOWED PRINT LEVELS ARE:\n");
7275  std::printf(" %s\n",cprlev[0].c_str());
7276  std::printf(" %s\n",cprlev[1].c_str());
7277  std::printf(" %s\n",cprlev[2].c_str());
7278  std::printf(" %s\n",cprlev[3].c_str());
7279  std::printf(" %s\n",cprlev[4].c_str());
7280  std::printf(" CURRENT PRINTOUT LEVEL IS %s\n",cprlev[fISW[4]+1].c_str());
7281  return;
7282 //*-*- . . . . . . . show nograd, grad
7283 L1070:
7284  if (fISW[2] <= 0) {
7285  std::printf(" NOGRAD IS SET. DERIVATIVES NOT COMPUTED IN FCN.\n");
7286  } else {
7287  std::printf(" GRAD IS SET. USER COMPUTES DERIVATIVES IN FCN.\n");
7288  }
7289  return;
7290 //*-*- . . . . . . . . . . show errdef
7291 L1090:
7292  std::printf(" ERRORS CORRESPOND TO FUNCTION CHANGE OF %g\n",fUp);
7293  return;
7294 //*-*- . . . . . . . . . . show input,
7295 //*-*- batch, or interactive
7296 L1100:
7297 // ioin__1.inerr = 0;
7298 // ioin__1.inunit = fIsysrd;
7299 // ioin__1.infile = 0;
7300 // ioin__1.inex = 0;
7301 // ioin__1.inopen = 0;
7302 // ioin__1.innum = 0;
7303 // ioin__1.innamed = &lname;
7304 // ioin__1.innamlen = 64;
7305 // ioin__1.inname = cfname;
7306 // ioin__1.inacc = 0;
7307 // ioin__1.inseq = 0;
7308 // ioin__1.indir = 0;
7309 // ioin__1.infmt = 0;
7310 // ioin__1.inform = 0;
7311 // ioin__1.inunf = 0;
7312 // ioin__1.inrecl = 0;
7313 // ioin__1.innrec = 0;
7314 // ioin__1.inblank = 0;
7315 // f_inqu(&ioin__1);
7316  cmode = "BATCH MODE ";
7317  if (fISW[5] == 1) cmode = "INTERACTIVE MODE";
7318  if (! lname) cfname = "unknown";
7319  std::printf(" INPUT NOW BEING READ IN %s FROM UNIT NO. %d FILENAME: %s\n"
7320  ,cmode.c_str(),fIsysrd,cfname.c_str());
7321  return;
7322 //*-*- . . . . . . . . . . show width
7323 L1110:
7324  std::printf(" PAGE WIDTH IS SET TO %d COLUMNS\n",fNpagwd);
7325  return;
7326 //*-*- . . . . . . . . . . show lines
7327 L1120:
7328  std::printf(" PAGE LENGTH IS SET TO %d LINES\n",fNpagln);
7329  return;
7330 //*-*- . . . . . . .show nowarn, warn
7331 L1130:
7332  cwarn = "SUPPRESSED";
7333  if (fLwarn) cwarn = "REPORTED ";
7334  std::printf("%s\n",cwarn.c_str());
7335  if (! fLwarn) mnwarn("W", "SHO", "SHO");
7336  return;
7337 //*-*- . . . . . . . . . . show random
7338 L1150:
7339  val = 0;
7340  mnrn15(val, igrain);
7341  ikseed = igrain;
7342  std::printf(" MINUIT RNDM SEED IS CURRENTLY=%d\n",ikseed);
7343  val = 3;
7344  iseed = ikseed;
7345  mnrn15(val, iseed);
7346  return;
7347 //*-*- . . . . . . . . . show title
7348 L1160:
7349  std::printf(" TITLE OF CURRENT TASK IS:%s\n",fCtitl.c_str());
7350  return;
7351 //*-*- . . . . . . . show strategy
7352 L1170:
7353  std::printf(" ALLOWED STRATEGIES ARE:\n");
7354  std::printf(" %s\n",cstrat[0].c_str());
7355  std::printf(" %s\n",cstrat[1].c_str());
7356  std::printf(" %s\n",cstrat[2].c_str());
7357 L1172:
7358  std::printf(" NOW USING STRATEGY %s\n",cstrat[fIstrat].c_str());
7359  return;
7360 //*-*- . . . . . show eigenvalues
7361 L1180:
7362  iswsav = fISW[4];
7363  fISW[4] = 3;
7364  if (fISW[1] < 1) {
7365  std::printf("%s\n",fCovmes[0].c_str());
7366  } else {
7367  mnpsdf();
7368  }
7369  fISW[4] = iswsav;
7370  return;
7371 //*-*- . . . . . show page throw
7372 L1190:
7373  std::printf(" PAGE THROW CARRIAGE CONTROL = %d\n",fNewpag);
7374  if (fNewpag == 0) {
7375  std::printf(" NO PAGE THROWS IN MINUIT OUTPUT\n");
7376  }
7377  return;
7378 //*-*- . . . . . . show minos errors
7379 L1200:
7380  for (ii = 1; ii <= fNpar; ++ii) {
7381  if (fErp[ii-1] > 0 || fErn[ii-1] < 0) goto L1204;
7382  }
7383  std::printf(" THERE ARE NO MINOS ERRORS CURRENTLY VALID.\n");
7384  return;
7385 L1204:
7386  mnprin(4, fAmin);
7387  return;
7388 //*-*- . . . . . . . . . show epsmac
7389 L1210:
7390  std::printf(" FLOATING-POINT NUMBERS ASSUMED ACCURATE TO %g\n",fEpsmac);
7391  return;
7392 //*-*- . . . . . . show outputfiles
7393 L1220:
7394  std::printf(" MINUIT PRIMARY OUTPUT TO UNIT %d\n",fIsyswr);
7395  return;
7396 //*-*- . . . . . . show version
7397 L1250:
7398  std::printf(" THIS IS MINUIT VERSION:%s\n",fCvrsn.c_str());
7399  return;
7400 //*-*- . . . . . . show nodebug, debug
7401 L1270:
7402  for (id = 0; id <= 6; ++id) {
7403  copt = "OFF";
7404  if (fIdbg[id] >= 1) copt = "ON ";
7405  std::printf(" DEBUG OPTION %3d IS %3s :%s\n"
7406  ,id,copt.c_str(),cdbopt[id].c_str());
7407  }
7408  if (! fLrepor) mnwarn("D", "SHO", "SHO");
7409  return;
7410 //*-*- . . . . . . . . . . show show
7411 L1290:
7412  ckind = "SHOW";
7413  goto L2100;
7414 //*-*- . . . . . . . . . . show set
7415 L1300:
7416  ckind = "SET ";
7417  goto L2100;
7418 //*-*- -----------------------------------------------------
7419 //*-*- UNKNOWN COMMAND
7420 L1900:
7421  std::printf(" THE COMMAND:%10s IS UNKNOWN.\n",fCword.c_str());
7422  goto L2100;
7423 //*-*- -----------------------------------------------------
7424 //*-*- HELP SHOW, HELP SET, SHOW SET, or SHOW SHOW
7425 L2000:
7426  ckind = "SET ";
7427  ctemp2 = fCword.substr(3,7);
7428  if (strcmp(ctemp2.c_str(), "SHO")) ckind = "SHOW";
7429 L2100:
7430  std::printf(" THE FORMAT OF THE %4s COMMAND IS:\n",ckind.c_str());
7431  std::printf(" %s xxx [numerical arguments if any]\n",ckind.c_str());
7432  std::printf(" WHERE xxx MAY BE ONE OF THE FOLLOWING:\n");
7433  for (kk = 1; kk <= nname; ++kk) {
7434  std::printf(" %s\n",cname[kk-1]);
7435  }
7436  return;
7437 //*-*- -----------------------------------------------------
7438 //*-*- ILLEGAL COMMAND
7439 L3000:
7440  std::printf(" ABOVE COMMAND IS ILLEGAL. IGNORED\n");
7441 
7442 } /* mnset_ */
7443 
7444 //______________________________________________________________________________
7446 {
7447 //*-*-*-*-*Minimization using the simplex method of Nelder and Mead*-*-*-*-*
7448 //*-* ========================================================
7449 //*-* Performs a minimization using the simplex method of Nelder
7450 //*-* and Mead (ref. -- Comp. J. 7,308 (1965)).
7451 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7452 
7453  /* Initialized data */
7454 
7455  static Double_urt alpha = 1;
7456  static Double_urt beta = .5;
7457  static Double_urt gamma = 2;
7458  static Double_urt rhomin = 4;
7459  static Double_urt rhomax = 8;
7460 
7461  /* Local variables */
7462  Double_urt dmin_, dxdi, yrho, f, ynpp1, aming, ypbar;
7463  Double_urt bestx, ystar, y1, y2, ystst, pb, wg;
7464  Double_urt absmin, rho, sig2, rho1, rho2;
7465  Int_urt npfn, i, j, k, jhold, ncycl, nparx;
7466  Int_urt nparp1, kg, jh, nf, jl, ns;
7467 
7468  if (fNpar <= 0) return;
7469  if (fAmin == fUndefi) mnamin();
7470  fCfrom = "SIMPLEX ";
7471  fNfcnfr = fNfcn;
7472  fCstatu = "UNCHANGED ";
7473  npfn = fNfcn;
7474  nparp1 = fNpar + 1;
7475  nparx = fNpar;
7476  rho1 = alpha + 1;
7477  rho2 = rho1 + alpha*gamma;
7478  wg = 1 / Double_urt(fNpar);
7479  if (fISW[4] >= 0) {
7480  std::printf(" START SIMPLEX MINIMIZATION. CONVERGENCE WHEN EDM .LT. %g\n",fEpsi);
7481  }
7482  for (i = 1; i <= fNpar; ++i) {
7483  fDirin[i-1] = fWerr[i-1];
7484  mndxdi(fX[i-1], i-1, dxdi);
7485  if (dxdi != 0) fDirin[i-1] = fWerr[i-1] / dxdi;
7486  dmin_ = fEpsma2*URMath::Abs(fX[i-1]);
7487  if (fDirin[i-1] < dmin_) fDirin[i-1] = dmin_;
7488  }
7489 //*-* ** choose the initial simplex using single-parameter searches
7490 L1:
7491  ynpp1 = fAmin;
7492  jl = nparp1;
7493  fSIMPy[nparp1-1] = fAmin;
7494  absmin = fAmin;
7495  for (i = 1; i <= fNpar; ++i) {
7496  aming = fAmin;
7497  fPbar[i-1] = fX[i-1];
7498  bestx = fX[i-1];
7499  kg = 0;
7500  ns = 0;
7501  nf = 0;
7502 L4:
7503  fX[i-1] = bestx + fDirin[i-1];
7504  mninex(fX);
7505 // Eval(nparx, fGin, f, fU, 4); ++fNfcn;
7506  Eval(nparx, fGin, f, m_userParameterValue, 4); ++fNfcn;
7507  if (f <= aming) goto L6;
7508 //*-*- failure
7509  if (kg == 1) goto L8;
7510  kg = -1;
7511  ++nf;
7512  fDirin[i-1] *= -.4;
7513  if (nf < 3) goto L4;
7514  ns = 6;
7515 //*-*- success
7516 L6:
7517  bestx = fX[i-1];
7518  fDirin[i-1] *= 3;
7519  aming = f;
7520  fCstatu = "PROGRESS ";
7521  kg = 1;
7522  ++ns;
7523  if (ns < 6) goto L4;
7524 //*-*- local minimum found in ith direction
7525 L8:
7526  fSIMPy[i-1] = aming;
7527  if (aming < absmin) jl = i;
7528  if (aming < absmin) absmin = aming;
7529  fX[i-1] = bestx;
7530  for (k = 1; k <= fNpar; ++k) { fP[k + i*fMaxpar - fMaxpar-1] = fX[k-1]; }
7531  }
7532  jh = nparp1;
7533  fAmin = fSIMPy[jl-1];
7534  mnrazz(ynpp1, fPbar, fSIMPy, jh, jl);
7535  for (i = 1; i <= fNpar; ++i) { fX[i-1] = fP[i + jl*fMaxpar - fMaxpar-1]; }
7536  mninex(fX);
7537  fCstatu = "PROGRESS ";
7538  if (fISW[4] >= 1) mnprin(5, fAmin);
7539  fEDM = fBigedm;
7540  sig2 = fEDM;
7541  ncycl = 0;
7542 //*-*- . . . . . start main loop
7543 L50:
7544  if (sig2 < fEpsi && fEDM < fEpsi) goto L76;
7545  sig2 = fEDM;
7546  if (fNfcn - npfn > fNfcnmx) goto L78;
7547 //*-*- calculate new point * by reflection
7548  for (i = 1; i <= fNpar; ++i) {
7549  pb = 0;
7550  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7551  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7552  fPstar[i-1] = (alpha + 1)*fPbar[i-1] - alpha*fP[i + jh*fMaxpar - fMaxpar-1];
7553  }
7554  mninex(fPstar);
7555 // Eval(nparx, fGin, ystar, fU, 4); ++fNfcn;
7556  Eval(nparx, fGin, ystar, m_userParameterValue, 4); ++fNfcn;
7557  if (ystar >= fAmin) goto L70;
7558 //*-*- point * better than jl, calculate new point **
7559  for (i = 1; i <= fNpar; ++i) {
7560  fPstst[i-1] = gamma*fPstar[i-1] + (1 - gamma)*fPbar[i-1];
7561  }
7562  mninex(fPstst);
7563 // Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7564  Eval(nparx, fGin, ystst, m_userParameterValue, 4); ++fNfcn;
7565 //*-*- try a parabola through ph, pstar, pstst. min = prho
7566  y1 = (ystar - fSIMPy[jh-1])*rho2;
7567  y2 = (ystst - fSIMPy[jh-1])*rho1;
7568  rho = (rho2*y1 - rho1*y2)*.5 / (y1 - y2);
7569  if (rho < rhomin) goto L66;
7570  if (rho > rhomax) rho = rhomax;
7571  for (i = 1; i <= fNpar; ++i) {
7572  fPrho[i-1] = rho*fPbar[i-1] + (1 - rho)*fP[i + jh*fMaxpar - fMaxpar-1];
7573  }
7574  mninex(fPrho);
7575 // Eval(nparx, fGin, yrho, fU, 4); ++fNfcn;
7576  Eval(nparx, fGin, yrho, m_userParameterValue, 4); ++fNfcn;
7577  if (yrho < fSIMPy[jl-1] && yrho < ystst) goto L65;
7578  if (ystst < fSIMPy[jl-1]) goto L67;
7579  if (yrho > fSIMPy[jl-1]) goto L66;
7580 //*-*- accept minimum point of parabola, PRHO
7581 L65:
7582  mnrazz(yrho, fPrho, fSIMPy, jh, jl);
7583  goto L68;
7584 L66:
7585  if (ystst < fSIMPy[jl-1]) goto L67;
7586  mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7587  goto L68;
7588 L67:
7589  mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7590 L68:
7591  ++ncycl;
7592  if (fISW[4] < 2) goto L50;
7593  if (fISW[4] >= 3 || ncycl % 10 == 0) {
7594  mnprin(5, fAmin);
7595  }
7596  goto L50;
7597 //*-*- point * is not as good as jl
7598 L70:
7599  if (ystar >= fSIMPy[jh-1]) goto L73;
7600  jhold = jh;
7601  mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7602  if (jhold != jh) goto L50;
7603 //*-*- calculate new point **
7604 L73:
7605  for (i = 1; i <= fNpar; ++i) {
7606  fPstst[i-1] = beta*fP[i + jh*fMaxpar - fMaxpar-1] + (1 - beta)*fPbar[i-1];
7607  }
7608  mninex(fPstst);
7609 // Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7610  Eval(nparx, fGin, ystst, m_userParameterValue, 4); ++fNfcn;
7611  if (ystst > fSIMPy[jh-1]) goto L1;
7612 //*-*- point ** is better than jh
7613  if (ystst < fAmin) goto L67;
7614  mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7615  goto L50;
7616 //*-*- . . . . . . end main loop
7617 L76:
7618  if (fISW[4] >= 0) {
7619  std::printf(" SIMPLEX MINIMIZATION HAS CONVERGED.\n");
7620  }
7621  fISW[3] = 1;
7622  goto L80;
7623 L78:
7624  if (fISW[4] >= 0) {
7625  std::printf(" SIMPLEX TERMINATES WITHOUT CONVERGENCE.\n");
7626  }
7627  fCstatu = "CALL LIMIT";
7628  fISW[3] = -1;
7629  fISW[0] = 1;
7630 L80:
7631  for (i = 1; i <= fNpar; ++i) {
7632  pb = 0;
7633  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7634  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7635  }
7636  mninex(fPbar);
7637 // Eval(nparx, fGin, ypbar, fU, 4); ++fNfcn;
7638  Eval(nparx, fGin, ypbar, m_userParameterValue, 4); ++fNfcn;
7639  if (ypbar < fAmin) mnrazz(ypbar, fPbar, fSIMPy, jh, jl);
7640  mninex(fX);
7641  if (fNfcnmx + npfn - fNfcn < fNpar*3) goto L90;
7642  if (fEDM > fEpsi*2) goto L1;
7643 L90:
7644  if (fISW[4] >= 0) mnprin(5, fAmin);
7645 } /* mnsimp_ */
7646 
7647 //______________________________________________________________________________
7648 void URMinuit::mnstat(Double_urt &fmin, Double_urt &fedm, Double_urt &errdef, Int_urt &npari, Int_urt &nparx, Int_urt &istat)
7649 {
7650 
7651 //*-*-*-*-*Returns concerning the current status of the minimization*-*-*-*-*
7652 //*-* =========================================================
7653 //*-* User-called
7654 //*-* Namely, it returns:
7655 //*-* FMIN: the best function value found so far
7656 //*-* FEDM: the estimated vertical distance remaining to minimum
7657 //*-* ERRDEF: the value of UP defining parameter uncertainties
7658 //*-* NPARI: the number of currently variable parameters
7659 //*-* NPARX: the highest (external) parameter number defined by user
7660 //*-* ISTAT: a status integer indicating how good is the covariance
7661 //*-* matrix: 0= not calculated at all
7662 //*-* 1= approximation only, not accurate
7663 //*-* 2= full matrix, but forced positive-definite
7664 //*-* 3= full accurate covariance matrix
7665 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7666 
7667  fmin = fAmin;
7668  fedm = fEDM;
7669  errdef = fUp;
7670  npari = fNpar;
7671  nparx = fNu;
7672  istat = fISW[1];
7673  if (fEDM == fBigedm) fedm = fUp;
7674  if (fAmin == fUndefi) {
7675  fmin = 0;
7676  fedm = fUp;
7677  istat = 0;
7678  }
7679 } /* mnstat_ */
7680 
7681 //______________________________________________________________________________
7683 {
7684 //*-*-*-*-*-*-*-*To find the machine precision*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7685 //*-* =============================
7686 //*-* Compares its argument with the value 1.0, and returns
7687 //*-* the value .TRUE. if they are equal. To find EPSMAC
7688 //*-* safely by foiling the Fortran optimizer
7689 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7690 
7691  epsbak = epsp1 - 1;
7692 } /* mntiny_ */
7693 
7694 //______________________________________________________________________________
7695 Bool_urt URMinuit::mnunpt(const string &cfname)
7696 {
7697 //*-*-*-*-*-*Returns .TRUE. if CFNAME contains unprintable characters*-*-*-*
7698 //*-* ========================================================
7699 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7700 
7701  Int_urt i, l, ic;
7702  Bool_urt ret_val;
7703  static string cpt = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./;:[]$%*_!@#&+()";
7704 
7705  ret_val = kurFALSE;
7706  l = strlen(cfname.c_str());
7707  for (i = 1; i <= l; ++i) {
7708  for (ic = 1; ic <= 80; ++ic) {
7709  if (cfname[i-1] == cpt[ic-1]) goto L100;
7710  }
7711  return kurTRUE;
7712 L100:
7713  ;
7714  }
7715  return ret_val;
7716 } /* mnunpt_ */
7717 
7718 //______________________________________________________________________________
7720 {
7721 //*-*-*-*-*-*-*-*-*-*-*-*Inverts a symmetric matrix*-*-*-*-*-*-*-*-*-*-*-*-*
7722 //*-* ==========================
7723 //*-* inverts a symmetric matrix. matrix is first scaled to
7724 //*-* have all ones on the diagonal (equivalent to change of units)
7725 //*-* but no pivoting is done since matrix is positive-definite.
7726 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7727 
7728  /* System generated locals */
7729  Int_urt a_offset;
7730 
7731  /* Local variables */
7732  Double_urt si;
7733  Int_urt i, j, k, kp1, km1;
7734 
7735  /* Parameter adjustments */
7736  a_offset = l + 1;
7737  a -= a_offset;
7738 
7739  /* Function Body */
7740  ifail = 0;
7741  if (n < 1) goto L100;
7742  if (n > fMaxint) goto L100;
7743 //*-*- scale matrix by sqrt of diag elements
7744  for (i = 1; i <= n; ++i) {
7745  si = a[i + i*l];
7746  if (si <= 0) goto L100;
7747  fVERTs[i-1] = 1 / URMath::Sqrt(si);
7748  }
7749  for (i = 1; i <= n; ++i) {
7750  for (j = 1; j <= n; ++j) {
7751  a[i + j*l] = a[i + j*l]*fVERTs[i-1]*fVERTs[j-1];
7752  }
7753  }
7754 //*-*- . . . start main loop . . . .
7755  for (i = 1; i <= n; ++i) {
7756  k = i;
7757 //*-*- preparation for elimination step1
7758  if (a[k + k*l] != 0) fVERTq[k-1] = 1 / a[k + k*l];
7759  else goto L100;
7760  fVERTpp[k-1] = 1;
7761  a[k + k*l] = 0;
7762  kp1 = k + 1;
7763  km1 = k - 1;
7764  if (km1 < 0) goto L100;
7765  else if (km1 == 0) goto L50;
7766  else goto L40;
7767 L40:
7768  for (j = 1; j <= km1; ++j) {
7769  fVERTpp[j-1] = a[j + k*l];
7770  fVERTq[j-1] = a[j + k*l]*fVERTq[k-1];
7771  a[j + k*l] = 0;
7772  }
7773 L50:
7774  if (k - n < 0) goto L51;
7775  else if (k - n == 0) goto L60;
7776  else goto L100;
7777 L51:
7778  for (j = kp1; j <= n; ++j) {
7779  fVERTpp[j-1] = a[k + j*l];
7780  fVERTq[j-1] = -a[k + j*l]*fVERTq[k-1];
7781  a[k + j*l] = 0;
7782  }
7783 //*-*- elimination proper
7784 L60:
7785  for (j = 1; j <= n; ++j) {
7786  for (k = j; k <= n; ++k) { a[j + k*l] += fVERTpp[j-1]*fVERTq[k-1]; }
7787  }
7788  }
7789 //*-*- elements of left diagonal and unscaling
7790  for (j = 1; j <= n; ++j) {
7791  for (k = 1; k <= j; ++k) {
7792  a[k + j*l] = a[k + j*l]*fVERTs[k-1]*fVERTs[j-1];
7793  a[j + k*l] = a[k + j*l];
7794  }
7795  }
7796  return;
7797 //*-*- failure return
7798 L100:
7799  ifail = 1;
7800 } /* mnvert_ */
7801 
7802 //______________________________________________________________________________
7803 void URMinuit::mnwarn(const char* copt1, const char* corg1, const char* cmes1)
7804 {
7805 //*-*-*-*-*-*-*-*-*-*-*-*Prints Warning messages*-*-*-*-*-*-*-*-*-*-*-*-*-*
7806 //*-* =======================
7807 //*-* If COPT='W', CMES is a WARning message from CORG.
7808 //*-* If COPT='D', CMES is a DEBug message from CORG.
7809 //*-* If SET WARnings is in effect (the default), this routine
7810 //*-* prints the warning message CMES coming from CORG.
7811 //*-* If SET NOWarnings is in effect, the warning message is
7812 //*-* stored in a circular buffer of length MAXMES.
7813 //*-* If called with CORG=CMES='SHO', it prints the messages in
7814 //*-* the circular buffer, FIFO, and empties the buffer.
7815 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7816 
7817  string copt = copt1;
7818  string corg = corg1;
7819  string cmes = cmes1;
7820 
7821  const Int_urt MAXMES = 10;
7822  Int_urt ityp, i, ic, nm;
7823  string englsh, ctyp;
7824 
7825  if (corg.substr(0,3) != "SHO" || cmes.substr(0,3) != "SHO") {
7826 
7827 //*-*- Either print warning or put in buffer
7828  if (copt == "W") {
7829  ityp = 1;
7830  if (fLwarn) {
7831  std::printf(" MINUIT WARNING IN %s\n",corg.c_str());
7832  std::printf(" ============== %s\n",cmes.c_str());
7833  return;
7834  }
7835  } else {
7836  ityp = 2;
7837  if (fLrepor) {
7838  std::printf(" MINUIT DEBUG FOR %s\n",corg.c_str());
7839  std::printf(" =============== %s \n",cmes.c_str());
7840  return;
7841  }
7842  }
7843 //*-*- if appropriate flag is off, fill circular buffer
7844  if (fNwrmes[ityp-1] == 0) fIcirc[ityp-1] = 0;
7845  ++fNwrmes[ityp-1];
7846  ++fIcirc[ityp-1];
7847  if (fIcirc[ityp-1] > 10) fIcirc[ityp-1] = 1;
7848  ic = fIcirc[ityp-1];
7849  fOrigin[ic] = corg;
7850  fWarmes[ic] = cmes;
7851  fNfcwar[ic] = fNfcn;
7852  return;
7853  }
7854 
7855 //*-*- 'SHO WARnings', ask if any suppressed mess in buffer
7856  if (copt == "W") {
7857  ityp = 1;
7858  ctyp = "WARNING";
7859  } else {
7860  ityp = 2;
7861  ctyp = "*DEBUG*";
7862  }
7863  if (fNwrmes[ityp-1] > 0) {
7864  englsh = " WAS SUPPRESSED. ";
7865  if (fNwrmes[ityp-1] > 1) englsh = "S WERE SUPPRESSED.";
7866  std::printf(" %5d MINUIT %s MESSAGE%s\n",fNwrmes[ityp-1]
7867  ,ctyp.c_str(),englsh.c_str());
7868  nm = fNwrmes[ityp-1];
7869  ic = 0;
7870  if (nm > MAXMES) {
7871  std::printf(" ONLY THE MOST RECENT 10 WILL BE LISTED BELOW.\n");
7872  nm = MAXMES;
7873  ic = fIcirc[ityp-1];
7874  }
7875  std::printf(" CALLS ORIGIN MESSAGE\n");
7876  for (i = 1; i <= nm; ++i) {
7877  ++ic;
7878  if (ic > MAXMES) ic = 1;
7879  std::printf(" %6d %s %s\n", fNfcwar[ic],fOrigin[ic].c_str(),fWarmes[ic].c_str());
7880  }
7881  fNwrmes[ityp-1] = 0;
7882  std::printf(" \n");
7883  }
7884 } /* mnwarn_ */
7885 
7886 //______________________________________________________________________________
7888 {
7889 //*-*-*-*-*-*-*-*Calculates the WERR, external parameter errors*-*-*-*-*-*-*
7890 //*-* ==============================================
7891 //*-* and the global correlation coefficients, to be called
7892 //*-* whenever a new covariance matrix is available.
7893 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7894 
7895  Double_urt denom, ba, al, dx, du1, du2;
7896  Int_urt ndex, ierr, i, j, k, l, ndiag, k1, iin;
7897 
7898 //*-*- calculate external error if v exists
7899  if (fISW[1] >= 1) {
7900  for (l = 1; l <= fNpar; ++l) {
7901  ndex = l*(l + 1) / 2;
7902  dx = URMath::Sqrt(URMath::Abs(fVhmat[ndex-1]*fUp));
7903  i = fNexofi[l-1];
7904 // if (fNvarl[i-1] > 1) {
7905  if (m_userParameterFlag[i] > 1) {
7906  al = fAlim[i-1];
7907  ba = fBlim[i-1] - al;
7908 // du1 = al + 0.5*(URMath::Sin(fX[l-1] + dx) + 1)*ba - fU[i-1];
7909 // du2 = al + 0.5*(URMath::Sin(fX[l-1] - dx) + 1)*ba - fU[i-1];
7910  du1 = al + 0.5*(URMath::Sin(fX[l-1] + dx) + 1)*ba - m_userParameterValue[i];
7911  du2 = al + 0.5*(URMath::Sin(fX[l-1] - dx) + 1)*ba - m_userParameterValue[i];
7912  if (dx > 1) du1 = ba;
7913  dx = 0.5*(URMath::Abs(du1) + URMath::Abs(du2));
7914  }
7915  fWerr[l-1] = dx;
7916  }
7917  }
7918 //*-*- global correlation coefficients
7919  if (fISW[1] >= 1) {
7920  for (i = 1; i <= fNpar; ++i) {
7921  fGlobcc[i-1] = 0;
7922  k1 = i*(i-1) / 2;
7923  for (j = 1; j <= i; ++j) {
7924  k = k1 + j;
7925  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[k-1];
7926  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
7927  }
7928  }
7929  mnvert(fP, fMaxint, fMaxint, fNpar, ierr);
7930  if (ierr == 0) {
7931  for (iin = 1; iin <= fNpar; ++iin) {
7932  ndiag = iin*(iin + 1) / 2;
7933  denom = fP[iin + iin*fMaxpar - fMaxpar-1]*fVhmat[ndiag-1];
7934  if (denom <= 1 && denom >= 0) fGlobcc[iin-1] = 0;
7935  else fGlobcc[iin-1] = URMath::Sqrt(1 - 1 / denom);
7936  }
7937  }
7938  }
7939 } /* mnwerr_ */
const char charal[29]
Definition: URMinuit.cc:35
Double_urt fUp
Definition: URMinuit.h:56
virtual void mnset()
Definition: URMinuit.cc:6919
Int_urt fMaxpar
Definition: URMinuit.h:45
Int_urt fIsyssa
Definition: URMinuit.h:140
Double_urt * fWerr
Definition: URMinuit.h:79
Int_urt fNstkwr
Definition: URMinuit.h:147
static Double_urt ASin(Double_urt)
Definition: URMath.h:472
Double_urt fYdircr
Definition: URMinuit.h:72
virtual void mncuve()
Definition: URMinuit.cc:1846
virtual void mnwerr()
Definition: URMinuit.cc:7887
virtual Int_urt FixParameter(Int_urt parNo)
Definition: URMinuit.cc:433
Double_urt * fErp
Definition: URMinuit.h:77
virtual void mnpars(const std::string &crdbuf, Int_urt &icondn)
Definition: URMinuit.cc:5780
Double_urt * fYpt
Definition: URMinuit.h:105
static Double_urt Sin(Double_urt)
Definition: URMath.h:454
void mnwarn(const char *copt1, const char *corg1, const char *cmes1)
Definition: URMinuit.cc:7803
Int_urt fStatus
Definition: URMinuit.h:161
Double_urt fUndefi
Definition: URMinuit.h:66
virtual void mnlims()
Definition: URMinuit.cc:4452
Int_urt fNfcwar[20]
Definition: URMinuit.h:159
Double_urt * fG2
Definition: URMinuit.h:88
virtual void mnmnos()
Definition: URMinuit.cc:5247
Double_urt fEpsi
Definition: URMinuit.h:59
Int_urt fNpfix
Definition: URMinuit.h:43
Double_urt * fMNOTxdev
Definition: URMinuit.h:120
virtual void mnhess()
Definition: URMinuit.cc:3796
virtual void mnemat(Double_urt *emat, Int_urt ndim)
Definition: URMinuit.cc:2232
Double_urt * fDirins
Definition: URMinuit.h:86
std::string fCtitl
Definition: URMinuit.h:174
Double_urt * fGRADgf
Definition: URMinuit.h:110
Double_urt * fCONTgcc
Definition: URMinuit.h:107
Double_urt fBigedm
Definition: URMinuit.h:67
std::string fCundef
Definition: URMinuit.h:176
Double_urt * fMNOTw
Definition: URMinuit.h:121
Double_urt fXdircr
Definition: URMinuit.h:71
virtual void mnpout(Int_urt iuext, std::string &chnam, Double_urt &val, Double_urt &err, Double_urt &xlolim, Double_urt &xuplim, Int_urt &iuint) const
Definition: URMinuit.cc:6151
Bool_urt fLrepor
Definition: URMinuit.h:165
Definition: URFcn.h:21
static Short_urt Max(Short_urt a, Short_urt b)
Definition: URMath.h:358
int Int_urt
Definition: URtypes.h:37
const Bool_urt kurFALSE
Definition: URtypes.h:76
Double_urt * fGlobcc
Definition: URMinuit.h:80
virtual Int_urt GetParameter(Int_urt parNo, Double_urt &currentValue, Double_urt &currentError) const
Definition: URMinuit.cc:448
Double_urt * fX
Definition: URMinuit.h:81
virtual Int_urt GetNumFreePars() const
Definition: URMinuit.cc:469
virtual void mntiny(Double_urt epsp1, Double_urt &epsbak)
Definition: URMinuit.cc:7682
Double_urt * fDirin
Definition: URMinuit.h:83
Double_urt fXmidcr
Definition: URMinuit.h:69
virtual void mnimpr()
Definition: URMinuit.cc:4120
Double_urt fVlimhi
Definition: URMinuit.h:65
Int_urt fMaxIterations
Definition: URMinuit.h:49
virtual void mnexcm(const std::string &command, Double_urt *plist, Int_urt llist, Int_urt &ierflg)
Definition: URMinuit.cc:2393
virtual void BuildArrays(Int_urt maxpar=15)
Definition: URMinuit.cc:164
Double_urt * fXs
Definition: URMinuit.h:84
virtual void mnseek()
Definition: URMinuit.cc:6821
static Short_urt Min(Short_urt a, Short_urt b)
Definition: URMath.h:332
virtual Int_urt DefineParameter(Int_urt parNo, const std::string &name, Double_urt initVal, Double_urt initErr, Double_urt lowerLimit, Double_urt upperLimit)
Definition: URMinuit.cc:288
Double_urt * fPSDFs
Definition: URMinuit.h:123
Double_urt * fVERTq
Definition: URMinuit.h:127
Int_urt fMaxpar2
Definition: URMinuit.h:52
Bool_urt mnunpt(const std::string &cfname)
Definition: URMinuit.cc:7695
Int_urt fNblock
Definition: URMinuit.h:150
virtual void mnexin(Double_urt *pint)
Definition: URMinuit.cc:2909
virtual Int_urt Migrad()
Definition: URMinuit.cc:486
Double_urt * fVthmat
Definition: URMinuit.h:97
virtual void mnfixp(Int_urt iint, Int_urt &ierr)
Definition: URMinuit.cc:2930
virtual Int_urt SetPrintLevel(Int_urt printLevel=0)
Definition: URMinuit.cc:564
Int_urt * fNexofi
Definition: URMinuit.h:135
static Double_urt Log10(Double_urt x)
Definition: URMath.h:496
char * fChpt
Definition: URMinuit.h:170
Double_urt * fMNOTgcc
Definition: URMinuit.h:122
Int_urt fISW[7]
Definition: URMinuit.h:148
Int_urt fNfcnlc
Definition: URMinuit.h:154
Double_urt * fPARSplist
Definition: URMinuit.h:131
Double_urt fFval3
Definition: URMinuit.h:58
virtual void mnvert(Double_urt *a, Int_urt l, Int_urt m, Int_urt n, Int_urt &ifail)
Definition: URMinuit.cc:7719
virtual void mnrn15(Double_urt &val, Int_urt &inseed)
Definition: URMinuit.cc:6626
URFcn * fFCN
Definition: URMinuit.h:181
Double_urt * fVhmat
Definition: URMinuit.h:95
Double_urt * fMIGRvg
Definition: URMinuit.h:118
unsigned int uint
Definition: URMinuit.cc:33
Double_urt * fHESSyy
Definition: URMinuit.h:111
Double_urt * fSecDer
Definition: URMinuit.h:96
virtual Int_urt GetNumFixedPars() const
Definition: URMinuit.cc:461
Int_urt fMaxpar5
Definition: URMinuit.h:50
Double_urt * fFIXPyy
Definition: URMinuit.h:109
Double_urt * fGrd
Definition: URMinuit.h:87
static Double_urt ATan(Double_urt)
Definition: URMath.h:478
Double_urt * fMATUvline
Definition: URMinuit.h:114
static Double_urt Log(Double_urt x)
Definition: URMath.h:493
virtual void mnpint(Double_urt &pexti, Int_urt i, Double_urt &pinti)
Definition: URMinuit.cc:5940
Double_urt fYmidcr
Definition: URMinuit.h:70
Int_urt fIstkwr[10]
Definition: URMinuit.h:146
Int_urt fMaxcpt
Definition: URMinuit.h:51
Double_urt * fMIGRgs
Definition: URMinuit.h:117
Double_urt * fSEEKxbest
Definition: URMinuit.h:125
virtual void mnrset(Int_urt iopt)
Definition: URMinuit.cc:6655
virtual void mnsimp()
Definition: URMinuit.cc:7445
Double_urt * fGsteps
Definition: URMinuit.h:94
Double_urt * fAlim
Definition: URMinuit.h:75
Double_urt fUpdflt
Definition: URMinuit.h:68
virtual void mndxdi(Double_urt pint, Int_urt ipar, Double_urt &dxdi)
Definition: URMinuit.cc:2023
const Int_urt kDefaultMaximumInternalParameters
Definition: URMinuit.cc:36
virtual Int_urt Release(Int_urt parNo)
Definition: URMinuit.cc:531
Bool_urt fLphead
Definition: URMinuit.h:169
std::string fCword
Definition: URMinuit.h:175
Double_urt * fPstst
Definition: URMinuit.h:100
Double_urt * fGin
Definition: URMinuit.h:90
Double_urt * fP
Definition: URMinuit.h:98
virtual void mnderi()
Definition: URMinuit.cc:1896
virtual void mnsave()
Definition: URMinuit.cc:6693
virtual void mngrad()
Definition: URMinuit.cc:3133
const Bool_urt kurTRUE
Definition: URtypes.h:75
Double_urt * fIMPRy
Definition: URMinuit.h:113
virtual void mnrazz(Double_urt ynew, Double_urt *pnew, Double_urt *y, Int_urt &jh, Int_urt &jl)
Definition: URMinuit.cc:6579
Double_urt * fGstep
Definition: URMinuit.h:89
virtual void mneig(Double_urt *a, Int_urt ndima, Int_urt n, Int_urt mits, Double_urt *work, Double_urt precis, Int_urt &ifault)
Definition: URMinuit.cc:2041
virtual void mnhes1()
Definition: URMinuit.cc:4042
Int_urt fIstrat
Definition: URMinuit.h:157
static Double_urt Sqrt(Double_urt x)
Definition: URMath.h:484
Double_urt * fXpt
Definition: URMinuit.h:104
virtual void mnparm(Int_urt k, const std::string &cnamj, Double_urt uk, Double_urt wk, Double_urt a, Double_urt b, Int_urt &ierflg)
Definition: URMinuit.cc:5543
Int_urt * fIpfix
Definition: URMinuit.h:136
Double_urt * fDgrd
Definition: URMinuit.h:91
virtual void mnhelp()
Definition: URMinuit.cc:3202
Bool_urt fLnolim
Definition: URMinuit.h:167
virtual void mncont(Int_urt ke1, Int_urt ke2, Int_urt nptu, Double_urt *xptu, Double_urt *yptu, Int_urt &ierrf)
Definition: URMinuit.cc:1045
Double_urt fDcovar
Definition: URMinuit.h:61
Int_urt fEmpty
Definition: URMinuit.h:44
virtual void mnfree(Int_urt k)
Definition: URMinuit.cc:3013
Double_urt * fPrho
Definition: URMinuit.h:102
static Double_urt Power(Double_urt x, Double_urt y)
Definition: URMath.h:490
Double_urt * fMIGRflnu
Definition: URMinuit.h:115
Double_urt * fMIGRstep
Definition: URMinuit.h:116
const string kUndefinedParameterName(")UNDEFINED")
virtual void mnline(Double_urt *start, Double_urt fstart, Double_urt *step, Double_urt slope, Double_urt toler)
Definition: URMinuit.cc:4573
virtual Int_urt Minos()
Definition: URMinuit.cc:516
Double_urt fEDM
Definition: URMinuit.h:57
Double_urt * fG2s
Definition: URMinuit.h:93
Int_urt fItaur
Definition: URMinuit.h:156
Bool_urt fLimset
Definition: URMinuit.h:166
virtual void mnpsdf()
Definition: URMinuit.cc:6501
std::string fWarmes[kMAXWARN]
Definition: URMinuit.h:180
Double_urt * fCONTw
Definition: URMinuit.h:108
Double_urt * fCOMDplist
Definition: URMinuit.h:130
Double_urt * fXts
Definition: URMinuit.h:85
Int_urt fNfcnmx
Definition: URMinuit.h:153
Double_urt fVlimlo
Definition: URMinuit.h:64
Bool_urt fLnewmn
Definition: URMinuit.h:168
virtual void mnerrs(Int_urt number, Double_urt &eplus, Double_urt &eminus, Double_urt &eparab, Double_urt &gcc)
Definition: URMinuit.cc:2309
static Short_urt Abs(Short_urt d)
Definition: URMath.h:298
virtual void mncler()
Definition: URMinuit.cc:713
virtual void mninit(Int_urt i1, Int_urt i2, Int_urt i3)
Definition: URMinuit.cc:4360
Double_urt * fVERTs
Definition: URMinuit.h:128
std::string fCvrsn
Definition: URMinuit.h:177
virtual Int_urt Command(const char *command)
Definition: URMinuit.cc:257
Int_urt fNfcn
Definition: URMinuit.h:152
Int_urt fMaxint
Definition: URMinuit.h:46
Int_urt fMaxext
Definition: URMinuit.h:48
virtual void mncros(Double_urt &aopt, Int_urt &iercr)
Definition: URMinuit.cc:1504
Int_urt fKe2cr
Definition: URMinuit.h:163
Int_urt fIsyswr
Definition: URMinuit.h:139
Double_urt fAmin
Definition: URMinuit.h:55
Double_urt * fSEEKxmid
Definition: URMinuit.h:124
std::string fOrigin[kMAXWARN]
Definition: URMinuit.h:179
Double_urt fEpsma2
Definition: URMinuit.h:63
Int_urt fNu
Definition: URMinuit.h:137
std::string fCstatu
Definition: URMinuit.h:173
const Int_urt kDefaultMaximumExternalParameters
Definition: URMinuit.cc:37
Double_urt * fPstar
Definition: URMinuit.h:99
Int_urt fIdbg[11]
Definition: URMinuit.h:149
double Double_urt
Definition: URtypes.h:50
virtual void mninex(Double_urt *pint)
Definition: URMinuit.cc:4336
Double_urt * fBlim
Definition: URMinuit.h:76
virtual Int_urt GetNumPars() const
Definition: URMinuit.cc:477
Double_urt * fGrds
Definition: URMinuit.h:92
virtual void mncntr(Int_urt ke1, Int_urt ke2, Int_urt &ierrf)
Definition: URMinuit.cc:747
virtual void mnmatu(Int_urt kode)
Definition: URMinuit.cc:4817
virtual void DeleteArrays()
Definition: URMinuit.cc:301
virtual Int_urt Hesse()
Definition: URMinuit.cc:501
Double_urt * fIMPRdsav
Definition: URMinuit.h:112
Int_urt fNpagwd
Definition: URMinuit.h:141
Int_urt fNewpag
Definition: URMinuit.h:143
virtual void mnstat(Double_urt &fmin, Double_urt &fedm, Double_urt &errdef, Int_urt &npari, Int_urt &nparx, Int_urt &istat)
Definition: URMinuit.cc:7648
Int_urt fNpar
Definition: URMinuit.h:47
bool parameterFixed(Int_urt parameterNumber)
Definition: URMinuit.cc:419
virtual void mnscan()
Definition: URMinuit.cc:6706
virtual void mncrck(std::string crdbuf, Int_urt maxcwd, std::string &comand, Int_urt &lnc, Int_urt mxp, Double_urt *plist, Int_urt &llist, Int_urt &ierr, Int_urt isyswr)
Definition: URMinuit.cc:1376
std::string fCfrom
Character to be plotted at the X,Y contour positions.
Definition: URMinuit.h:172
Bool_urt fLwarn
Definition: URMinuit.h:164
bool Bool_urt
Definition: URtypes.h:52
virtual void mnpfit(Double_urt *parx2p, Double_urt *pary2p, Int_urt npar2p, Double_urt *coef2p, Double_urt &sdev2p)
Definition: URMinuit.cc:5871
Int_urt fNfcnfr
Definition: URMinuit.h:155
Int_urt fKe1cr
Definition: URMinuit.h:162
std::string fCovmes[4]
Definition: URMinuit.h:178
virtual void mnprin(Int_urt inkode, Double_urt fval)
Definition: URMinuit.cc:6215
Double_urt * fWord7
Definition: URMinuit.h:103
virtual Int_urt SetErrorDef(Double_urt up)
Definition: URMinuit.cc:545
Double_urt * fSIMPy
Definition: URMinuit.h:126
virtual void mnmnot(Int_urt ilax, Int_urt ilax2, Double_urt &val2pl, Double_urt &val2mi)
Definition: URMinuit.cc:5326
virtual void mnmigr()
Definition: URMinuit.cc:4904
Int_urt fIcirc[2]
Definition: URMinuit.h:160
Int_urt fNwrmes[2]
Definition: URMinuit.h:158
virtual void SetMaxIterations(Int_urt maxiter=5000)
Definition: URMinuit.h:278
virtual ~URMinuit()
Definition: URMinuit.cc:84
Int_urt fNpagln
Definition: URMinuit.h:142
virtual void mnamin()
Definition: URMinuit.cc:575
virtual Int_urt Eval(Int_urt npar, Double_urt *grad, Double_urt &fval, const std::vector< Double_urt > &par, Int_urt flag)
Definition: URMinuit.cc:374
Double_urt * fMIGRxxs
Definition: URMinuit.h:119
virtual void mnbins(Double_urt a1, Double_urt a2, Int_urt naa, Double_urt &bl, Double_urt &bh, Int_urt &nb, Double_urt &bwid)
Definition: URMinuit.cc:600
Int_urt fNstkrd
Definition: URMinuit.h:145
Double_urt * fXt
Definition: URMinuit.h:82
Double_urt * fPbar
Definition: URMinuit.h:101
Double_urt fEpsmac
Definition: URMinuit.h:62
virtual void mncalf(Double_urt *pvec, Double_urt &ycalf)
Definition: URMinuit.cc:676
virtual void mneval(Double_urt anext, Double_urt &fnext, Int_urt &ierev)
Definition: URMinuit.cc:2357
virtual void mncomd(const std::string &crdbin, Int_urt &icondn)
Definition: URMinuit.cc:952
Int_urt fMaxpar1
Definition: URMinuit.h:53
Double_urt * fErn
Definition: URMinuit.h:78
Double_urt * fVERTpp
Definition: URMinuit.h:129
Double_urt fApsi
Definition: URMinuit.h:60
virtual void SetFCN(URFcn *fcn)
Definition: URMinuit.cc:555
Int_urt fIsysrd
Definition: URMinuit.h:138
virtual void mnplot(Double_urt *xpt, Double_urt *ypt, char *chpt, Int_urt nxypt, Int_urt npagwd, Int_urt npagln)
Definition: URMinuit.cc:5985
virtual void zeroPointers()
Definition: URMinuit.cc:94
URMinuit()
Definition: URMinuit.cc:41
Int_urt fIcomnd
Definition: URMinuit.h:151
static Double_urt Cos(Double_urt)
Definition: URMath.h:457