ROOT  6.06/09
Reference Guide
TMinuit.cxx
Go to the documentation of this file.
1 // @(#)root/minuit:$Id$
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 
14  \defgroup MinuitOld TMinuit
15  \ingroup Math
16 
17  The Minuit Minimization package.
18  Direct C++ implementation of the Minuit minimization package.
19  This package was originally written in Fortran by Fred James
20  and part of PACKLIB (patch D506)
21  It has been converted to a C++ class, TMinuit, by R.Brun.
22 */
23 
24 /**
25  \class TMinuit
26 
27  Implementation in C++ of the Minuit package written by F. James.
28  Thjis is a straightforward conversion
29  of the original Fortran version.
30  The main changes are:
31 
32  - The variables in the various Minuit labelled common blocks
33  have been changed to the TMinuit class data members.
34  - The internal arrays with a maximum dimension depending on the
35  maximum number of parameters are now data members arrays with
36  a dynamic dimension such that one can fit very large problems
37  by simply initialising the TMinuit constructor with the maximum
38  number of parameters.
39  - The include file Minuit.h has been commented as much as possible
40  using existing comments in the code or the printed documentation
41  - The original Minuit subroutines are now member functions.
42  - Constructors and destructor have been added.
43  - Instead of passing the FCN function in the argument
44  list, the addresses of this function is stored as pointer
45  in the data members of the class. This is by far more elegant
46  and flexible in an interactive environment.
47  The member function SetFCN can be used to define this pointer.
48  - The ROOT static function Printf is provided to replace all
49  format statements and to print on currently defined output file.
50  - The functions SetObjectFit(TObject * obj)/GetObjectFit() can be
51  used inside the FCN function to set/get a referenced object
52  instead of using global variables.
53 
54 <P>
55 <H2><A NAME=H2Basic-concepts-of-MINUIT.html>Basic concepts of MINUIT</A></H2>
56 <P>
57 The <A HREF="http://wwwinfo.cern.ch/asdoc/minuit/minmain.html"> MINUIT</A> package acts on a multiparameter Fortran function to which one
58 must give the generic name <TT>FCN</TT>. In the ROOT implementation,
59 the function <TT>FCN</TT> is defined via the MINUIT SetFCN member function
60 when an Histogram.Fit command is invoked.
61 The value of <TT>FCN</TT> will in general depend on one
62 or more variable parameters.
63 <P>
64 To take a simple example, in case of ROOT histograms (classes TH1C,TH1S,TH1F,TH1D)
65 the Fit function defines the Minuit fitting function as being H1FitChisquare
66 or H1FitLikelihood depending on the options selected.
67 H1FitChisquare
68 calculates the chisquare between the user fitting function (gaussian, polynomial,
69 user defined,etc) and the data for given values of the parameters.
70 It is the task of MINUIT to find those values of the parameters
71 which give the lowest value of chisquare.
72 <P>
73 <H3>Basic concepts - The transformation for parameters with limits.</H3>
74 <P>
75 For variable parameters with limits, MINUIT uses the following
76 transformation:
77 <P>
78 <PRE>
79  P = arcsin(2((P -a)/(b- a))-1) P = a+((b- a)/(2))(sinP +1)
80  int ext ext int
81 </PRE>
82 <P>
83 so that the internal value P can take on any value, while the external
84  int
85 value P can take on values only between the lower limit a and the
86  ext
87 upper limit b. Since the transformation is necessarily non-linear, it
88 would transform a nice linear problem into a nasty non-linear one, which
89 is the reason why limits should be avoided if not necessary. In addition,
90 the transformation does require some computer time, so it slows down the
91 computation a little bit, and more importantly, it introduces additional
92 numerical inaccuracy into the problem in addition to what is introduced in
93 the numerical calculation of the <TT>FCN</TT> value. The effects of
94 non-linearity and numerical roundoff both become more important as the
95 external value gets closer to one of the limits (expressed as the distance
96 to nearest limit divided by distance between limits). The user must
97 therefore be aware of the fact that, for example, if they put limits of
98 (0,10^10 ) on a parameter, then the values 0.0 and 1. 0 will be
99 indistinguishable to the accuracy of most machines.
100 <P>
101 The transformation also affects the parameter error matrix, of course, so
102 MINUIT does a transformation of the error matrix (and the ``parabolic''
103 parameter errors) when there are parameter limits. Users should however
104 realize that the transformation is only a linear approximation, and that
105 it cannot give a meaningful result if one or more parameters is very close
106 to a limit, where partial Pext /partial Pint #0. Therefore, it is
107 recommended that:
108 <P>
109 <OL>
110 <LI>Limits on variable parameters should be used only when needed in order
111 to prevent the parameter from taking on unphysical values.
112 <LI>When a satisfactory minimum has been found using limits, the limits
113 should then be removed if possible, in order to perform or re-perform the
114 error analysis without limits.
115 </OL>
116 <P>
117 <H3>How to get the right answer from MINUIT.</H3>
118 <P>
119 MINUIT offers the user a choice of several minimization algorithms. The
120 MIGRAD algorithm is in general the best minimizer for
121 nearly all functions. It is a variable-metric method with inexact line
122 search, a stable metric updating scheme, and checks for
123 positive-definiteness. Its main weakness is that it depends heavily on
124 knowledge of the first derivatives, and fails miserably if they are very
125 inaccurate.
126 <P>
127 If parameter limits are needed, in spite of the side effects, then the
128 user should be aware of the following techniques to alleviate problems
129 caused by limits:
130 <P>
131 <H4>Getting the right minimum with limits.</H4>
132 <P>
133 If MIGRAD converges normally to a point where no parameter is near one of
134 its limits, then the existence of limits has probably not prevented MINUIT
135 from finding the right minimum. On the other hand, if one or more
136 parameters is near its limit at the minimum, this may be because the true
137 minimum is indeed at a limit, or it may be because the minimizer has
138 become ``blocked'' at a limit. This may normally happen only if the
139 parameter is so close to a limit (internal value at an odd multiple of #((pi)/(2))
140 that MINUIT prints a warning to this effect when it prints
141 the parameter values.
142 
143 The minimizer can become blocked at a limit, because at a limit the
144 derivative seen by the minimizer partial F/partial Pint is zero no matter
145 what the real derivative partial F/partial Pext is.
146 <P>
147 <P>
148 <PRE>
149 ((partial F)/(partial P ))= ((partial F)/(partial P ))((partial P )/(partial P )) =((partial F)/(partial P ))= 0
150  int ext ext int ext
151 </PRE>
152 <P>
153 <P>
154 <H4>Getting the right parameter errors with limits.</H4>
155 <P>
156 In the best case, where the minimum is far from any limits, MINUIT will
157 correctly transform the error matrix, and the parameter errors it reports
158 should be accurate and very close to those you would have got without
159 limits. In other cases (which should be more common, since otherwise you
160 wouldn't need limits), the very meaning of parameter errors becomes
161 problematic. Mathematically, since the limit is an absolute constraint on
162 the parameter, a parameter at its limit has no error, at least in one
163 direction. The error matrix, which can assign only symmetric errors, then
164 becomes essentially meaningless.
165 <P>
166 <H3>Interpretation of Parameter Errors:</H3>
167 <P>
168 There are two kinds of problems that can arise: the reliability of
169 MINUIT's error estimates, and their statistical interpretation, assuming
170 they are accurate.
171 <P>
172 <H3>Statistical interpretation:</H3>
173 <P>
174 For discussuion of basic concepts, such as the meaning of the elements of
175 the error matrix, or setting of exact confidence levels see:
176 <ol>
177  <li>F.James.
178  Determining the statistical Significance of experimental Results.
179  Technical Report DD/81/02 and CERN Report 81-03, CERN, 1981.</li>
180 
181  <li>W.T.Eadie, D.Drijard, F.James, M.Roos, and B.Sadoulet.
182  Statistical Methods in Experimental Physics.
183  North-Holland, 1971.</li>
184 </ol>
185 <P>
186 <H3>Reliability of MINUIT error estimates.</H3>
187 <P>
188 MINUIT always carries around its own current estimates of the parameter
189 errors, which it will print out on request, no matter how accurate they
190 are at any given point in the execution. For example, at initialization,
191 these estimates are just the starting step sizes as specified by the user.
192 After a HESSE step, the errors are usually quite accurate,
193 unless there has been a problem. MINUIT, when it prints out error values,
194 also gives some indication of how reliable it thinks they are. For
195 example, those marked <TT>CURRENT GUESS ERROR</TT> are only working values
196 not to be believed, and <TT>APPROXIMATE ERROR</TT> means that they have
197 been calculated but there is reason to believe that they may not be
198 accurate.
199 <P>
200 If no mitigating adjective is given, then at least MINUIT believes the
201 errors are accurate, although there is always a small chance that MINUIT
202 has been fooled. Some visible signs that MINUIT may have been fooled are:
203 <P>
204 <OL>
205 <LI>Warning messages produced during the minimization or error analysis.
206 <LI>Failure to find new minimum.
207 <LI>Value of <TT>EDM</TT> too big (estimated Distance to Minimum).
208 <LI>Correlation coefficients exactly equal to zero, unless some parameters
209 are known to be uncorrelated with the others.
210 <LI>Correlation coefficients very close to one (greater than 0.99). This
211 indicates both an exceptionally difficult problem, and one which has been
212 badly parameterized so that individual errors are not very meaningful
213 because they are so highly correlated.
214 <LI>Parameter at limit. This condition, signalled by a MINUIT warning
215 message, may make both the function minimum and parameter errors
216 unreliable. See the discussion above ``Getting the right parameter errors
217 with limits''.
218 </OL>
219 <P>
220 The best way to be absolutely sure of the errors, is to use
221 ``independent'' calculations and compare them, or compare the calculated
222 errors with a picture of the function. Theoretically, the covariance
223 matrix for a ``physical'' function must be positive-definite at the
224 minimum, although it may not be so for all points far away from the
225 minimum, even for a well-determined physical problem. Therefore, if MIGRAD
226 reports that it has found a non-positive-definite covariance matrix, this
227 may be a sign of one or more of the following:
228 <P>
229 <H5>A non-physical region:</H5>
230 <P>
231 On its way to the minimum, MIGRAD may have traversed a region which has
232 unphysical behaviour, which is of course not a serious problem as long as
233 it recovers and leaves such a region.
234 <P>
235 <H5>An underdetermined problem:</H5>
236 <P>
237 If the matrix is not positive-definite even at the minimum, this may mean
238 that the solution is not well-defined, for example that there are more
239 unknowns than there are data points, or that the parameterization of the
240 fit contains a linear dependence. If this is the case, then MINUIT (or any
241 other program) cannot solve your problem uniquely, and the error matrix
242 will necessarily be largely meaningless, so the user must remove the
243 underdeterminedness by reformulating the parameterization. MINUIT cannot
244 do this itself.
245 <P>
246 <H5>Numerical inaccuracies:</H5>
247 <P>
248 It is possible that the apparent lack of positive-definiteness is in fact
249 only due to excessive roundoff errors in numerical calculations in the
250 user function or not enough precision. This is unlikely in general, but
251 becomes more likely if the number of free parameters is very large, or if
252 
253 the parameters are badly scaled (not all of the same order of magnitude),
254 and correlations are also large. In any case, whether the
255 non-positive-definiteness is real or only numerical is largely irrelevant,
256 since in both cases the error matrix will be unreliable and the minimum
257 suspicious.
258 <P>
259 <H5>An ill-posed problem:</H5>
260 <P>
261 For questions of parameter dependence, see the discussion above on
262 positive-definiteness.
263 <P>
264 Possible other mathematical problems are the following:
265 <P>
266 <H5>Excessive numerical roundoff:</H5>
267 <P>
268 Be especially careful of exponential and factorial functions which get big
269 very quickly and lose accuracy.
270 <P>
271 <H5>Starting too far from the solution:</H5>
272 <P>
273 The function may have unphysical local minima, especially at infinity in
274 some variables.
275 
276 <H5>Minuit parameter errors in the presence of limits</H5>
277 This concerns the way Minuit reports the symmetric (or parabolic) errors
278 on parameters. It does not apply to the errors reported from Minos, which
279 are in general asymmetric.
280 <P>
281 The symmetric errors reported by Minuit are always calculated from
282 the covariance matrix, assuming that this matrix has been calculated,
283 usually as the result of a Migrad minimization or a direct
284 calculation by Hesse which inverts the second derivative matrix.
285 <P>
286 When there are no limits on the parameter in question, the error reported
287 by Minuit should therefore be exactly equal to the square root of the
288 corresponding diagonal element of the error matrix reported by Minuit.
289 <P>
290 However, when there are limits on the parameter, there is a transformation
291 between the internal parameter values seen by Minuit (which are unbounded)
292 and the external parameter values seen by the user in FCN (which remain
293 inside the desired limits). Therefore the internal error matrix kept by
294 Minuit must be transformed to an external error matrix for the user.
295 This is done by multiplying the (I,J)th element by DEXDIN(I)*DEXDIN(J),
296 where DEXDIN is the derivative of the external value with respect to the
297 internal value at the minimum. This is a linearization of the
298 transformation, and is the only way to produce an error matrix in external
299 coordinates meaningful to the user. But when reporting the individual
300 parabolic errors for limited parameters, Minuit can do a little better, so
301 it does. In this case, Minuit actually transforms the ends of the
302 internal "error bar" to external coordinates and reports the length of
303 this transformed interval. Strictly speaking, it is now asymmetric, but
304 since the origin of the asymmetry is only an artificial transformation it
305 does not make much sense, so the transformed errors are symmetrized.
306 <P>
307 The result of all the above is that for parameters with limits, the error
308 reported by Minuit is not exactly equal to the square root of the diagonal
309 element of the error matrix. The difference is a measure of how much the
310 limits deform the problem. If possible, it is suggested not to use limits
311 on parameters, and the problem goes away. If for some reason limits are
312 necessary, and you are sensitive to the difference between the two ways of
313 calculating the errors, it is suggested to use Minos errors which take
314 into account the non-linearities much more precisely.
315 
316 @ingroup MinuitOld
317 
318 */
319 
320 #include <stdlib.h>
321 #include <stdio.h>
322 
323 #include "TROOT.h"
324 #include "TMinuit.h"
325 #include "TMath.h"
326 #include "TError.h"
327 #include "TPluginManager.h"
328 #include "TClass.h"
329 #include "TInterpreter.h"
330 
332 
333 const char charal[29] = " .ABCDEFGHIJKLMNOPQRSTUVWXYZ";
334 
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 ///*-*-*-*-*-*-*-*-*-*-*Minuit normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
339 ///*-* ========================
340 
341 TMinuit::TMinuit(): TNamed("MINUIT","The Minimization package")
342 {
343  if (TMinuit::Class()->IsCallingNew() != TClass::kRealNew) {
344  //preset all pointers to null
345  fCpnam = 0;
346  fU = 0;
347  fAlim = 0;
348  fBlim = 0;
349  fPstar = 0;
350  fGin = 0;
351  fNvarl = 0;
352  fNiofex = 0;
353 
354  fNexofi = 0;
355  fIpfix = 0;
356  fErp = 0;
357  fErn = 0;
358  fWerr = 0;
359  fGlobcc = 0;
360  fX = 0;
361  fXt = 0;
362  fDirin = 0;
363  fXs = 0;
364  fXts = 0;
365  fDirins = 0;
366  fGrd = 0;
367  fG2 = 0;
368  fGstep = 0;
369  fDgrd = 0;
370  fGrds = 0;
371  fG2s = 0;
372  fGsteps = 0;
373  fPstst = 0;
374  fPbar = 0;
375  fPrho = 0;
376  fWord7 = 0;
377  fVhmat = 0;
378  fVthmat = 0;
379  fP = 0;
380  fXpt = 0;
381  fYpt = 0;
382  fChpt = 0;
383  fCONTgcc = 0;
384  fCONTw = 0;
385  fFIXPyy = 0;
386  fGRADgf = 0;
387  fHESSyy = 0;
388  fIMPRdsav = 0;
389  fIMPRy = 0;
390  fMATUvline = 0;
391  fMIGRflnu = 0;
392  fMIGRstep = 0;
393  fMIGRgs = 0;
394  fMIGRvg = 0;
395  fMIGRxxs = 0;
396  fMNOTxdev = 0;
397  fMNOTw = 0;
398  fMNOTgcc = 0;
399  fPSDFs = 0;
400  fSEEKxmid = 0;
401  fSEEKxbest = 0;
402  fSIMPy = 0;
403  fVERTq = 0;
404  fVERTs = 0;
405  fVERTpp = 0;
406  fCOMDplist = 0;
407  fPARSplist = 0;
408 
409  fUp = 0;
410  fEpsi = 0;
411  fApsi = 0;
412  fXmidcr = 0;
413  fYmidcr = 0;
414  fXdircr = 0;
415  fYdircr = 0;
416 
417  fStatus = 0;
418  fEmpty = 0;
419  fObjectFit = 0;
420  fMethodCall = 0;
421  fPlot = 0;
422  fGraphicsMode = kTRUE;
423 
424  } else {
425  BuildArrays(25);
426 
427  fUp = 0;
428  fEpsi = 0;
429  fApsi = 0;
430  fXmidcr = 0;
431  fYmidcr = 0;
432  fXdircr = 0;
433  fYdircr = 0;
434 
435  fStatus = 0;
436  fEmpty = 0;
437  fObjectFit = 0;
438  fMethodCall = 0;
439  fPlot = 0;
440  fGraphicsMode = kTRUE;
441  SetMaxIterations();
442  mninit(5,6,7);
443  }
444 
445  fFCN = 0;
446  {
448  gROOT->GetListOfSpecials()->Add(this);
449  }
450  gMinuit = this;
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 ///*-*-*-*-*-*-*-*-*-*-*Minuit normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
455 ///*-* ========================
456 ///
457 /// maxpar is the maximum number of parameters used with this TMinuit object.
458 
459 TMinuit::TMinuit(Int_t maxpar): TNamed("MINUIT","The Minimization package")
460 {
461  fFCN = 0;
462 
463  BuildArrays(maxpar);
464 
465  fStatus = 0;
466  fEmpty = 0;
467  fObjectFit = 0;
468  fMethodCall = 0;
469  fPlot = 0;
472 
473  mninit(5,6,7);
474  {
476  gROOT->GetListOfSpecials()->Add(this);
477  }
478  gMinuit = this;
479 }
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 /// Private TMinuit copy ctor. TMinuit can not be copied.
483 
484 TMinuit::TMinuit(const TMinuit &minuit) : TNamed(minuit)
485 {
486  Error("TMinuit", "can not copy construct TMinuit");
487 }
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 ///*-*-*-*-*-*-*-*-*-*-*Minuit default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
491 ///*-* =========================
492 
494 {
495  DeleteArrays();
496  delete fPlot;
497  delete fMethodCall;
498  {
500  if (gROOT != 0 && gROOT->GetListOfSpecials() != 0) gROOT->GetListOfSpecials()->Remove(this);
501  }
502  if (gMinuit == this) gMinuit = nullptr;
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 ///*-*-*-*-*-*-*Create internal Minuit arrays for the maxpar parameters*-*-*-*
507 ///*-* =======================================================
508 
510 {
511  fMaxpar = 25;
512  if (maxpar >= fMaxpar) fMaxpar = maxpar+1;
513  fMaxpar1= fMaxpar*(fMaxpar+1);
514  fMaxpar2= 2*fMaxpar;
515  fMaxpar5= fMaxpar1/2;
516  fMaxcpt = 101;
517  fCpnam = new TString[fMaxpar2];
518  fU = new Double_t[fMaxpar2];
519  fAlim = new Double_t[fMaxpar2];
520  fBlim = new Double_t[fMaxpar2];
521  fPstar = new Double_t[fMaxpar2];
522  fGin = new Double_t[fMaxpar2];
523  fNvarl = new Int_t[fMaxpar2];
524  fNiofex = new Int_t[fMaxpar2];
525 
526  fNexofi = new Int_t[fMaxpar];
527  fIpfix = new Int_t[fMaxpar];
528  fErp = new Double_t[fMaxpar];
529  fErn = new Double_t[fMaxpar];
530  fWerr = new Double_t[fMaxpar];
531  fGlobcc = new Double_t[fMaxpar];
532  fX = new Double_t[fMaxpar];
533  fXt = new Double_t[fMaxpar];
534  fDirin = new Double_t[fMaxpar];
535  fXs = new Double_t[fMaxpar];
536  fXts = new Double_t[fMaxpar];
537  fDirins = new Double_t[fMaxpar];
538  fGrd = new Double_t[fMaxpar];
539  fG2 = new Double_t[fMaxpar];
540  fGstep = new Double_t[fMaxpar];
541  fDgrd = new Double_t[fMaxpar];
542  fGrds = new Double_t[fMaxpar];
543  fG2s = new Double_t[fMaxpar];
544  fGsteps = new Double_t[fMaxpar];
545  fPstst = new Double_t[fMaxpar];
546  fPbar = new Double_t[fMaxpar];
547  fPrho = new Double_t[fMaxpar];
548  fWord7 = new Double_t[fMaxpar];
549  fVhmat = new Double_t[fMaxpar5];
550  fVthmat = new Double_t[fMaxpar5];
551  fP = new Double_t[fMaxpar1];
552  fXpt = new Double_t[fMaxcpt];
553  fYpt = new Double_t[fMaxcpt];
554  fChpt = new char[fMaxcpt+1];
555  // initialisation of dynamic arrays used internally in some functions
556  // these arrays had a fix dimension in Minuit
557  fCONTgcc = new Double_t[fMaxpar];
558  fCONTw = new Double_t[fMaxpar];
559  fFIXPyy = new Double_t[fMaxpar];
560  fGRADgf = new Double_t[fMaxpar];
561  fHESSyy = new Double_t[fMaxpar];
562  fIMPRdsav = new Double_t[fMaxpar];
563  fIMPRy = new Double_t[fMaxpar];
564  fMATUvline = new Double_t[fMaxpar];
565  fMIGRflnu = new Double_t[fMaxpar];
566  fMIGRstep = new Double_t[fMaxpar];
567  fMIGRgs = new Double_t[fMaxpar];
568  fMIGRvg = new Double_t[fMaxpar];
569  fMIGRxxs = new Double_t[fMaxpar];
570  fMNOTxdev = new Double_t[fMaxpar];
571  fMNOTw = new Double_t[fMaxpar];
572  fMNOTgcc = new Double_t[fMaxpar];
573  fPSDFs = new Double_t[fMaxpar];
574  fSEEKxmid = new Double_t[fMaxpar];
575  fSEEKxbest = new Double_t[fMaxpar];
576  fSIMPy = new Double_t[fMaxpar];
577  fVERTq = new Double_t[fMaxpar];
578  fVERTs = new Double_t[fMaxpar];
579  fVERTpp = new Double_t[fMaxpar];
580  fCOMDplist = new Double_t[fMaxpar];
581  fPARSplist = new Double_t[fMaxpar];
582 
583  for (int i = 0; i < fMaxpar; i++) {
584  fErp[i] = 0;
585  fErn[i] = 0;
586  }
587 }
588 
589 
590 ////////////////////////////////////////////////////////////////////////////////
591 /// Make a clone of an object using the Streamer facility.
592 /// Function pointer is copied to Clone
593 
594 TObject *TMinuit::Clone(const char *newname) const
595 {
596  TMinuit *named = (TMinuit*)TNamed::Clone(newname);
597  named->fFCN=fFCN;
598  return named;
599 }
600 
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// execute a Minuit command
604 /// Equivalent to MNEXCM except that the command is given as a
605 /// character string.
606 /// See TMinuit::mnhelp for the full list of available commands
607 /// See also http://wwwasdoc.web.cern.ch/wwwasdoc/minuit/node18.html for
608 /// a complete documentation of all the available commands
609 ///
610 /// Returns the status of the execution:
611 /// = 0: command executed normally
612 /// 1: command is blank, ignored
613 /// 2: command line unreadable, ignored
614 /// 3: unknown command, ignored
615 /// 4: abnormal termination (e.g., MIGRAD not converged)
616 /// 5: command is a request to read PARAMETER definitions
617 /// 6: 'SET INPUT' command
618 /// 7: 'SET TITLE' command
619 /// 8: 'SET COVAR' command
620 /// 9: reserved
621 /// 10: END command
622 /// 11: EXIT or STOP command
623 /// 12: RETURN command
624 ///
625 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
626 
627 Int_t TMinuit::Command(const char *command)
628 {
629  Int_t status = 0;
630  mncomd(command,status);
631  return status;
632 }
633 
634 ////////////////////////////////////////////////////////////////////////////////
635 /// Creates a TGraph object describing the n-sigma contour of a
636 /// TMinuit fit. The contour of the parameters pa1 and pa2 is calculated
637 /// unsing npoints (>=4) points. The TMinuit status will be
638 /// 0 on success and
639 /// -1 if errors in the calling sequence (pa1, pa2 not variable)
640 /// 1 if less than four points can be found
641 /// 2 if npoints<4
642 /// n>3 if only n points can be found (n < npoints)
643 /// The status can be obtained via TMinuit::GetStatus().
644 ///
645 /// To get the n-sigma contour the ERRDEF parameter in Minuit has to set
646 /// to n^2. The fcn function has to be set before the routine is called.
647 ///
648 /// The TGraph object is created via the interpreter. The user must cast it
649 /// to a TGraph*. Note that the TGraph is created with npoints+1 in order to
650 /// close the contour (setting last point equal to first point).
651 ///
652 /// You can find an example in $ROOTSYS/tutorials/fit/fitcont.C
653 
655 {
656  if (npoints<4) {
657  // we need at least 4 points
658  fStatus= 2;
659  return (TObject *)0;
660  }
661  Int_t npfound;
662  Double_t *xcoor = new Double_t[npoints+1];
663  Double_t *ycoor = new Double_t[npoints+1];
664  mncont(pa1,pa2,npoints,xcoor,ycoor,npfound);
665  if (npfound<4) {
666  // mncont did go wrong
667  Warning("Contour","Cannot find more than 4 points, no TGraph returned");
668  fStatus= (npfound==0 ? 1 : npfound);
669  delete [] xcoor;
670  delete [] ycoor;
671  return (TObject *)0;
672  }
673  if (npfound!=npoints) {
674  // mncont did go wrong
675  Warning("Contour","Returning a TGraph with %d points only",npfound);
676  npoints = npfound;
677  }
678  fStatus=0;
679  // create graph via the PluginManager
680  xcoor[npoints] = xcoor[0]; // add first point at end to get closed polyline
681  ycoor[npoints] = ycoor[0];
682  TObject *gr = 0;
683  TPluginHandler *h;
684  if ((h = gROOT->GetPluginManager()->FindHandler("TMinuitGraph"))) {
685  if (h->LoadPlugin() != -1)
686  gr = (TObject*)h->ExecPlugin(3,npoints+1,xcoor,ycoor);
687  }
688  delete [] xcoor;
689  delete [] ycoor;
690  return gr;
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Define a parameter
695 
696 Int_t TMinuit::DefineParameter( Int_t parNo, const char *name, Double_t initVal, Double_t initErr, Double_t lowerLimit, Double_t upperLimit )
697 {
698  Int_t err;
699 
700  TString sname = name;
701  mnparm( parNo, sname, initVal, initErr, lowerLimit, upperLimit, err);
702 
703  return err;
704 }
705 
706 ////////////////////////////////////////////////////////////////////////////////
707 ///*-*-*-*-*-*-*-*-*-*-*-*Delete internal Minuit arrays*-*-*-*-*-*-*-*-*
708 ///*-* =============================
709 
711 {
712  if (fEmpty) return;
713  delete [] fCpnam;
714  delete [] fU;
715  delete [] fAlim;
716  delete [] fBlim;
717  delete [] fErp;
718  delete [] fErn;
719  delete [] fWerr;
720  delete [] fGlobcc;
721  delete [] fNvarl;
722  delete [] fNiofex;
723  delete [] fNexofi;
724  delete [] fX;
725  delete [] fXt;
726  delete [] fDirin;
727  delete [] fXs;
728  delete [] fXts;
729  delete [] fDirins;
730  delete [] fGrd;
731  delete [] fG2;
732  delete [] fGstep;
733  delete [] fGin;
734  delete [] fDgrd;
735  delete [] fGrds;
736  delete [] fG2s;
737  delete [] fGsteps;
738  delete [] fIpfix;
739  delete [] fVhmat;
740  delete [] fVthmat;
741  delete [] fP;
742  delete [] fPstar;
743  delete [] fPstst;
744  delete [] fPbar;
745  delete [] fPrho;
746  delete [] fWord7;
747  delete [] fXpt;
748  delete [] fYpt;
749  delete [] fChpt;
750 
751  delete [] fCONTgcc;
752  delete [] fCONTw;
753  delete [] fFIXPyy;
754  delete [] fGRADgf;
755  delete [] fHESSyy;
756  delete [] fIMPRdsav;
757  delete [] fIMPRy;
758  delete [] fMATUvline;
759  delete [] fMIGRflnu;
760  delete [] fMIGRstep;
761  delete [] fMIGRgs;
762  delete [] fMIGRvg;
763  delete [] fMIGRxxs;
764  delete [] fMNOTxdev;
765  delete [] fMNOTw;
766  delete [] fMNOTgcc;
767  delete [] fPSDFs;
768  delete [] fSEEKxmid;
769  delete [] fSEEKxbest;
770  delete [] fSIMPy;
771  delete [] fVERTq;
772  delete [] fVERTs;
773  delete [] fVERTpp;
774  delete [] fCOMDplist;
775  delete [] fPARSplist;
776 
777  fEmpty = 1;
778 }
779 
780 ////////////////////////////////////////////////////////////////////////////////
781 /// Evaluate the minimisation function
782 /// Input parameters:
783 /// npar: number of currently variable parameters
784 /// par: array of (constant and variable) parameters
785 /// flag: Indicates what is to be calculated (see example below)
786 /// grad: array of gradients
787 /// Output parameters:
788 /// fval: The calculated function value.
789 /// grad: The (optional) vector of first derivatives).
790 ///
791 /// The meaning of the parameters par is of course defined by the user,
792 /// who uses the values of those parameters to calculate their function value.
793 /// The starting values must be specified by the user.
794 /// Later values are determined by Minuit as it searches for the minimum
795 /// or performs whatever analysis is requested by the user.
796 ///
797 /// Note that this virtual function may be redefined in a class derived from TMinuit.
798 /// The default function calls the function specified in SetFCN
799 ///
800 /// Example of Minimisation function:
801 
803 {
804 /*
805  if (flag == 1) {
806  read input data,
807  calculate any necessary constants, etc.
808  }
809  if (flag == 2) {
810  calculate GRAD, the first derivatives of FVAL
811  (this is optional)
812  }
813  Always calculate the value of the function, FVAL,
814  which is usually a chisquare or log likelihood.
815  if (iflag == 3) {
816  will come here only after the fit is finished.
817  Perform any final calculations, output fitted data, etc.
818  }
819 */
820 // See concrete examples in TH1::H1FitChisquare, H1FitLikelihood
821 
822  if (fFCN) (*fFCN)(npar,grad,fval,par,flag);
823  return 0;
824 }
825 
826 ////////////////////////////////////////////////////////////////////////////////
827 /// fix a parameter
828 
830 {
831  Int_t err;
832  Double_t tmp[1];
833  tmp[0] = parNo+1; //set internal Minuit numbering
834 
835  mnexcm( "FIX", tmp, 1, err );
836 
837  return err;
838 }
839 
840 ////////////////////////////////////////////////////////////////////////////////
841 /// return parameter value and error
842 
843 Int_t TMinuit::GetParameter( Int_t parNo, Double_t &currentValue, Double_t &currentError ) const
844 {
845  Int_t err;
846  TString name; // ignored
847  Double_t bnd1, bnd2; // ignored
848 
849  mnpout( parNo, name, currentValue, currentError, bnd1, bnd2, err );
850 
851  return err;
852 }
853 
854 ////////////////////////////////////////////////////////////////////////////////
855 /// returns the number of currently fixed parameters
856 
858 {
859  return fNpfix;
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// returns the number of currently free parameters
864 
866 {
867  return fNpar;
868 }
869 
870 ////////////////////////////////////////////////////////////////////////////////
871 /// returns the total number of parameters that have been defined
872 /// as fixed or free. The constant parameters are not counted.
873 
875 {
876  return fNpar + fNpfix;
877 }
878 
879 ////////////////////////////////////////////////////////////////////////////////
880 /// invokes the MIGRAD minimizer
881 
883 {
884  Int_t err;
885  Double_t tmp[1];
886  tmp[0] = 0;
887 
888  mnexcm( "MIGRAD", tmp, 0, err );
889 
890  return err;
891 }
892 
893 ////////////////////////////////////////////////////////////////////////////////
894 /// release a parameter
895 
897 {
898  Int_t err;
899  Double_t tmp[1];
900  tmp[0] = parNo+1; //set internal Minuit numbering
901 
902  mnexcm( "RELEASE", tmp, 1, err );
903 
904  return err;
905 }
906 
907 ////////////////////////////////////////////////////////////////////////////////
908 /// To get the n-sigma contour the error def parameter "up" has to set to n^2.
909 
911 {
912  Int_t err;
913 
914  mnexcm( "SET ERRDEF", &up, 1, err );
915 
916  return err;
917 }
918 
919 ////////////////////////////////////////////////////////////////////////////////
920 ///*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-*
921 ///*-* ===============================================
922 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
923 
924 void TMinuit::SetFCN(void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
925 {
926  fFCN = fcn;
927 }
928 
929 ////////////////////////////////////////////////////////////////////////////////
930 ///*-*-*-*-*-*-*Static function called when SetFCN is called in interactive mode
931 ///*-* ===============================================
932 
933 void InteractiveFCNm(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
934 {
935  TMethodCall *m = gMinuit->GetMethodCall();
936  if (!m) return;
937 
938  Long_t args[5];
939  args[0] = (Long_t)&npar;
940  args[1] = (Long_t)gin;
941  args[2] = (Long_t)&f;
942  args[3] = (Long_t)u;
943  args[4] = (Long_t)flag;
944  m->SetParamPtrs(args);
946  m->Execute(result);
947 }
948 
949 ////////////////////////////////////////////////////////////////////////////////
950 ///*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-*
951 ///*-* ===============================================
952 /// this function is called by CINT instead of the function above
953 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
954 
955 void TMinuit::SetFCN(void *fcn)
956 {
957  if (!fcn) return;
958 
959  const char *funcname = gCling->Getp2f2funcname(fcn);
960  if (funcname) {
961  fMethodCall = new TMethodCall();
962  fMethodCall->InitWithPrototype(funcname,"Int_t&,Double_t*,Double_t&,Double_t*,Int_t");
963  }
965  gMinuit = this; //required by InteractiveFCNm
966 }
967 
968 ////////////////////////////////////////////////////////////////////////////////
969 ///set Minuit print level
970 /// printlevel = -1 quiet (also suppresse all warnings)
971 /// = 0 normal
972 /// = 1 verbose
973 
975 {
976  Int_t err;
977  Double_t tmp[1];
978  tmp[0] = printLevel;
979 
980  mnexcm( "SET PRINT", tmp, 1, err );
981 
982  if (printLevel <=-1) mnexcm("SET NOWarnings",tmp,0,err);
983 
984  return err;
985 }
986 
987 ////////////////////////////////////////////////////////////////////////////////
988 ///*-*-*-*-*-*-*-*-*-*-*-*-*Initialize AMIN*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
989 ///*-* ===============
990 ///*-*C Called from many places. Initializes the value of AMIN by
991 ///*-*C calling the user function. Prints out the function value and
992 ///*-*C parameter values if Print Flag value is high enough.
993 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
994 
996 {
997  /* Local variables */
998  Double_t fnew;
999  Int_t nparx;
1000 
1001  nparx = fNpar;
1002  if (fISW[4] >= 1) {
1003  Printf(" FIRST CALL TO USER FUNCTION AT NEW START POINT, WITH IFLAG=4.");
1004  }
1005  mnexin(fX);
1006  Eval(nparx, fGin, fnew, fU, 4); ++fNfcn;
1007  fAmin = fnew;
1008  fEDM = fBigedm;
1009 } /* mnamin_ */
1010 
1011 ////////////////////////////////////////////////////////////////////////////////
1012 ///*-*-*-*-*-*-*-*-*-*-*Compute reasonable histogram intervals*-*-*-*-*-*-*-*-*
1013 ///*-* ======================================
1014 ///*-* Function TO DETERMINE REASONABLE HISTOGRAM INTERVALS
1015 ///*-* GIVEN ABSOLUTE UPPER AND LOWER BOUNDS A1 AND A2
1016 ///*-* AND DESIRED MAXIMUM NUMBER OF BINS NAA
1017 ///*-* PROGRAM MAKES REASONABLE BINNING FROM BL TO BH OF WIDTH BWID
1018 ///*-* F. JAMES, AUGUST, 1974 , stolen for Minuit, 1988
1019 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1020 
1021 void TMinuit::mnbins(Double_t a1, Double_t a2, Int_t naa, Double_t &bl, Double_t &bh, Int_t &nb, Double_t &bwid)
1022 {
1023  /* Local variables */
1024  Double_t awid,ah, al, sigfig, sigrnd, alb;
1025  Int_t kwid, lwid, na=0, log_;
1026 
1027  al = TMath::Min(a1,a2);
1028  ah = TMath::Max(a1,a2);
1029  if (al == ah) ah = al + 1;
1030 
1031 //*-*- IF NAA .EQ. -1 , PROGRAM USES BWID INPUT FROM CALLING ROUTINE
1032  if (naa == -1) goto L150;
1033 L10:
1034  na = naa - 1;
1035  if (na < 1) na = 1;
1036 
1037 //*-*- GET NOMINAL BIN WIDTH IN EXPON FORM
1038 L20:
1039  awid = (ah-al) / Double_t(na);
1040  log_ = Int_t(TMath::Log10(awid));
1041  if (awid <= 1) --log_;
1042  sigfig = awid*TMath::Power(10, -log_);
1043 //*-*- ROUND MANTISSA UP TO 2, 2.5, 5, OR 10
1044  if (sigfig > 2) goto L40;
1045  sigrnd = 2;
1046  goto L100;
1047 L40:
1048  if (sigfig > 2.5) goto L50;
1049  sigrnd = 2.5;
1050  goto L100;
1051 L50:
1052  if (sigfig > 5) goto L60;
1053  sigrnd = 5;
1054  goto L100;
1055 L60:
1056  sigrnd = 1;
1057  ++log_;
1058 L100:
1059  bwid = sigrnd*TMath::Power(10, log_);
1060  goto L200;
1061 //*-*- GET NEW BOUNDS FROM NEW WIDTH BWID
1062 L150:
1063  if (bwid <= 0) goto L10;
1064 L200:
1065  alb = al / bwid;
1066  lwid = Int_t(alb);
1067  if (alb < 0) --lwid;
1068  bl = bwid*Double_t(lwid);
1069  alb = ah / bwid + 1;
1070  kwid = Int_t(alb);
1071  if (alb < 0) --kwid;
1072  bh = bwid*Double_t(kwid);
1073  nb = kwid - lwid;
1074  if (naa > 5) goto L240;
1075  if (naa == -1) return;
1076 //*-*- REQUEST FOR ONE BIN IS DIFFICULT CASE
1077  if (naa > 1 || nb == 1) return;
1078  bwid *= 2;
1079  nb = 1;
1080  return;
1081 L240:
1082  if (nb << 1 != naa) return;
1083  ++na;
1084  goto L20;
1085 } /* mnbins_ */
1086 
1087 ////////////////////////////////////////////////////////////////////////////////
1088 ///*-*-*-*-*-*-*-*-*-*Transform FCN to find further minima*-*-*-*-*-*-*-*-*-*
1089 ///*-* ====================================
1090 ///*-* Called only from MNIMPR. Transforms the function FCN
1091 ///*-* by dividing out the quadratic part in order to find further
1092 ///*-* minima. Calculates ycalf = (f-fmin)/(x-xmin)*v*(x-xmin)
1093 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1094 
1095 void TMinuit::mncalf(Double_t *pvec, Double_t &ycalf)
1096 {
1097  /* Local variables */
1098  Int_t ndex, i, j, m, n, nparx;
1099  Double_t denom, f;
1100 
1101  nparx = fNpar;
1102  mninex(&pvec[0]);
1103  Eval(nparx, fGin, f, fU, 4); ++fNfcn;
1104  for (i = 1; i <= fNpar; ++i) {
1105  fGrd[i-1] = 0;
1106  for (j = 1; j <= fNpar; ++j) {
1107  m = TMath::Max(i,j);
1108  n = TMath::Min(i,j);
1109  ndex = m*(m-1) / 2 + n;
1110  fGrd[i-1] += fVthmat[ndex-1]*(fXt[j-1] - pvec[j-1]);
1111  }
1112  }
1113  denom = 0;
1114  for (i = 1; i <= fNpar; ++i) {denom += fGrd[i-1]*(fXt[i-1] - pvec[i-1]); }
1115  if (denom <= 0) {
1116  fDcovar = 1;
1117  fISW[1] = 0;
1118  denom = 1;
1119  }
1120  ycalf = (f - fApsi) / denom;
1121 } /* mncalf_ */
1122 
1123 ////////////////////////////////////////////////////////////////////////////////
1124 ///*-*-*-*-*-*-*-*-*-*-*Resets the parameter list to UNDEFINED*-*-*-*-*-*-*-*
1125 ///*-* ======================================
1126 ///*-* Called from MINUIT and by option from MNEXCM
1127 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1128 
1130 {
1131  Int_t i;
1132 
1133  fNpfix = 0;
1134  fNu = 0;
1135  fNpar = 0;
1136  fNfcn = 0;
1137  fNwrmes[0] = 0;
1138  fNwrmes[1] = 0;
1139  for (i = 1; i <= fMaxext; ++i) {
1140  fU[i-1] = 0;
1141  fCpnam[i-1] = fCundef;
1142  fNvarl[i-1] = -1;
1143  fNiofex[i-1] = 0;
1144  }
1145  mnrset(1);
1146  fCfrom = "CLEAR ";
1147  fNfcnfr = fNfcn;
1148  fCstatu = "UNDEFINED ";
1149  fLnolim = kTRUE;
1150  fLphead = kTRUE;
1151 } /* mncler_ */
1152 
1153 ////////////////////////////////////////////////////////////////////////////////
1154 ///*-*-*-*-*Print function contours in two variables, on line printer*-*-*-*-*
1155 ///*-* =========================================================
1156 ///*-*
1157 ///*-* input arguments: parx, pary, devs, ngrid
1158 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1159 
1160 void TMinuit::mncntr(Int_t ike1, Int_t ike2, Int_t &ierrf)
1161 {
1162  static TString clabel = "0123456789ABCDEFGHIJ";
1163 
1164  /* Local variables */
1165  Double_t d__1, d__2;
1166  Double_t fcna[115], fcnb[115], contur[20];
1167  Double_t ylabel, fmn, fmx, xlo, ylo, xup, yup;
1168  Double_t devs, xsav, ysav, bwidx, bwidy, unext, ff, xb4;
1169  Int_t i, ngrid, ixmid, nparx, ix, nx, ny, ki1, ki2, ixzero, iy, ics;
1170  TString chmid, chln, chzero;
1171 
1172  Int_t ke1 = ike1+1;
1173  Int_t ke2 = ike2+1;
1174  if (ke1 <= 0 || ke2 <= 0) goto L1350;
1175  if (ke1 > fNu || ke2 > fNu) goto L1350;
1176  ki1 = fNiofex[ke1-1];
1177  ki2 = fNiofex[ke2-1];
1178  if (ki1 <= 0 || ki2 <= 0) goto L1350;
1179  if (ki1 == ki2) goto L1350;
1180 
1181  if (fISW[1] < 1) {
1182  mnhess();
1183  mnwerr();
1184  }
1185  nparx = fNpar;
1186  xsav = fU[ke1-1];
1187  ysav = fU[ke2-1];
1188  devs = fWord7[2];
1189  if (devs <= 0) devs = 2;
1190  xlo = fU[ke1-1] - devs*fWerr[ki1-1];
1191  xup = fU[ke1-1] + devs*fWerr[ki1-1];
1192  ylo = fU[ke2-1] - devs*fWerr[ki2-1];
1193  yup = fU[ke2-1] + devs*fWerr[ki2-1];
1194  ngrid = Int_t(fWord7[3]);
1195  if (ngrid <= 0) {
1196  ngrid = 25;
1197 //*-* Computing MIN
1198  nx = TMath::Min(fNpagwd - 15,ngrid);
1199 //*-* Computing MIN
1200  ny = TMath::Min(fNpagln - 7,ngrid);
1201  } else {
1202  nx = ngrid;
1203  ny = ngrid;
1204  }
1205  if (nx < 11) nx = 11;
1206  if (ny < 11) ny = 11;
1207  if (nx >= 115) nx = 114;
1208 
1209 //*-*- ask if parameter outside limits
1210  if (fNvarl[ke1-1] > 1) {
1211  if (xlo < fAlim[ke1-1]) xlo = fAlim[ke1-1];
1212  if (xup > fBlim[ke1-1]) xup = fBlim[ke1-1];
1213  }
1214  if (fNvarl[ke2-1] > 1) {
1215  if (ylo < fAlim[ke2-1]) ylo = fAlim[ke2-1];
1216  if (yup > fBlim[ke2-1]) yup = fBlim[ke2-1];
1217  }
1218  bwidx = (xup - xlo) / Double_t(nx);
1219  bwidy = (yup - ylo) / Double_t(ny);
1220  ixmid = Int_t(((xsav - xlo)*Double_t(nx) / (xup - xlo)) + 1);
1221  if (ixmid < 1) ixmid = 1;
1222  if (fAmin == fUndefi) mnamin();
1223 
1224  for (i = 1; i <= 20; ++i) { contur[i-1] = fAmin + fUp*(i-1)*(i-1); }
1225  contur[0] += fUp*.01;
1226 //*-*- fill FCNB to prepare first row, and find column zero/
1227  fU[ke2-1] = yup;
1228  ixzero = 0;
1229  xb4 = 1;
1230 //TH
1231  chmid.Resize(nx+1);
1232  chzero.Resize(nx+1);
1233  chln.Resize(nx+1);
1234  for (ix = 1; ix <= nx + 1; ++ix) {
1235  fU[ke1-1] = xlo + Double_t(ix-1)*bwidx;
1236  Eval(nparx, fGin, ff, fU, 4);
1237  fcnb[ix-1] = ff;
1238  if (xb4 < 0 && fU[ke1-1] > 0) ixzero = ix - 1;
1239  xb4 = fU[ke1-1];
1240  chmid[ix-1] = '*';
1241  chzero[ix-1] = '-';
1242  }
1243  Printf(" Y-AXIS: PARAMETER %3d: %s",ke2,(const char*)fCpnam[ke2-1]);
1244  if (ixzero > 0) {
1245  chzero[ixzero-1] = '+';
1246  chln = " ";
1247  Printf(" X=0");
1248  }
1249 //*-*- loop over rows
1250  for (iy = 1; iy <= ny; ++iy) {
1251  unext = fU[ke2-1] - bwidy;
1252 //*-*- prepare this line background pattern for contour
1253  chln = " ";
1254 // TH
1255  chln.Resize(nx+1);
1256  chln[ixmid-1] = '*';
1257  if (ixzero != 0) chln[ixzero-1] = ':';
1258  if (fU[ke2-1] > ysav && unext < ysav) chln = chmid;
1259  if (fU[ke2-1] > 0 && unext < 0) chln = chzero;
1260  fU[ke2-1] = unext;
1261  ylabel = fU[ke2-1] + bwidy*.5;
1262 //*-*- move FCNB to FCNA and fill FCNB with next row
1263  for (ix = 1; ix <= nx + 1; ++ix) {
1264  fcna[ix-1] = fcnb[ix-1];
1265  fU[ke1-1] = xlo + Double_t(ix-1)*bwidx;
1266  Eval(nparx, fGin, ff, fU, 4);
1267  fcnb[ix-1] = ff;
1268  }
1269 //*-*- look for contours crossing the FCNxy squares
1270  for (ix = 1; ix <= nx; ++ix) {
1271  d__1 = TMath::Max(fcna[ix-1],fcnb[ix-1]),
1272  d__2 = TMath::Max(fcna[ix],fcnb[ix]);
1273  fmx = TMath::Max(d__1,d__2);
1274  d__1 = TMath::Min(fcna[ix-1],fcnb[ix-1]),
1275  d__2 = TMath::Min(fcna[ix],fcnb[ix]);
1276  fmn = TMath::Min(d__1,d__2);
1277  for (ics = 1; ics <= 20; ++ics) {
1278  if (contur[ics-1] > fmn) goto L240;
1279  }
1280  continue;
1281 L240:
1282  if (contur[ics-1] < fmx) chln[ix-1] = clabel[ics-1];
1283  }
1284 //*-*- print a row of the contour plot
1285  Printf(" %12.4g %s",ylabel,(const char*)chln);
1286  }
1287 //*-*- contours printed, label x-axis
1288  chln = " ";
1289  chln(0,1) = 'I';
1290  chln(ixmid-1,1) = 'I';
1291  chln(nx-1,1) = 'I';
1292  Printf(" %s",(const char*)chln);
1293 
1294 //*-*- the hardest of all: print x-axis scale!
1295  chln = " ";
1296  if (nx <= 26) {
1297  Printf(" %12.4g%s%12.4g",xlo,(const char*)chln,xup);
1298  Printf(" %s%12.4g",(const char*)chln,xsav);
1299  } else {
1300  Printf(" %12.4g%s%12.4g%s%12.4g",xlo,(const char*)chln,xsav,(const char*)chln,xup);
1301  }
1302  Printf(" X-AXIS: PARAMETER %3d %s ONE COLUMN=%12.4g"
1303  ,ke1,(const char*)fCpnam[ke1-1],bwidx);
1304  Printf(" FUNCTION VALUES: F(I)=%12.4g +%12.4g *I**2",fAmin,fUp);
1305 //*-*- finished. reset input values
1306  fU[ke1-1] = xsav;
1307  fU[ke2-1] = ysav;
1308  ierrf = 0;
1309  return;
1310 L1350:
1311  Printf(" INVALID PARAMETER NUMBER(S) REQUESTED. IGNORED.");
1312  ierrf = 1;
1313 } /* mncntr_ */
1314 
1315 ////////////////////////////////////////////////////////////////////////////////
1316 ///*-*-*-*-*-*-*-*-*-*-*Reads a command string and executes*-*-*-*-*-*-*-*-*-*
1317 ///*-* ===================================
1318 ///*-* Called by user. 'Reads' a command string and executes.
1319 ///*-* Equivalent to MNEXCM except that the command is given as a
1320 ///*-* character string.
1321 ///*-*
1322 ///*-* ICONDN = 0: command executed normally
1323 ///*-* 1: command is blank, ignored
1324 ///*-* 2: command line unreadable, ignored
1325 ///*-* 3: unknown command, ignored
1326 ///*-* 4: abnormal termination (e.g., MIGRAD not converged)
1327 ///*-* 5: command is a request to read PARAMETER definitions
1328 ///*-* 6: 'SET INPUT' command
1329 ///*-* 7: 'SET TITLE' command
1330 ///*-* 8: 'SET COVAR' command
1331 ///*-* 9: reserved
1332 ///*-* 10: END command
1333 ///*-* 11: EXIT or STOP command
1334 ///*-* 12: RETURN command
1335 ///*-*
1336 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1337 
1338 void TMinuit::mncomd(const char *crdbin, Int_t &icondn)
1339 {
1340  /* Local variables */
1341  Int_t ierr, ipos, i, llist, lenbuf, lnc;
1342  Bool_t leader;
1343  TString comand, crdbuf, ctemp;
1344 
1345  crdbuf = crdbin;
1346  crdbuf.ToUpper();
1347  lenbuf = crdbuf.Length();
1348  icondn = 0;
1349 //*-*- record not case-sensitive, get upper case, strip leading blanks
1350  leader = kTRUE;
1351  ipos = 1;
1352  for (i = 1; i <= TMath::Min(20,lenbuf); ++i) {
1353  if (crdbuf[i-1] == '\'') break;
1354  if (crdbuf[i-1] == ' ') {
1355  if (leader) ++ipos;
1356  continue;
1357  }
1358  leader = kFALSE;
1359  }
1360 
1361 //*-*- blank or null command
1362  if (ipos > lenbuf) {
1363  Printf(" BLANK COMMAND IGNORED.");
1364  icondn = 1;
1365  return;
1366  }
1367 //*-*- . . preemptive commands
1368 //*-*- if command is 'PARAMETER'
1369  if (crdbuf(ipos-1,3) == "PAR") {
1370  icondn = 5;
1371  fLphead = kTRUE;
1372  return;
1373  }
1374 //*-*- if command is 'SET INPUT'
1375  if (crdbuf(ipos-1,3) == "SET INP") {
1376  icondn = 6;
1377  fLphead = kTRUE;
1378  return;
1379  }
1380 //*-*- if command is 'SET TITLE'
1381  if (crdbuf(ipos-1,7) == "SET TIT") {
1382  icondn = 7;
1383  fLphead = kTRUE;
1384  return;
1385  }
1386 //*-*- if command is 'SET COVARIANCE'
1387  if (crdbuf(ipos-1,7) == "SET COV") {
1388  icondn = 8;
1389  fLphead = kTRUE;
1390  return;
1391  }
1392 //*-*- crack the command . . . . . . . . . . . . . . . .
1393  ctemp = crdbuf(ipos-1,lenbuf-ipos+1);
1394  mncrck(ctemp, 20, comand, lnc, fMaxpar, fCOMDplist, llist, ierr, fIsyswr);
1395  if (ierr > 0) {
1396  Printf(" COMMAND CANNOT BE INTERPRETED");
1397  icondn = 2;
1398  return;
1399  }
1400 
1401  mnexcm(comand.Data(), fCOMDplist, llist, ierr);
1402  icondn = ierr;
1403 } /* mncomd_ */
1404 
1405 ////////////////////////////////////////////////////////////////////////////////
1406 ///*-*-*-*-*-*-*Find points along a contour where FCN is minimum*-*-*-*-*-*-*
1407 ///*-* ================================================
1408 ///*-* Find NPTU points along a contour where the function
1409 ///*-* FMIN (X(KE1),X(KE2)) = AMIN+UP
1410 ///*-* where FMIN is the minimum of FCN with respect to all
1411 ///*-* the other NPAR-2 variable parameters (if any).
1412 ///*-* IERRF on return will be equal to the number of points found:
1413 ///*-* NPTU if normal termination with NPTU points found
1414 ///*-* -1 if errors in the calling sequence (KE1, KE2 not variable)
1415 ///*-* 0 if less than four points can be found (using MNMNOT)
1416 ///*-* n>3 if only n points can be found (n < NPTU)
1417 ///*-*
1418 ///*-* input arguments: parx, pary, devs, ngrid
1419 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1420 
1421 void TMinuit::mncont(Int_t ike1, Int_t ike2, Int_t nptu, Double_t *xptu, Double_t *yptu, Int_t &ierrf)
1422 {
1423  /* System generated locals */
1424  Int_t i__1;
1425 
1426  /* Local variables */
1427  Double_t d__1, d__2;
1428  Double_t dist, xdir, ydir, aopt, u1min, u2min;
1429  Double_t abest, scalx, scaly;
1430  Double_t a1, a2, val2mi, val2pl, dc, sclfac, bigdis, sigsav;
1431  Int_t nall, iold, line, mpar, ierr, inew, move, next, i, j, nfcol, iercr;
1432  Int_t idist=0, npcol, kints, i2, i1, lr, nfcnco=0, ki1, ki2, ki3, ke3;
1433  Int_t nowpts, istrav, nfmxin, isw2, isw4;
1434  Bool_t ldebug;
1435 
1436  /* Function Body */
1437  Int_t ke1 = ike1+1;
1438  Int_t ke2 = ike2+1;
1439  ldebug = fIdbg[6] >= 1;
1440  if (ke1 <= 0 || ke2 <= 0) goto L1350;
1441  if (ke1 > fNu || ke2 > fNu) goto L1350;
1442  ki1 = fNiofex[ke1-1];
1443  ki2 = fNiofex[ke2-1];
1444  if (ki1 <= 0 || ki2 <= 0) goto L1350;
1445  if (ki1 == ki2) goto L1350;
1446  if (nptu < 4) goto L1400;
1447 
1448  nfcnco = fNfcn;
1449  fNfcnmx = (nptu + 5)*100*(fNpar + 1);
1450 //*-*- The minimum
1451  mncuve();
1452  u1min = fU[ke1-1];
1453  u2min = fU[ke2-1];
1454  ierrf = 0;
1455  fCfrom = "MNContour ";
1456  fNfcnfr = nfcnco;
1457  if (fISW[4] >= 0) {
1458  Printf(" START MNCONTOUR CALCULATION OF %4d POINTS ON CONTOUR.",nptu);
1459  if (fNpar > 2) {
1460  if (fNpar == 3) {
1461  ki3 = 6 - ki1 - ki2;
1462  ke3 = fNexofi[ki3-1];
1463  Printf(" EACH POINT IS A MINIMUM WITH RESPECT TO PARAMETER %3d %s",ke3,(const char*)fCpnam[ke3-1]);
1464  } else {
1465  Printf(" EACH POINT IS A MINIMUM WITH RESPECT TO THE OTHER %3d VARIABLE PARAMETERS.",fNpar - 2);
1466  }
1467  }
1468  }
1469 
1470 //*-*- Find the first four points using MNMNOT
1471 //*-*- ........................ first two points
1472  mnmnot(ke1, ke2, val2pl, val2mi);
1473  if (fErn[ki1-1] == fUndefi) {
1474  xptu[0] = fAlim[ke1-1];
1475  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1476  } else {
1477  if (fErn[ki1-1] >= 0) goto L1500;
1478  xptu[0] = u1min + fErn[ki1-1];
1479  }
1480  yptu[0] = val2mi;
1481 
1482  if (fErp[ki1-1] == fUndefi) {
1483  xptu[2] = fBlim[ke1-1];
1484  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1485  } else {
1486  if (fErp[ki1-1] <= 0) goto L1500;
1487  xptu[2] = u1min + fErp[ki1-1];
1488  }
1489  yptu[2] = val2pl;
1490  scalx = 1 / (xptu[2] - xptu[0]);
1491 //*-*- ........................... next two points
1492  mnmnot(ke2, ke1, val2pl, val2mi);
1493  if (fErn[ki2-1] == fUndefi) {
1494  yptu[1] = fAlim[ke2-1];
1495  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1496  } else {
1497  if (fErn[ki2-1] >= 0) goto L1500;
1498  yptu[1] = u2min + fErn[ki2-1];
1499  }
1500  xptu[1] = val2mi;
1501  if (fErp[ki2-1] == fUndefi) {
1502  yptu[3] = fBlim[ke2-1];
1503  mnwarn("W", "MNContour ", "Contour squeezed by parameter limits.");
1504  } else {
1505  if (fErp[ki2-1] <= 0) goto L1500;
1506  yptu[3] = u2min + fErp[ki2-1];
1507  }
1508  xptu[3] = val2pl;
1509  scaly = 1 / (yptu[3] - yptu[1]);
1510  nowpts = 4;
1511  next = 5;
1512  if (ldebug) {
1513  Printf(" Plot of four points found by MINOS");
1514  fXpt[0] = u1min;
1515  fYpt[0] = u2min;
1516  fChpt[0] = ' ';
1517 //*-* Computing MIN
1518  nall = TMath::Min(nowpts + 1,101);
1519  for (i = 2; i <= nall; ++i) {
1520  fXpt[i-1] = xptu[i-2];
1521  fYpt[i-1] = yptu[i-2];
1522  }
1523  sprintf(fChpt,"%s"," ABCD");
1524  mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1525  }
1526 
1527 //*-*- ..................... save some values before fixing
1528  isw2 = fISW[1];
1529  isw4 = fISW[3];
1530  sigsav = fEDM;
1531  istrav = fIstrat;
1532  dc = fDcovar;
1533  fApsi = fEpsi*.5;
1534  abest = fAmin;
1535  mpar = fNpar;
1536  nfmxin = fNfcnmx;
1537  for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
1538  i__1 = mpar*(mpar + 1) / 2;
1539  for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
1540  for (i = 1; i <= mpar; ++i) {
1541  fCONTgcc[i-1] = fGlobcc[i-1];
1542  fCONTw[i-1] = fWerr[i-1];
1543  }
1544 //*-*- fix the two parameters in question
1545  kints = fNiofex[ke1-1];
1546  mnfixp(kints-1, ierr);
1547  kints = fNiofex[ke2-1];
1548  mnfixp(kints-1, ierr);
1549 //*-*- ......................Fill in the rest of the points
1550  for (inew = next; inew <= nptu; ++inew) {
1551 //*-* find the two neighbouring points with largest separation
1552  bigdis = 0;
1553  for (iold = 1; iold <= inew - 1; ++iold) {
1554  i2 = iold + 1;
1555  if (i2 == inew) i2 = 1;
1556  d__1 = scalx*(xptu[iold-1] - xptu[i2-1]);
1557  d__2 = scaly*(yptu[iold-1] - yptu[i2-1]);
1558  dist = d__1*d__1 + d__2*d__2;
1559  if (dist > bigdis) {
1560  bigdis = dist;
1561  idist = iold;
1562  }
1563  }
1564  i1 = idist;
1565  i2 = i1 + 1;
1566  if (i2 == inew) i2 = 1;
1567 //*-*- next point goes between I1 and I2
1568  a1 = .5;
1569  a2 = .5;
1570 L300:
1571  fXmidcr = a1*xptu[i1-1] + a2*xptu[i2-1];
1572  fYmidcr = a1*yptu[i1-1] + a2*yptu[i2-1];
1573  xdir = yptu[i2-1] - yptu[i1-1];
1574  ydir = xptu[i1-1] - xptu[i2-1];
1575  sclfac = TMath::Max(TMath::Abs(xdir*scalx),TMath::Abs(ydir*scaly));
1576  fXdircr = xdir / sclfac;
1577  fYdircr = ydir / sclfac;
1578  fKe1cr = ke1;
1579  fKe2cr = ke2;
1580 //*-*- Find the contour crossing point along DIR
1581  fAmin = abest;
1582  mncros(aopt, iercr);
1583  if (iercr > 1) {
1584 //*-*- If cannot find mid-point, try closer to point 1
1585  if (a1 > .5) {
1586  if (fISW[4] >= 0) {
1587  Printf(" MNCONT CANNOT FIND NEXT POINT ON CONTOUR. ONLY %3d POINTS FOUND.",nowpts);
1588  }
1589  goto L950;
1590  }
1591  mnwarn("W", "MNContour ", "Cannot find midpoint, try closer.");
1592  a1 = .75;
1593  a2 = .25;
1594  goto L300;
1595  }
1596 //*-*- Contour has been located, insert new point in list
1597  for (move = nowpts; move >= i1 + 1; --move) {
1598  xptu[move] = xptu[move-1];
1599  yptu[move] = yptu[move-1];
1600  }
1601  ++nowpts;
1602  xptu[i1] = fXmidcr + fXdircr*aopt;
1603  yptu[i1] = fYmidcr + fYdircr*aopt;
1604  }
1605 L950:
1606 
1607  ierrf = nowpts;
1608  fCstatu = "SUCCESSFUL";
1609  if (nowpts < nptu) fCstatu = "INCOMPLETE";
1610 
1611 //*-*- make a lineprinter plot of the contour
1612  if (fISW[4] >= 0) {
1613  fXpt[0] = u1min;
1614  fYpt[0] = u2min;
1615  fChpt[0] = ' ';
1616  nall = TMath::Min(nowpts + 1,101);
1617  for (i = 2; i <= nall; ++i) {
1618  fXpt[i-1] = xptu[i-2];
1619  fYpt[i-1] = yptu[i-2];
1620  fChpt[i-1] = 'X';
1621  }
1622  fChpt[nall] = 0;
1623  Printf(" Y-AXIS: PARAMETER %3d %s",ke2,(const char*)fCpnam[ke2-1]);
1624 
1625  mnplot(fXpt, fYpt, fChpt, nall, fNpagwd, fNpagln);
1626 
1627  Printf(" X-AXIS: PARAMETER %3d %s",ke1,(const char*)fCpnam[ke1-1]);
1628  }
1629 //*-*- print out the coordinates around the contour
1630  if (fISW[4] >= 1) {
1631  npcol = (nowpts + 1) / 2;
1632  nfcol = nowpts / 2;
1633  Printf("%5d POINTS ON CONTOUR. FMIN=%13.5e ERRDEF=%11.3g",nowpts,abest,fUp);
1634  Printf(" %s%s%s%s",(const char*)fCpnam[ke1-1],
1635  (const char*)fCpnam[ke2-1],
1636  (const char*)fCpnam[ke1-1],
1637  (const char*)fCpnam[ke2-1]);
1638  for (line = 1; line <= nfcol; ++line) {
1639  lr = line + npcol;
1640  Printf(" %5d%13.5e%13.5e %5d%13.5e%13.5e",line,xptu[line-1],yptu[line-1],lr,xptu[lr-1],yptu[lr-1]);
1641  }
1642  if (nfcol < npcol) {
1643  Printf(" %5d%13.5e%13.5e",npcol,xptu[npcol-1],yptu[npcol-1]);
1644  }
1645  }
1646 //*-*- . . contour finished. reset v
1647  fItaur = 1;
1648  mnfree(1);
1649  mnfree(1);
1650  i__1 = mpar*(mpar + 1) / 2;
1651  for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
1652  for (i = 1; i <= mpar; ++i) {
1653  fGlobcc[i-1] = fCONTgcc[i-1];
1654  fWerr[i-1] = fCONTw[i-1];
1655  fX[i-1] = fXt[i-1];
1656  }
1657  mninex(fX);
1658  fEDM = sigsav;
1659  fAmin = abest;
1660  fISW[1] = isw2;
1661  fISW[3] = isw4;
1662  fDcovar = dc;
1663  fItaur = 0;
1664  fNfcnmx = nfmxin;
1665  fIstrat = istrav;
1666  fU[ke1-1] = u1min;
1667  fU[ke2-1] = u2min;
1668  goto L2000;
1669 //*-*- Error returns
1670 L1350:
1671  Printf(" INVALID PARAMETER NUMBERS.");
1672  goto L1450;
1673 L1400:
1674  Printf(" LESS THAN FOUR POINTS REQUESTED.");
1675 L1450:
1676  ierrf = -1;
1677  fCstatu = "USER ERROR";
1678  goto L2000;
1679 L1500:
1680  Printf(" MNCONT UNABLE TO FIND FOUR POINTS.");
1681  fU[ke1-1] = u1min;
1682  fU[ke2-1] = u2min;
1683  ierrf = 0;
1684  fCstatu = "FAILED";
1685 L2000:
1686  fCfrom = "MNContour ";
1687  fNfcnfr = nfcnco;
1688 } /* mncont_ */
1689 
1690 ////////////////////////////////////////////////////////////////////////////////
1691 ///*-*-*-*-*-*-*-*-*-*-*-*Cracks the free-format input*-*-*-*-*-*-*-*-*-*-*-*-*
1692 ///*-* ============================
1693 ///*-* Cracks the free-format input, expecting zero or more
1694 ///*-* alphanumeric fields (which it joins into COMAND(1:LNC))
1695 ///*-* followed by one or more numeric fields separated by
1696 ///*-* blanks and/or one comma. The numeric fields are put into
1697 ///*-* the LLIST (but at most MXP) elements of PLIST.
1698 ///*-* IERR = 0 if no errors,
1699 ///*-* = 1 if error(s).
1700 ///*-*
1701 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1702 
1703 void TMinuit::mncrck(TString cardbuf, Int_t maxcwd, TString &comand, Int_t &lnc,
1704  Int_t mxp, Double_t *plist, Int_t &llist, Int_t &ierr, Int_t)
1705 {
1706  /* Initialized data */
1707 
1708  char *cnull = 0;
1709  const char *cnumer = "123456789-.0+";
1710 
1711  /* Local variables */
1712  Int_t ifld, iend, lend, left, nreq, ipos, kcmnd, nextb, ic, ibegin, ltoadd;
1713  Int_t ielmnt, lelmnt[25], nelmnt;
1714  TString ctemp;
1715  char *celmnt[25];
1716  char command[25];
1717 
1718  /* Function Body */
1719  char *crdbuf = (char*)cardbuf.Data();
1720  lend = cardbuf.Length();
1721  ielmnt = 0;
1722  nextb = 1;
1723  ierr = 0;
1724 //*-*- . . . . loop over words CELMNT
1725 L10:
1726  for (ipos = nextb; ipos <= lend; ++ipos) {
1727  ibegin = ipos;
1728  if (crdbuf[ipos-1] == ' ') continue;
1729  if (crdbuf[ipos-1] == ',') goto L250;
1730  goto L150;
1731  }
1732  goto L300;
1733 L150:
1734 //*-*- found beginning of word, look for end
1735  for (ipos = ibegin + 1; ipos <= lend; ++ipos) {
1736  if (crdbuf[ipos-1] == ' ') goto L250;
1737  if (crdbuf[ipos-1] == ',') goto L250;
1738  }
1739  ipos = lend + 1;
1740 L250:
1741  iend = ipos - 1;
1742  ++ielmnt;
1743  if (iend >= ibegin) celmnt[ielmnt-1] = &crdbuf[ibegin-1];
1744  else celmnt[ielmnt-1] = cnull;
1745  lelmnt[ielmnt-1] = iend - ibegin + 1;
1746  if (lelmnt[ielmnt-1] > 19) {
1747  Printf(" MINUIT WARNING: INPUT DATA WORD TOO LONG.");
1748  ctemp = cardbuf(ibegin-1,iend-ibegin+1);
1749  Printf(" ORIGINAL:%s",ctemp.Data());
1750  Printf(" TRUNCATED TO:%s",celmnt[ielmnt-1]);
1751  lelmnt[ielmnt-1] = 19;
1752  }
1753  if (ipos >= lend) goto L300;
1754  if (ielmnt >= 25) goto L300;
1755 //*-*- look for comma or beginning of next word
1756  for (ipos = iend + 1; ipos <= lend; ++ipos) {
1757  if (crdbuf[ipos-1] == ' ') continue;
1758  nextb = ipos;
1759  if (crdbuf[ipos-1] == ',') nextb = ipos + 1;
1760  goto L10;
1761  }
1762 //*-*- All elements found, join the alphabetic ones to
1763 //*-*- form a command
1764 L300:
1765  nelmnt = ielmnt;
1766  command[0] = ' '; command[1] = 0;
1767  lnc = 1;
1768  plist[0] = 0;
1769  llist = 0;
1770  if (ielmnt == 0) goto L900;
1771  kcmnd = 0;
1772  for (ielmnt = 1; ielmnt <= nelmnt; ++ielmnt) {
1773  if ( celmnt[ielmnt-1] == cnull) goto L450;
1774  for (ic = 1; ic <= 13; ++ic) {
1775  if (*celmnt[ielmnt-1] == cnumer[ic-1]) goto L450;
1776  }
1777  if (kcmnd >= maxcwd) continue;
1778  left = maxcwd - kcmnd;
1779  ltoadd = lelmnt[ielmnt-1];
1780  if (ltoadd > left) ltoadd = left;
1781  strncpy(&command[kcmnd],celmnt[ielmnt-1],ltoadd);
1782  kcmnd += ltoadd;
1783  if (kcmnd == maxcwd) continue;
1784  command[kcmnd] = ' ';
1785  ++kcmnd;
1786  command[kcmnd] = 0;
1787  }
1788  lnc = kcmnd;
1789  goto L900;
1790 L450:
1791  lnc = kcmnd;
1792 //*-*- . . . . we have come to a numeric field
1793  llist = 0;
1794  for (ifld = ielmnt; ifld <= nelmnt; ++ifld) {
1795  ++llist;
1796  if (llist > mxp) {
1797  nreq = nelmnt - ielmnt + 1;
1798  Printf(" MINUIT WARNING IN MNCRCK: ");
1799  Printf(" COMMAND HAS INPUT %5d NUMERIC FIELDS, BUT MINUIT CAN ACCEPT ONLY%3d",nreq,mxp);
1800  goto L900;
1801  }
1802  if (celmnt[ifld-1] == cnull) plist[llist-1] = 0;
1803  else {
1804  sscanf(celmnt[ifld-1],"%lf",&plist[llist-1]);
1805  }
1806  }
1807 //*-*- end loop over numeric fields
1808 L900:
1809  if (lnc <= 0) lnc = 1;
1810  comand = command;
1811 } /* mncrck_ */
1812 
1813 ////////////////////////////////////////////////////////////////////////////////
1814 ///*-*-*-*-*-*-*-*-*-*-*Find point where MNEVAL=AMIN+UP*-*-*-*-*-*-*-*-*-*-*-*
1815 ///*-* ===============================
1816 ///*-* Find point where MNEVAL=AMIN+UP, along the line through
1817 ///*-* XMIDCR,YMIDCR with direction XDIRCR,YDIRCR, where X and Y
1818 ///*-* are parameters KE1CR and KE2CR. If KE2CR=0 (from MINOS),
1819 ///*-* only KE1CR is varied. From MNCONT, both are varied.
1820 ///*-* Crossing point is at
1821 ///*-* (U(KE1),U(KE2)) = (XMID,YMID) + AOPT*(XDIR,YDIR)
1822 ///*-*
1823 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1824 
1825 void TMinuit::mncros(Double_t &aopt, Int_t &iercr)
1826 {
1827  /* Local variables */
1828  Double_t alsb[3], flsb[3], bmin, bmax, zmid, sdev, zdir, zlim;
1829  Double_t coeff[3], aleft, aulim, fdist, adist, aminsv;
1830  Double_t anext, fnext, slope, s1, s2, x1, x2, ecarmn, ecarmx;
1831  Double_t determ, rt, smalla, aright, aim, tla, tlf, dfda,ecart;
1832  Int_t iout=0, i, ileft, ierev, maxlk, ibest, ik, it;
1833  Int_t noless, iworst=0, iright, itoohi, kex, ipt;
1834  Bool_t ldebug;
1835  const char *chsign;
1836  x2 = 0;
1837 
1838  ldebug = fIdbg[6] >= 1;
1839  aminsv = fAmin;
1840 //*-*- convergence when F is within TLF of AIM and next prediction
1841 //*-*- of AOPT is within TLA of previous value of AOPT
1842  aim = fAmin + fUp;
1843  tlf = fUp*.01;
1844  tla = .01;
1845  fXpt[0] = 0;
1846  fYpt[0] = aim;
1847  fChpt[0] = ' ';
1848  ipt = 1;
1849  if (fKe2cr == 0) {
1850  fXpt[1] = -1;
1851  fYpt[1] = fAmin;
1852  fChpt[1] = '.';
1853  ipt = 2;
1854  }
1855 //*-*- find the largest allowed A
1856  aulim = 100;
1857  for (ik = 1; ik <= 2; ++ik) {
1858  if (ik == 1) {
1859  kex = fKe1cr;
1860  zmid = fXmidcr;
1861  zdir = fXdircr;
1862  } else {
1863  if (fKe2cr == 0) continue;
1864  kex = fKe2cr;
1865  zmid = fYmidcr;
1866  zdir = fYdircr;
1867  }
1868  if (fNvarl[kex-1] <= 1) continue;
1869  if (zdir == 0) continue;
1870  zlim = fAlim[kex-1];
1871  if (zdir > 0) zlim = fBlim[kex-1];
1872  aulim = TMath::Min(aulim,(zlim - zmid) / zdir);
1873  }
1874 //*-*- LSB = Line Search Buffer
1875 //*-*- first point
1876  anext = 0;
1877  aopt = anext;
1878  fLimset = kFALSE;
1879  if (aulim < aopt + tla) fLimset = kTRUE;
1880  mneval(anext, fnext, ierev);
1881 //*-* debug printout:
1882  if (ldebug) {
1883  Printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1884  }
1885  if (ierev > 0) goto L900;
1886  if (fLimset && fnext <= aim) goto L930;
1887  ++ipt;
1888  fXpt[ipt-1] = anext;
1889  fYpt[ipt-1] = fnext;
1890  fChpt[ipt-1] = charal[ipt-1];
1891  alsb[0] = anext;
1892  flsb[0] = fnext;
1893  fnext = TMath::Max(fnext,aminsv + fUp*.1);
1894  aopt = TMath::Sqrt(fUp / (fnext - aminsv)) - 1;
1895  if (TMath::Abs(fnext - aim) < tlf) goto L800;
1896 
1897  if (aopt < -.5)aopt = -.5;
1898  if (aopt > 1) aopt = 1;
1899  fLimset = kFALSE;
1900  if (aopt > aulim) {
1901  aopt = aulim;
1902  fLimset = kTRUE;
1903  }
1904  mneval(aopt, fnext, ierev);
1905 //*-* debug printout:
1906  if (ldebug) {
1907  Printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1908  }
1909  if (ierev > 0) goto L900;
1910  if (fLimset && fnext <= aim) goto L930;
1911  alsb[1] = aopt;
1912  ++ipt;
1913  fXpt[ipt-1] = alsb[1];
1914  fYpt[ipt-1] = fnext;
1915  fChpt[ipt-1] = charal[ipt-1];
1916  flsb[1] = fnext;
1917  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1918 //*-*- DFDA must be positive on the contour
1919  if (dfda > 0) goto L460;
1920 L300:
1921  mnwarn("D", "MNCROS ", "Looking for slope of the right sign");
1922  maxlk = 15 - ipt;
1923  for (it = 1; it <= maxlk; ++it) {
1924  alsb[0] = alsb[1];
1925  flsb[0] = flsb[1];
1926  aopt = alsb[0] + Double_t(it)*.2;
1927  fLimset = kFALSE;
1928  if (aopt > aulim) {
1929  aopt = aulim;
1930  fLimset = kTRUE;
1931  }
1932  mneval(aopt, fnext, ierev);
1933 //*-* debug printout:
1934  if (ldebug) {
1935  Printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1936  }
1937  if (ierev > 0) goto L900;
1938  if (fLimset && fnext <= aim) goto L930;
1939  alsb[1] = aopt;
1940  ++ipt;
1941  fXpt[ipt-1] = alsb[1];
1942  fYpt[ipt-1] = fnext;
1943  fChpt[ipt-1] = charal[ipt-1];
1944  flsb[1] = fnext;
1945  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
1946  if (dfda > 0) goto L450;
1947  }
1948  mnwarn("W", "MNCROS ", "Cannot find slope of the right sign");
1949  goto L950;
1950 L450:
1951 //*-*- we have two points with the right slope
1952 L460:
1953  aopt = alsb[1] + (aim - flsb[1]) / dfda;
1954  fdist = TMath::Min(TMath::Abs(aim - flsb[0]),TMath::Abs(aim - flsb[1]));
1955  adist = TMath::Min(TMath::Abs(aopt - alsb[0]),TMath::Abs(aopt - alsb[1]));
1956  tla = .01;
1957  if (TMath::Abs(aopt) > 1) tla = TMath::Abs(aopt)*.01;
1958  if (adist < tla && fdist < tlf) goto L800;
1959  if (ipt >= 15) goto L950;
1960  bmin = TMath::Min(alsb[0],alsb[1]) - 1;
1961  if (aopt < bmin) aopt = bmin;
1962  bmax = TMath::Max(alsb[0],alsb[1]) + 1;
1963  if (aopt > bmax) aopt = bmax;
1964 //*-*- Try a third point
1965  fLimset = kFALSE;
1966  if (aopt > aulim) {
1967  aopt = aulim;
1968  fLimset = kTRUE;
1969  }
1970  mneval(aopt, fnext, ierev);
1971 //*-* debug printout:
1972  if (ldebug) {
1973  Printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
1974  }
1975  if (ierev > 0) goto L900;
1976  if (fLimset && fnext <= aim) goto L930;
1977  alsb[2] = aopt;
1978  ++ipt;
1979  fXpt[ipt-1] = alsb[2];
1980  fYpt[ipt-1] = fnext;
1981  fChpt[ipt-1] = charal[ipt-1];
1982  flsb[2] = fnext;
1983 //*-*- now we have three points, ask how many <AIM
1984  ecarmn = TMath::Abs(fnext-aim);
1985  ibest = 3;
1986  ecarmx = 0;
1987  noless = 0;
1988  for (i = 1; i <= 3; ++i) {
1989  ecart = TMath::Abs(flsb[i-1] - aim);
1990  if (ecart > ecarmx) { ecarmx = ecart; iworst = i; }
1991  if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
1992  if (flsb[i-1] < aim) ++noless;
1993  }
1994 //*-*- if at least one on each side of AIM, fit a parabola
1995  if (noless == 1 || noless == 2) goto L500;
1996 //*-*- if all three are above AIM, third must be closest to AIM
1997  if (noless == 0 && ibest != 3) goto L950;
1998 //*-*- if all three below, and third is not best, then slope
1999 //*-*- has again gone negative, look for positive slope.
2000  if (noless == 3 && ibest != 3) {
2001  alsb[1] = alsb[2];
2002  flsb[1] = flsb[2];
2003  goto L300;
2004  }
2005 //*-*- in other cases, new straight line thru last two points
2006  alsb[iworst-1] = alsb[2];
2007  flsb[iworst-1] = flsb[2];
2008  dfda = (flsb[1] - flsb[0]) / (alsb[1] - alsb[0]);
2009  goto L460;
2010 //*-*- parabola fit
2011 L500:
2012  mnpfit(alsb, flsb, 3, coeff, sdev);
2013  if (coeff[2] <= 0) {
2014  mnwarn("D", "MNCROS ", "Curvature is negative near contour line.");
2015  }
2016  determ = coeff[1]*coeff[1] - coeff[2]*4*(coeff[0] - aim);
2017  if (determ <= 0) {
2018  mnwarn("D", "MNCROS ", "Problem 2, impossible determinant");
2019  goto L950;
2020  }
2021 //*-*- Find which root is the right one
2022  rt = TMath::Sqrt(determ);
2023  x1 = (-coeff[1] + rt) / (coeff[2]*2);
2024  x2 = (-coeff[1] - rt) / (coeff[2]*2);
2025  s1 = coeff[1] + x1*2*coeff[2];
2026  s2 = coeff[1] + x2*2*coeff[2];
2027  if (s1*s2 > 0) {
2028  Printf(" MNCONTour problem 1");
2029  }
2030  aopt = x1;
2031  slope = s1;
2032  if (s2 > 0) {
2033  aopt = x2;
2034  slope = s2;
2035  }
2036 //*-*- ask if converged
2037  tla = .01;
2038  if (TMath::Abs(aopt) > 1) tla = TMath::Abs(aopt)*.01;
2039  if (TMath::Abs(aopt - alsb[ibest-1]) < tla && TMath::Abs(flsb[ibest-1] - aim) < tlf) {
2040  goto L800;
2041  }
2042  if (ipt >= 15) goto L950;
2043 
2044 //*-*- see if proposed point is in acceptable zone between L and R
2045 //*-*- first find ILEFT, IRIGHT, IOUT and IBEST
2046  ileft = 0;
2047  iright = 0;
2048  ibest = 1;
2049  ecarmx = 0;
2050  ecarmn = TMath::Abs(aim - flsb[0]);
2051  for (i = 1; i <= 3; ++i) {
2052  ecart = TMath::Abs(flsb[i-1] - aim);
2053  if (ecart < ecarmn) { ecarmn = ecart; ibest = i; }
2054  if (ecart > ecarmx) { ecarmx = ecart; }
2055  if (flsb[i-1] > aim) {
2056  if (iright == 0) iright = i;
2057  else if (flsb[i-1] > flsb[iright-1]) iout = i;
2058  else { iout = iright; iright = i; }
2059  }
2060  else if (ileft == 0) ileft = i;
2061  else if (flsb[i-1] < flsb[ileft-1]) iout = i;
2062  else { iout = ileft; ileft = i; }
2063  }
2064 //*-*- avoid keeping a very bad point next time around
2065  if (ecarmx > TMath::Abs(flsb[iout-1] - aim)*10) {
2066  aopt = aopt*.5 + (alsb[iright-1] + alsb[ileft-1])*.25;
2067  }
2068 //*-*- knowing ILEFT and IRIGHT, get acceptable window
2069  smalla = tla*.1;
2070  if (slope*smalla > tlf) smalla = tlf / slope;
2071  aleft = alsb[ileft-1] + smalla;
2072  aright = alsb[iright-1] - smalla;
2073 //*-*- move proposed point AOPT into window if necessary
2074  if (aopt < aleft) aopt = aleft;
2075  if (aopt > aright) aopt = aright;
2076  if (aleft > aright) aopt = (aleft + aright)*.5;
2077 
2078 //*-*- see if proposed point outside limits (should be impossible!)
2079  fLimset = kFALSE;
2080  if (aopt > aulim) {
2081  aopt = aulim;
2082  fLimset = kTRUE;
2083  }
2084 //*-*- Evaluate function at new point AOPT
2085  mneval(aopt, fnext, ierev);
2086 //*-* debug printout:
2087  if (ldebug) {
2088  Printf(" MNCROS: calls=%8d AIM=%10.5f F,A=%10.5f%10.5f",fNfcn,aim,fnext,aopt);
2089  }
2090  if (ierev > 0) goto L900;
2091  if (fLimset && fnext <= aim) goto L930;
2092  ++ipt;
2093  fXpt[ipt-1] = aopt;
2094  fYpt[ipt-1] = fnext;
2095  fChpt[ipt-1] = charal[ipt-1];
2096 //*-*- Replace odd point by new one
2097  alsb[iout-1] = aopt;
2098  flsb[iout-1] = fnext;
2099 //*-*- the new point may not be the best, but it is the only one
2100 //*-*- which could be good enough to pass convergence criteria
2101  ibest = iout;
2102  goto L500;
2103 
2104 //*-*- Contour has been located, return point to MNCONT OR MINOS
2105 L800:
2106  iercr = 0;
2107  goto L1000;
2108 //*-*- error in the minimization
2109 L900:
2110  if (ierev == 1) goto L940;
2111  goto L950;
2112 //*-*- parameter up against limit
2113 L930:
2114  iercr = 1;
2115  goto L1000;
2116 //*-*- too many calls to FCN
2117 L940:
2118  iercr = 2;
2119  goto L1000;
2120 //*-*- cannot find next point
2121 L950:
2122  iercr = 3;
2123 //*-*- in any case
2124 L1000:
2125  if (ldebug) {
2126  itoohi = 0;
2127  for (i = 1; i <= ipt; ++i) {
2128  if (fYpt[i-1] > aim + fUp) {
2129  fYpt[i-1] = aim + fUp;
2130  fChpt[i-1] = '+';
2131  itoohi = 1;
2132  }
2133  }
2134  fChpt[ipt] = 0;
2135  chsign = "POSI";
2136  if (fXdircr < 0) chsign = "NEGA";
2137  if (fKe2cr == 0) {
2138  Printf(" %sTIVE MINOS ERROR, PARAMETER %3d",chsign,fKe1cr);
2139  }
2140  if (itoohi == 1) {
2141  Printf("POINTS LABELLED '+' WERE TOO HIGH TO PLOT.");
2142  }
2143  if (iercr == 1) {
2144  Printf("RIGHTMOST POINT IS UP AGAINST LIMIT.");
2145  }
2146  mnplot(fXpt, fYpt, fChpt, ipt, fNpagwd, fNpagln);
2147  }
2148 } /* mncros_ */
2149 
2150 ////////////////////////////////////////////////////////////////////////////////
2151 ///*-*-*-*-*-*-*-*Makes sure that the current point is a local minimum*-*-*-*-*
2152 ///*-* ====================================================
2153 ///*-* Makes sure that the current point is a local
2154 ///*-* minimum and that the error matrix exists,
2155 ///*-* or at least something good enough for MINOS and MNCONT
2156 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2157 
2159 {
2160  /* Local variables */
2161  Double_t dxdi, wint;
2162  Int_t ndex, iext, i, j;
2163 
2164  if (fISW[3] < 1) {
2165  Printf(" FUNCTION MUST BE MINIMIZED BEFORE CALLING %s",(const char*)fCfrom);
2166  fApsi = fEpsi;
2167  mnmigr();
2168  }
2169  if (fISW[1] < 3) {
2170  mnhess();
2171  if (fISW[1] < 1) {
2172  mnwarn("W", fCfrom, "NO ERROR MATRIX. WILL IMPROVISE.");
2173  for (i = 1; i <= fNpar; ++i) {
2174  ndex = i*(i-1) / 2;
2175  for (j = 1; j <= i-1; ++j) {
2176  ++ndex;
2177  fVhmat[ndex-1] = 0;
2178  }
2179  ++ndex;
2180  if (fG2[i-1] <= 0) {
2181  wint = fWerr[i-1];
2182  iext = fNexofi[i-1];
2183  if (fNvarl[iext-1] > 1) {
2184  mndxdi(fX[i-1], i-1, dxdi);
2185  if (TMath::Abs(dxdi) < .001) wint = .01;
2186  else wint /= TMath::Abs(dxdi);
2187  }
2188  fG2[i-1] = fUp / (wint*wint);
2189  }
2190  fVhmat[ndex-1] = 2 / fG2[i-1];
2191  }
2192  fISW[1] = 1;
2193  fDcovar = 1;
2194  } else mnwerr();
2195  }
2196 } /* mncuve_ */
2197 
2198 ////////////////////////////////////////////////////////////////////////////////
2199 ///*-*-*-*-*-*-*-*Calculates the first derivatives of FCN (GRD)*-*-*-*-*-*-*-*
2200 ///*-* =============================================
2201 ///*-* Calculates the first derivatives of FCN (GRD),
2202 ///*-* either by finite differences or by transforming the user-
2203 ///*-* supplied derivatives to internal coordinates,
2204 ///*-* according to whether fISW[2] is zero or one.
2205 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2206 
2208 {
2209  /* Local variables */
2210  Double_t step, dfmin, stepb4, dd, df, fs1;
2211  Double_t tlrstp, tlrgrd, epspri, optstp, stpmax, stpmin, fs2, grbfor=0, d1d2, xtf;
2212  Int_t icyc, ncyc, iint, iext, i, nparx;
2213  Bool_t ldebug;
2214 
2215  nparx = fNpar;
2216  ldebug = fIdbg[2] >= 1;
2217  if (fAmin == fUndefi) mnamin();
2218  if (fISW[2] == 1) goto L100;
2219 
2220  if (ldebug) {
2221 //*-*- make sure starting at the right place
2222  mninex(fX);
2223  nparx = fNpar;
2224  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
2225  if (fs1 != fAmin) {
2226  df = fAmin - fs1;
2227  mnwarn("D", "MNDERI", TString::Format("function value differs from AMIN by %12.3g",df));
2228  fAmin = fs1;
2229  }
2230  Printf(" FIRST DERIVATIVE DEBUG PRINTOUT. MNDERI");
2231  Printf(" PAR DERIV STEP MINSTEP OPTSTEP D1-D2 2ND DRV");
2232  }
2233  dfmin = fEpsma2*8*(TMath::Abs(fAmin) + fUp);
2234  if (fIstrat <= 0) {
2235  ncyc = 2;
2236  tlrstp = .5;
2237  tlrgrd = .1;
2238  } else if (fIstrat == 1) {
2239  ncyc = 3;
2240  tlrstp = .3;
2241  tlrgrd = .05;
2242  } else {
2243  ncyc = 5;
2244  tlrstp = .1;
2245  tlrgrd = .02;
2246  }
2247 //*-*- loop over variable parameters
2248  for (i = 1; i <= fNpar; ++i) {
2249  epspri = fEpsma2 + TMath::Abs(fGrd[i-1]*fEpsma2);
2250 //*-*- two-point derivatives always assumed necessary
2251 //*-*- maximum number of cycles over step size depends on strategy
2252  xtf = fX[i-1];
2253  stepb4 = 0;
2254 //*-*- loop as little as possible here!/
2255  for (icyc = 1; icyc <= ncyc; ++icyc) {
2256 //*-*- ........ theoretically best step
2257  optstp = TMath::Sqrt(dfmin / (TMath::Abs(fG2[i-1]) + epspri));
2258 //*-*- step cannot decrease by more than a factor of ten
2259  step = TMath::Max(optstp,TMath::Abs(fGstep[i-1]*.1));
2260 //*-*- but if parameter has limits, max step size = 0.5
2261  if (fGstep[i-1] < 0 && step > .5) step = .5;
2262 //*-*- and not more than ten times the previous step
2263  stpmax = TMath::Abs(fGstep[i-1])*10;
2264  if (step > stpmax) step = stpmax;
2265 //*-*- minimum step size allowed by machine precision
2266  stpmin = TMath::Abs(fEpsma2*fX[i-1])*8;
2267  if (step < stpmin) step = stpmin;
2268 //*-*- end of iterations if step change less than factor 2
2269  if (TMath::Abs((step - stepb4) / step) < tlrstp) goto L50;
2270 //*-*- take step positive
2271  stepb4 = step;
2272  if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(step);
2273  else fGstep[i-1] = -TMath::Abs(step);
2274  stepb4 = step;
2275  fX[i-1] = xtf + step;
2276  mninex(fX);
2277  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
2278 //*-*- take step negative
2279  fX[i-1] = xtf - step;
2280  mninex(fX);
2281  Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
2282  grbfor = fGrd[i-1];
2283  fGrd[i-1] = (fs1 - fs2) / (step*2);
2284  fG2[i-1] = (fs1 + fs2 - fAmin*2) / (step*step);
2285  fX[i-1] = xtf;
2286  if (ldebug) {
2287  d1d2 = (fs1 + fs2 - fAmin*2) / step;
2288  Printf("%4d%11.3g%11.3g%10.2g%10.2g%10.2g%10.2g",i,fGrd[i-1],step,stpmin,optstp,d1d2,fG2[i-1]);
2289  }
2290 //*-*- see if another iteration is necessary
2291  if (TMath::Abs(grbfor - fGrd[i-1]) / (TMath::Abs(fGrd[i-1]) + dfmin/step) < tlrgrd)
2292  goto L50;
2293  }
2294 //*-*- end of ICYC loop. too many iterations
2295  if (ncyc == 1) goto L50;
2296  mnwarn("D", "MNDERI", TString::Format("First derivative not converged. %g%g",fGrd[i-1],grbfor));
2297 L50:
2298  ;
2299  }
2300  mninex(fX);
2301  return;
2302 //*-*- . derivatives calc by fcn
2303 L100:
2304  for (iint = 1; iint <= fNpar; ++iint) {
2305  iext = fNexofi[iint-1];
2306  if (fNvarl[iext-1] <= 1) {
2307  fGrd[iint-1] = fGin[iext-1];
2308  } else {
2309  dd = (fBlim[iext-1] - fAlim[iext-1])*.5*TMath::Cos(fX[iint-1]);
2310  fGrd[iint-1] = fGin[iext-1]*dd;
2311  }
2312  }
2313 } /* mnderi_ */
2314 
2315 ////////////////////////////////////////////////////////////////////////////////
2316 ///*-*-*-*Calculates the transformation factor between ext/internal values*-*
2317 ///*-* =====================================================================
2318 ///*-* calculates the transformation factor between external and
2319 ///*-* internal parameter values. this factor is one for
2320 ///*-* parameters which are not limited. called from MNEMAT.
2321 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2322 
2323 void TMinuit::mndxdi(Double_t pint, Int_t ipar, Double_t &dxdi)
2324 {
2325  Int_t i = fNexofi[ipar];
2326  dxdi = 1;
2327  if (fNvarl[i-1] > 1) {
2328  dxdi = TMath::Abs((fBlim[i-1] - fAlim[i-1])*TMath::Cos(pint))*.5;
2329  }
2330 } /* mndxdi_ */
2331 
2332 ////////////////////////////////////////////////////////////////////////////////
2333 ///*-*-*-*-*-*-*-*-*-*-*-*Compute matrix eigen values*-*-*-*-*-*-*-*-*-*-*-*-*
2334 ///*-* ===========================
2335 
2336 void TMinuit::mneig(Double_t *a, Int_t ndima, Int_t n, Int_t mits, Double_t *work, Double_t precis, Int_t &ifault)
2337 {
2338  /* System generated locals */
2339  Int_t a_offset;
2340  Double_t d__1;
2341 
2342  /* Local variables */
2343  Double_t b, c, f, h, r, s, hh, gl, pr, pt;
2344  Int_t i, j, k, l, m=0, i0, i1, j1, m1, n1;
2345 
2346 //*-*- PRECIS is the machine precision EPSMAC
2347  /* Parameter adjustments */
2348  a_offset = ndima + 1;
2349  a -= a_offset;
2350  --work;
2351 
2352  /* Function Body */
2353  ifault = 1;
2354 
2355  i = n;
2356  for (i1 = 2; i1 <= n; ++i1) {
2357  l = i-2;
2358  f = a[i + (i-1)*ndima];
2359  gl = 0;
2360 
2361  if (l < 1) goto L25;
2362 
2363  for (k = 1; k <= l; ++k) {
2364  d__1 = a[i + k*ndima];
2365  gl += d__1*d__1;
2366  }
2367 L25:
2368  h = gl + f*f;
2369 
2370  if (gl > 1e-35) goto L30;
2371 
2372  work[i] = 0;
2373  work[n + i] = f;
2374  goto L65;
2375 L30:
2376  ++l;
2377  gl = TMath::Sqrt(h);
2378  if (f >= 0) gl = -gl;
2379  work[n + i] = gl;
2380  h -= f*gl;
2381  a[i + (i-1)*ndima] = f - gl;
2382  f = 0;
2383  for (j = 1; j <= l; ++j) {
2384  a[j + i*ndima] = a[i + j*ndima] / h;
2385  gl = 0;
2386  for (k = 1; k <= j; ++k) { gl += a[j + k*ndima]*a[i + k*ndima]; }
2387  if (j >= l) goto L47;
2388  j1 = j + 1;
2389  for (k = j1; k <= l; ++k) { gl += a[k + j*ndima]*a[i + k*ndima]; }
2390 L47:
2391  work[n + j] = gl / h;
2392  f += gl*a[j + i*ndima];
2393  }
2394  hh = f / (h + h);
2395  for (j = 1; j <= l; ++j) {
2396  f = a[i + j*ndima];
2397  gl = work[n + j] - hh*f;
2398  work[n + j] = gl;
2399  for (k = 1; k <= j; ++k) {
2400  a[j + k*ndima] = a[j + k*ndima] - f*work[n + k] - gl*a[i + k*ndima];
2401  }
2402  }
2403  work[i] = h;
2404 L65:
2405  --i;
2406  }
2407  work[1] = 0;
2408  work[n + 1] = 0;
2409  for (i = 1; i <= n; ++i) {
2410  l = i-1;
2411  if (work[i] == 0 || l == 0) goto L100;
2412 
2413  for (j = 1; j <= l; ++j) {
2414  gl = 0;
2415  for (k = 1; k <= l; ++k) { gl += a[i + k*ndima]*a[k + j*ndima]; }
2416  for (k = 1; k <= l; ++k) { a[k + j*ndima] -= gl*a[k + i*ndima]; }
2417  }
2418 L100:
2419  work[i] = a[i + i*ndima];
2420  a[i + i*ndima] = 1;
2421  if (l == 0) continue;
2422 
2423  for (j = 1; j <= l; ++j) {
2424  a[i + j*ndima] = 0;
2425  a[j + i*ndima] = 0;
2426  }
2427  }
2428 
2429  n1 = n - 1;
2430  for (i = 2; i <= n; ++i) {
2431  i0 = n + i-1;
2432  work[i0] = work[i0 + 1];
2433  }
2434  work[n + n] = 0;
2435  b = 0;
2436  f = 0;
2437  for (l = 1; l <= n; ++l) {
2438  j = 0;
2439  h = precis*(TMath::Abs(work[l]) + TMath::Abs(work[n + l]));
2440  if (b < h) b = h;
2441  for (m1 = l; m1 <= n; ++m1) {
2442  m = m1;
2443  if (TMath::Abs(work[n + m]) <= b) goto L150;
2444  }
2445 
2446 L150:
2447  if (m == l) goto L205;
2448 
2449 L160:
2450  if (j == mits) return;
2451  ++j;
2452  pt = (work[l + 1] - work[l]) / (work[n + l]*2);
2453  r = TMath::Sqrt(pt*pt + 1);
2454  pr = pt + r;
2455  if (pt < 0) pr = pt - r;
2456 
2457  h = work[l] - work[n + l] / pr;
2458  for (i = l; i <= n; ++i) { work[i] -= h; }
2459  f += h;
2460  pt = work[m];
2461  c = 1;
2462  s = 0;
2463  m1 = m - 1;
2464  i = m;
2465  for (i1 = l; i1 <= m1; ++i1) {
2466  j = i;
2467  --i;
2468  gl = c*work[n + i];
2469  h = c*pt;
2470  if (TMath::Abs(pt) >= TMath::Abs(work[n + i])) goto L180;
2471 
2472  c = pt / work[n + i];
2473  r = TMath::Sqrt(c*c + 1);
2474  work[n + j] = s*work[n + i]*r;
2475  s = 1 / r;
2476  c /= r;
2477  goto L190;
2478 L180:
2479  c = work[n + i] / pt;
2480  r = TMath::Sqrt(c*c + 1);
2481  work[n + j] = s*pt*r;
2482  s = c / r;
2483  c = 1 / r;
2484 L190:
2485  pt = c*work[i] - s*gl;
2486  work[j] = h + s*(c*gl + s*work[i]);
2487  for (k = 1; k <= n; ++k) {
2488  h = a[k + j*ndima];
2489  a[k + j*ndima] = s*a[k + i*ndima] + c*h;
2490  a[k + i*ndima] = c*a[k + i*ndima] - s*h;
2491  }
2492  }
2493  work[n + l] = s*pt;
2494  work[l] = c*pt;
2495 
2496  if (TMath::Abs(work[n + l]) > b) goto L160;
2497 
2498 L205:
2499  work[l] += f;
2500  }
2501  for (i = 1; i <= n1; ++i) {
2502  k = i;
2503  pt = work[i];
2504  i1 = i + 1;
2505  for (j = i1; j <= n; ++j) {
2506  if (work[j] >= pt) continue;
2507  k = j;
2508  pt = work[j];
2509  }
2510 
2511  if (k == i) continue;
2512 
2513  work[k] = work[i];
2514  work[i] = pt;
2515  for (j = 1; j <= n; ++j) {
2516  pt = a[j + i*ndima];
2517  a[j + i*ndima] = a[j + k*ndima];
2518  a[j + k*ndima] = pt;
2519  }
2520  }
2521  ifault = 0;
2522 } /* mneig_ */
2523 
2524 ////////////////////////////////////////////////////////////////////////////////
2525 /// Calculates the external error matrix from the internal matrix
2526 ///
2527 /// Note that if the matrix is declared like Double_t matrix[5][5]
2528 /// in the calling program, one has to call mnemat with, eg
2529 /// gMinuit->mnemat(&matrix[0][0],5);
2530 
2531 void TMinuit::mnemat(Double_t *emat, Int_t ndim)
2532 {
2533  /* System generated locals */
2534  Int_t emat_dim1, emat_offset;
2535 
2536  /* Local variables */
2537  Double_t dxdi, dxdj;
2538  Int_t i, j, k, npard, k2, kk, iz, nperln, kga, kgb;
2539  TString ctemp;
2540 
2541  /* Parameter adjustments */
2542  emat_dim1 = ndim;
2543  emat_offset = emat_dim1 + 1;
2544  emat -= emat_offset;
2545 
2546  /* Function Body */
2547  if (fISW[1] < 1) return;
2548  if (fISW[4] >= 2) {
2549  Printf(" EXTERNAL ERROR MATRIX. NDIM=%4d NPAR=%3d ERR DEF=%g",ndim,fNpar,fUp);
2550  }
2551 //*-*- size of matrix to be printed
2552  npard = fNpar;
2553  if (ndim < fNpar) {
2554  npard = ndim;
2555  if (fISW[4] >= 0) {
2556  Printf(" USER-DIMENSIONED ARRAY EMAT NOT BIG ENOUGH. REDUCED MATRIX CALCULATED.");
2557  }
2558  }
2559 //*-*- NPERLN is the number of elements that fit on one line
2560 
2561  nperln = (fNpagwd - 5) / 10;
2562  nperln = TMath::Min(nperln,13);
2563  if (fISW[4] >= 1 && npard > nperln) {
2564  Printf(" ELEMENTS ABOVE DIAGONAL ARE NOT PRINTED.");
2565  }
2566 //*-*- I counts the rows of the matrix
2567  for (i = 1; i <= npard; ++i) {
2568  mndxdi(fX[i-1], i-1, dxdi);
2569  kga = i*(i-1) / 2;
2570  for (j = 1; j <= i; ++j) {
2571  mndxdi(fX[j-1], j-1, dxdj);
2572  kgb = kga + j;
2573  emat[i + j*emat_dim1] = dxdi*fVhmat[kgb-1]*dxdj*fUp;
2574  emat[j + i*emat_dim1] = emat[i + j*emat_dim1];
2575  }
2576  }
2577 //*-*- IZ is number of columns to be printed in row I
2578  if (fISW[4] >= 2) {
2579  for (i = 1; i <= npard; ++i) {
2580  iz = npard;
2581  if (npard >= nperln) iz = i;
2582  ctemp = " ";
2583  for (k = 1; nperln < 0 ? k >= iz : k <= iz; k += nperln) {
2584  k2 = k + nperln - 1;
2585  if (k2 > iz) k2 = iz;
2586  for (kk = k; kk <= k2; ++kk) {
2587  ctemp += TString::Format("%10.3e ",emat[i + kk*emat_dim1]);
2588  }
2589  Printf("%s",(const char*)ctemp);
2590  }
2591  }
2592  }
2593 } /* mnemat_ */
2594 
2595 ////////////////////////////////////////////////////////////////////////////////
2596 ///*-*-*-*-*-*-*-*-*-*Utility routine to get MINOS errors*-*-*-*-*-*-*-*-*-*-*
2597 ///*-* ===================================
2598 ///*-* Called by user.
2599 ///*-* NUMBER is the parameter number
2600 ///*-* values returned by MNERRS:
2601 ///*-* EPLUS, EMINUS are MINOS errors of parameter NUMBER,
2602 ///*-* EPARAB is 'parabolic' error (from error matrix).
2603 ///*-* (Errors not calculated are set = 0)
2604 ///*-* GCC is global correlation coefficient from error matrix
2605 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2606 
2607 void TMinuit::mnerrs(Int_t number, Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &gcc)
2608 {
2609  Double_t dxdi;
2610  Int_t ndiag, iin, iex;
2611 
2612  iex = number+1;
2613 
2614  if (iex > fNu || iex <= 0) goto L900;
2615  iin = fNiofex[iex-1];
2616  if (iin <= 0) goto L900;
2617 
2618 //*-*- IEX is external number, IIN is internal number
2619  eplus = fErp[iin-1];
2620  if (eplus == fUndefi) eplus = 0;
2621  eminus = fErn[iin-1];
2622  if (eminus == fUndefi) eminus = 0;
2623  mndxdi(fX[iin-1], iin-1, dxdi);
2624  ndiag = iin*(iin + 1) / 2;
2625  eparab = TMath::Abs(dxdi*TMath::Sqrt(TMath::Abs(fUp*fVhmat[ndiag- 1])));
2626 //*-*- global correlation coefficient
2627  gcc = 0;
2628  if (fISW[1] < 2) return;
2629  gcc = fGlobcc[iin-1];
2630  return;
2631 //*-*- ERROR. parameter number not valid
2632 L900:
2633  eplus = 0;
2634  eminus = 0;
2635  eparab = 0;
2636  gcc = 0;
2637 } /* mnerrs_ */
2638 
2639 ////////////////////////////////////////////////////////////////////////////////
2640 ///*-*-*-*-*-*-*Evaluates the function being analyzed by MNCROS*-*-*-*-*-*-*-*
2641 ///*-* ===============================================
2642 ///*-* Evaluates the function being analyzed by MNCROS, which is
2643 ///*-* generally the minimum of FCN with respect to all remaining
2644 ///*-* variable parameters. The class data members contains the
2645 ///*-* data necessary to know the values of U(KE1CR) and U(KE2CR)
2646 ///*-* to be used, namely U(KE1CR) = XMIDCR + ANEXT*XDIRCR
2647 ///*-* and (if KE2CR .NE. 0) U(KE2CR) = YMIDCR + ANEXT*YDIRCR
2648 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2649 
2650 void TMinuit::mneval(Double_t anext, Double_t &fnext, Int_t &ierev)
2651 {
2652  Int_t nparx;
2653 
2654  fU[fKe1cr-1] = fXmidcr + anext*fXdircr;
2655  if (fKe2cr != 0) fU[fKe2cr-1] = fYmidcr + anext*fYdircr;
2656  mninex(fX);
2657  nparx = fNpar;
2658  Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
2659  ierev = 0;
2660  if (fNpar > 0) {
2661  fItaur = 1;
2662  fAmin = fnext;
2663  fISW[0] = 0;
2664  mnmigr();
2665  fItaur = 0;
2666  fnext = fAmin;
2667  if (fISW[0] >= 1) ierev = 1;
2668  if (fISW[3] < 1) ierev = 2;
2669  }
2670 } /* mneval_ */
2671 
2672 ////////////////////////////////////////////////////////////////////////////////
2673 ///*-*-*-*-*-*Interprets a command and takes appropriate action*-*-*-*-*-*-*-*
2674 ///*-* =================================================
2675 ///*-* either directly by skipping to the corresponding code in
2676 ///*-* MNEXCM, or by setting up a call to a function
2677 ///*-*
2678 ///*-* recognized MINUIT commands:
2679 ///*-* obsolete commands:
2680 ///*-* IERFLG is now (94.5) defined the same as ICONDN in MNCOMD
2681 ///*-* = 0: command executed normally
2682 ///*-* 1: command is blank, ignored
2683 ///*-* 2: command line unreadable, ignored
2684 ///*-* 3: unknown command, ignored
2685 ///*-* 4: abnormal termination (e.g., MIGRAD not converged)
2686 ///*-* 9: reserved
2687 ///*-* 10: END command
2688 ///*-* 11: EXIT or STOP command
2689 ///*-* 12: RETURN command
2690 ///*-*
2691 ///*-* see also http://wwwasdoc.web.cern.ch/wwwasdoc/minuit/node18.html for the possible list
2692 ///*-* of all Minuit commands
2693 ///*-*
2694 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2695 
2696 void TMinuit::mnexcm(const char *command, Double_t *plist, Int_t llist, Int_t &ierflg)
2697 {
2698  /* Initialized data */
2699 
2700  TString comand = command;
2701  static const char *cname[40] = {
2702  "MINImize ",
2703  "SEEk ",
2704  "SIMplex ",
2705  "MIGrad ",
2706  "MINOs ",
2707  "SET xxx ",
2708  "SHOw xxx ",
2709  "TOP of pag",
2710  "FIX ",
2711  "REStore ",
2712  "RELease ",
2713  "SCAn ",
2714  "CONtour ",
2715  "HESse ",
2716  "SAVe ",
2717  "IMProve ",
2718  "CALl fcn ",
2719  "STAndard ",
2720  "END ",
2721  "EXIt ",
2722  "RETurn ",
2723  "CLEar ",
2724  "HELP ",
2725  "MNContour ",
2726  "STOp ",
2727  "JUMp ",
2728  " ",
2729  " ",
2730  " ",
2731  " ",
2732  " ",
2733  " ",
2734  " ",
2735  "COVARIANCE",
2736  "PRINTOUT ",
2737  "GRADIENT ",
2738  "MATOUT ",
2739  "ERROR DEF ",
2740  "LIMITS ",
2741  "PUNCH "};
2742 
2743  Int_t nntot = 40;
2744 
2745  /* Local variables */
2746  Double_t step, xptu[101], yptu[101], f, rno;
2747  Int_t icol, kcol, ierr, iint, iext, lnow, nptu, i, iflag, ierrf;
2748  Int_t ilist, nparx, izero, nf, lk, it, iw, inonde, nsuper;
2749  Int_t it2, ke1, ke2, nowprt, kll, krl;
2750  TString chwhy, c26, cvblnk, cneway, comd;
2751  TString ctemp;
2752  Bool_t lfreed, ltofix, lfixed;
2753 
2754 //*-* alphabetical order of command names!
2755 
2756  /* Function Body */
2757 
2758  lk = comand.Length();
2759  if (lk > 20) lk = 20;
2760  fCword = comand;
2761  fCword.ToUpper();
2762 //*-*- Copy the first MAXP arguments into WORD7, making
2763 //*-*- sure that WORD7(1)=0 if LLIST=0
2764  for (iw = 1; iw <= fMaxpar; ++iw) {
2765  fWord7[iw-1] = 0;
2766  if (iw <= llist) fWord7[iw-1] = plist[iw-1];
2767  }
2768  ++fIcomnd;
2769  fNfcnlc = fNfcn;
2770  if (fCword(0,7) != "SET PRI" || fWord7[0] >= 0) {
2771  if (fISW[4] >= 0) {
2772  lnow = llist;
2773  if (lnow > 4) lnow = 4;
2774  Printf(" **********");
2775  ctemp.Form(" **%5d **%s",fIcomnd,(const char*)fCword);
2776  for (i = 1; i <= lnow; ++i) {
2777  ctemp += TString::Format("%12.4g",plist[i-1]);
2778  }
2779  Printf("%s",(const char*)ctemp);
2780  inonde = 0;
2781  if (llist > lnow) {
2782  kll = llist;
2783  if (llist > fMaxpar) {
2784  inonde = 1;
2785  kll = fMaxpar;
2786  }
2787  Printf(" ***********");
2788  for (i = lnow + 1; i <= kll; ++i) {
2789  Printf("%12.4g",plist[i-1]);
2790  }
2791  }
2792  Printf(" **********");
2793  if (inonde > 0) {
2794  Printf(" ERROR: ABOVE CALL TO MNEXCM TRIED TO PASS MORE THAN %d PARAMETERS.", fMaxpar);
2795  }
2796  }
2797  }
2798  fNfcnmx = Int_t(fWord7[0]);
2799  if (fNfcnmx <= 0) {
2800  fNfcnmx = fNpar*100 + 200 + fNpar*fNpar*5;
2801  }
2802  fEpsi = fWord7[1];
2803  if (fEpsi <= 0) {
2804  fEpsi = fUp*.1;
2805  }
2806  fLnewmn = kFALSE;
2807  fLphead = kTRUE;
2808  fISW[0] = 0;
2809  ierflg = 0;
2810 //*-*- look for command in list CNAME . . . . . . . . . .
2811  ctemp = fCword(0,3);
2812  for (i = 1; i <= nntot; ++i) {
2813  if (strncmp(ctemp.Data(),cname[i-1],3) == 0) goto L90;
2814  }
2815  Printf("UNKNOWN COMMAND IGNORED:%s", comand.Data());
2816  ierflg = 3;
2817  return;
2818 //*-*- normal case: recognized MINUIT command . . . . . . .
2819 L90:
2820  if (fCword(0,4) == "MINO") i = 5;
2821  if (i != 6 && i != 7 && i != 8 && i != 23) {
2822  fCfrom = cname[i-1];
2823  fNfcnfr = fNfcn;
2824  }
2825 //*-*- 1 2 3 4 5 6 7 8 9 10
2826  switch (i) {
2827  case 1: goto L400;
2828  case 2: goto L200;
2829  case 3: goto L300;
2830  case 4: goto L400;
2831  case 5: goto L500;
2832  case 6: goto L700;
2833  case 7: goto L700;
2834  case 8: goto L800;
2835  case 9: goto L900;
2836  case 10: goto L1000;
2837  case 11: goto L1100;
2838  case 12: goto L1200;
2839  case 13: goto L1300;
2840  case 14: goto L1400;
2841  case 15: goto L1500;
2842  case 16: goto L1600;
2843  case 17: goto L1700;
2844  case 18: goto L1800;
2845  case 19: goto L1900;
2846  case 20: goto L1900;
2847  case 21: goto L1900;
2848  case 22: goto L2200;
2849  case 23: goto L2300;
2850  case 24: goto L2400;
2851  case 25: goto L1900;
2852  case 26: goto L2600;
2853  case 27: goto L3300;
2854  case 28: goto L3300;
2855  case 29: goto L3300;
2856  case 30: goto L3300;
2857  case 31: goto L3300;
2858  case 32: goto L3300;
2859  case 33: goto L3300;
2860  case 34: goto L3400;
2861  case 35: goto L3500;
2862  case 36: goto L3600;
2863  case 37: goto L3700;
2864  case 38: goto L3800;
2865  case 39: goto L3900;
2866  case 40: goto L4000;
2867  }
2868 //*-*- . . . . . . . . . . seek
2869 L200:
2870  mnseek();
2871  return;
2872 //*-*- . . . . . . . . . . simplex
2873 L300:
2874  mnsimp();
2875  if (fISW[3] < 1) ierflg = 4;
2876  return;
2877 //*-*- . . . . . . migrad, minimize
2878 L400:
2879  nf = fNfcn;
2880  fApsi = fEpsi;
2881  mnmigr();
2882  mnwerr();
2883  if (fISW[3] >= 1) return;
2884  ierflg = 4;
2885  if (fISW[0] == 1) return;
2886  if (fCword(0,3) == "MIG") return;
2887 
2888  fNfcnmx = fNfcnmx + nf - fNfcn;
2889  nf = fNfcn;
2890  mnsimp();
2891  if (fISW[0] == 1) return;
2892  fNfcnmx = fNfcnmx + nf - fNfcn;
2893  mnmigr();
2894  if (fISW[3] >= 1) ierflg = 0;
2895  mnwerr();
2896  return;
2897 //*-*- . . . . . . . . . . minos
2898 L500:
2899  nsuper = fNfcn + ((fNpar + 1) << 1)*fNfcnmx;
2900 //*-*- possible loop over new minima
2901  fEpsi = fUp*.1;
2902 L510:
2903  fCfrom = cname[i-1]; // ensure that mncuve complains about MINOS not MIGRAD
2904  mncuve();
2905  mnmnos();
2906  if (! fLnewmn) return;
2907  mnrset(0);
2908  mnmigr();
2909  mnwerr();
2910  if (fNfcn < nsuper) goto L510;
2911  Printf(" TOO MANY FUNCTION CALLS. MINOS GIVES UP");
2912  ierflg = 4;
2913  return;
2914 //*-*- . . . . . . . . . .set, show
2915 L700:
2916  mnset();
2917  return;
2918 //*-*- . . . . . . . . . . top of page
2919 
2920 L800:
2921  Printf("1");
2922  return;
2923 //*-*- . . . . . . . . . . fix
2924 L900:
2925  ltofix = kTRUE;
2926 //*-*- . . (also release) ....
2927 L901:
2928  lfreed = kFALSE;
2929  lfixed = kFALSE;
2930  if (llist == 0) {
2931  Printf("%s: NO PARAMETERS REQUESTED ",(const char*)fCword);
2932  return;
2933  }
2934  for (ilist = 1; ilist <= llist; ++ilist) {
2935  iext = Int_t(plist[ilist-1]);
2936  chwhy = " IS UNDEFINED.";
2937  if (iext <= 0) goto L930;
2938  if (iext > fNu) goto L930;
2939  if (fNvarl[iext-1] < 0) goto L930;
2940  chwhy = " IS CONSTANT. ";
2941  if (fNvarl[iext-1] == 0) goto L930;
2942  iint = fNiofex[iext-1];
2943  if (ltofix) {
2944  chwhy = " ALREADY FIXED.";
2945  if (iint == 0) goto L930;
2946  mnfixp(iint-1, ierr);
2947  if (ierr == 0) lfixed = kTRUE;
2948  else ierflg = 4;
2949  } else {
2950  chwhy = " ALREADY VARIABLE.";
2951  if (iint > 0) goto L930;
2952  krl = -abs(iext);
2953  mnfree(krl);
2954  lfreed = kTRUE;
2955  }
2956  continue;
2957 L930:
2958  if (fISW[4] >= 0) Printf(" PARAMETER %4d %s IGNORED.",iext,(const char*)chwhy);
2959  }
2960  if (lfreed || lfixed) mnrset(0);
2961  if (lfreed) {
2962  fISW[1] = 0;
2963  fDcovar = 1;
2964  fEDM = fBigedm;
2965  fISW[3] = 0;
2966  }
2967  mnwerr();
2968  if (fISW[4] > 1) mnprin(5, fAmin);
2969  return;
2970 //*-*- . . . . . . . . . . restore
2971 L1000:
2972  it = Int_t(fWord7[0]);
2973  if (it > 1 || it < 0) goto L1005;
2974  lfreed = fNpfix > 0;
2975  mnfree(it);
2976  if (lfreed) {
2977  mnrset(0);
2978  fISW[1] = 0;
2979  fDcovar = 1;
2980  fEDM = fBigedm;
2981  }
2982  return;
2983 L1005:
2984  Printf(" IGNORED. UNKNOWN ARGUMENT:%4d",it);
2985  ierflg = 3;
2986  return;
2987 //*-*- . . . . . . . . . . release
2988 L1100:
2989  ltofix = kFALSE;
2990  goto L901;
2991 //*-*- . . . . . . . . . . scan . . .
2992 L1200:
2993  iext = Int_t(fWord7[0]);
2994  if (iext <= 0) goto L1210;
2995  it2 = 0;
2996  if (iext <= fNu) it2 = fNiofex[iext-1];
2997  if (it2 <= 0) goto L1250;
2998 
2999 L1210:
3000  mnscan();
3001  return;
3002 L1250:
3003  Printf(" PARAMETER %4d NOT VARIABLE.",iext);
3004  ierflg = 3;
3005  return;
3006 //*-*- . . . . . . . . . . contour
3007 L1300:
3008  ke1 = Int_t(fWord7[0]);
3009  ke2 = Int_t(fWord7[1]);
3010  if (ke1 == 0) {
3011  if (fNpar == 2) {
3012  ke1 = fNexofi[0];
3013  ke2 = fNexofi[1];
3014  } else {
3015  Printf("%s: NO PARAMETERS REQUESTED ",(const char*)fCword);
3016  ierflg = 3;
3017  return;
3018  }
3019  }
3020  fNfcnmx = 1000;
3021  mncntr(ke1-1, ke2-1, ierrf);
3022  if (ierrf > 0) ierflg = 3;
3023  return;
3024 //*-*- . . . . . . . . . . hesse
3025 L1400:
3026  mnhess();
3027  mnwerr();
3028  if (fISW[4] >= 0) mnprin(2, fAmin);
3029  if (fISW[4] >= 1) mnmatu(1);
3030  return;
3031 //*-*- . . . . . . . . . . save
3032 L1500:
3033  mnsave();
3034  return;
3035 //*-*- . . . . . . . . . . improve
3036 L1600:
3037  mncuve();
3038  mnimpr();
3039  if (fLnewmn) goto L400;
3040  ierflg = 4;
3041  return;
3042 //*-*- . . . . . . . . . . call fcn
3043 L1700:
3044  iflag = Int_t(fWord7[0]);
3045  nparx = fNpar;
3046  f = fUndefi;
3047  Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
3048  nowprt = 0;
3049  if (f != fUndefi) {
3050  if (fAmin == fUndefi) {
3051  fAmin = f;
3052  nowprt = 1;
3053  } else if (f < fAmin) {
3054  fAmin = f;
3055  nowprt = 1;
3056  }
3057  if (fISW[4] >= 0 && iflag <= 5 && nowprt == 1) {
3058  mnprin(5, fAmin);
3059  }
3060  if (iflag == 3) fFval3 = f;
3061  }
3062  if (iflag > 5) mnrset(1);
3063  return;
3064 //*-*- . . . . . . . . . . standard
3065 L1800:
3066 // stand();
3067  return;
3068 //*-*- . . . return, stop, end, exit
3069 L1900:
3070  it = Int_t(fWord7[0]);
3071  if (fFval3 != fAmin && it == 0) {
3072  iflag = 3;
3073  if (fISW[4] >= 0) Printf(" CALL TO USER FUNCTION WITH IFLAG = 3");
3074  nparx = fNpar;
3075  Eval(nparx, fGin, f, fU, iflag); ++fNfcn;
3076  }
3077  ierflg = 11;
3078  if (fCword(0,3) == "END") ierflg = 10;
3079  if (fCword(0,3) == "RET") ierflg = 12;
3080  return;
3081 //*-*- . . . . . . . . . . clear
3082 L2200:
3083  mncler();
3084  if (fISW[4] >= 1) {
3085  Printf(" MINUIT MEMORY CLEARED. NO PARAMETERS NOW DEFINED.");
3086  }
3087  return;
3088 //*-*- . . . . . . . . . . help
3089 L2300:
3090  kcol = 0;
3091  for (icol = 5; icol <= lk; ++icol) {
3092  if (fCword[icol-1] == ' ') continue;
3093  kcol = icol;
3094  goto L2320;
3095  }
3096 L2320:
3097  if (kcol == 0) comd = "* ";
3098  else comd = fCword(kcol-1,lk-kcol+1);
3099  mnhelp(comd);
3100  return;
3101 //*-*- . . . . . . . . . . MNContour
3102 L2400:
3103  fEpsi = fUp*.05;
3104  ke1 = Int_t(fWord7[0]);
3105  ke2 = Int_t(fWord7[1]);
3106  if (ke1 == 0 && fNpar == 2) {
3107  ke1 = fNexofi[0];
3108  ke2 = fNexofi[1];
3109  }
3110  nptu = Int_t(fWord7[2]);
3111  if (nptu <= 0) nptu = 20;
3112  if (nptu > 101) nptu = 101;
3113  fNfcnmx = (nptu + 5)*100*(fNpar + 1);
3114  mncont(ke1-1, ke2-1, nptu, xptu, yptu, ierrf);
3115  if (ierrf < nptu) ierflg = 4;
3116  if (ierrf == -1) ierflg = 3;
3117  return;
3118 //*-*- . . . . . . . . . . jump
3119 L2600:
3120  step = fWord7[0];
3121  if (step <= 0) step = 2;
3122  rno = 0;
3123  izero = 0;
3124  for (i = 1; i <= fNpar; ++i) {
3125  mnrn15(rno, izero);
3126  rno = rno*2 - 1;
3127  fX[i-1] += rno*step*fWerr[i-1];
3128  }
3129  mninex(fX);
3130  mnamin();
3131  mnrset(0);
3132  return;
3133 //*-*- . . . . . . . . . . blank line
3134 L3300:
3135  Printf(" BLANK COMMAND IGNORED.");
3136  ierflg = 1;
3137  return;
3138 //*-* . . . . . . . . obsolete commands . . . . . . . . . . . . . .
3139 //*-*- . . . . . . . . . . covariance
3140 L3400:
3141  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*");
3142  ierflg = 3;
3143  return;
3144 //*-*- . . . . . . . . . . printout
3145 L3500:
3146  cneway = "SET PRInt ";
3147  goto L3100;
3148 //*-*- . . . . . . . . . . gradient
3149 L3600:
3150  cneway = "SET GRAd ";
3151  goto L3100;
3152 //*-*- . . . . . . . . . . matout
3153 L3700:
3154  cneway = "SHOW COVar";
3155  goto L3100;
3156 //*-*- . . . . . . . . . error def
3157 L3800:
3158  cneway = "SET ERRdef";
3159  goto L3100;
3160 //*-*- . . . . . . . . . . limits
3161 L3900:
3162  cneway = "SET LIMits";
3163  goto L3100;
3164 //*-*- . . . . . . . . . . punch
3165 L4000:
3166  cneway = "SAVE ";
3167 //*-*- ....... come from obsolete commands
3168 L3100:
3169  Printf(" OBSOLETE COMMAND:%s PLEASE USE:%s",(const char*)fCword
3170  ,(const char*)cneway);
3171  fCword = cneway;
3172  if (fCword == "SAVE ") goto L1500;
3173  goto L700;
3174 //*-* . . . . . . . . . . . . . . . . . .
3175 } /* mnexcm_ */
3176 
3177 ////////////////////////////////////////////////////////////////////////////////
3178 ///*-*-*-*-*Transforms the external parameter values U to internal values*-*-*
3179 ///*-* =============================================================
3180 ///*-* Transforms the external parameter values U to internal
3181 ///*-* values in the dense array PINT.
3182 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3183 
3185 {
3186  Double_t pinti;
3187  Int_t iint, iext;
3188 
3189  fLimset = kFALSE;
3190  for (iint = 1; iint <= fNpar; ++iint) {
3191  iext = fNexofi[iint-1];
3192  mnpint(fU[iext-1], iext-1, pinti);
3193  pint[iint-1] = pinti;
3194  }
3195 } /* mnexin_ */
3196 
3197 ////////////////////////////////////////////////////////////////////////////////
3198 ///*-*-*-*-*-*-*Removes parameter IINT from the internal parameter list*-*-*
3199 ///*-* =======================================================
3200 ///*-* and arranges the rest of the list to fill the hole.
3201 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3202 
3203 void TMinuit::mnfixp(Int_t iint1, Int_t &ierr)
3204 {
3205  /* Local variables */
3206  Double_t yyover;
3207  Int_t kold, nold, ndex, knew, iext, i, j, m, n, lc, ik;
3208 
3209 //*-*- first see if it can be done
3210  ierr = 0;
3211  Int_t iint = iint1+1;
3212  if (iint > fNpar || iint <= 0) {
3213  ierr = 1;
3214  Printf(" MINUIT ERROR. ARGUMENT TO MNFIXP=%4d",iint);
3215  return;
3216  }
3217  iext = fNexofi[iint-1];
3218  if (fNpfix >= fMaxpar) {
3219  ierr = 1;
3220  Printf(" MINUIT CANNOT FIX PARAMETER %4d MAXIMUM NUMBER THAT CAN BE FIXED IS %d",iext,fMaxpar);
3221  return;
3222  }
3223 //*-*- reduce number of variable parameters by one
3224 
3225  fNiofex[iext-1] = 0;
3226  nold = fNpar;
3227  --fNpar;
3228 //*-*- save values in case parameter is later restored
3229 
3230  ++fNpfix;
3231  fIpfix[fNpfix-1] = iext;
3232  lc = iint;
3233  fXs[fNpfix-1] = fX[lc-1];
3234  fXts[fNpfix-1] = fXt[lc-1];
3235  fDirins[fNpfix-1] = fWerr[lc-1];
3236  fGrds[fNpfix-1] = fGrd[lc-1];
3237  fG2s[fNpfix-1] = fG2[lc-1];
3238  fGsteps[fNpfix-1] = fGstep[lc-1];
3239 //*-*- shift values for other parameters to fill hole
3240  for (ik = iext + 1; ik <= fNu; ++ik) {
3241  if (fNiofex[ik-1] > 0) {
3242  lc = fNiofex[ik-1] - 1;
3243  fNiofex[ik-1] = lc;
3244  fNexofi[lc-1] = ik;
3245  fX[lc-1] = fX[lc];
3246  fXt[lc-1] = fXt[lc];
3247  fDirin[lc-1] = fDirin[lc];
3248  fWerr[lc-1] = fWerr[lc];
3249  fGrd[lc-1] = fGrd[lc];
3250  fG2[lc-1] = fG2[lc];
3251  fGstep[lc-1] = fGstep[lc];
3252  }
3253  }
3254  if (fISW[1] <= 0) return;
3255 //*-*- remove one row and one column from variance matrix
3256  if (fNpar <= 0) return;
3257  for (i = 1; i <= nold; ++i) {
3258  m = TMath::Max(i,iint);
3259  n = TMath::Min(i,iint);
3260  ndex = m*(m-1) / 2 + n;
3261  fFIXPyy[i-1] = fVhmat[ndex-1];
3262  }
3263  yyover = 1 / fFIXPyy[iint-1];
3264  knew = 0;
3265  kold = 0;
3266  for (i = 1; i <= nold; ++i) {
3267  for (j = 1; j <= i; ++j) {
3268  ++kold;
3269  if (j == iint || i == iint) continue;
3270  ++knew;
3271  fVhmat[knew-1] = fVhmat[kold-1] - fFIXPyy[j-1]*fFIXPyy[i-1]*yyover;
3272  }
3273  }
3274 } /* mnfixp_ */
3275 
3276 ////////////////////////////////////////////////////////////////////////////////
3277 ///*-*-*-*Restores one or more fixed parameter(s) to variable status*-*-*-*-*-*
3278 ///*-* ==========================================================
3279 ///*-* Restores one or more fixed parameter(s) to variable status
3280 ///*-* by inserting it into the internal parameter list at the
3281 ///*-* appropriate place.
3282 ///*-*
3283 ///*-* K = 0 means restore all parameters
3284 ///*-* K = 1 means restore the last parameter fixed
3285 ///*-* K = -I means restore external parameter I (if possible)
3286 ///*-* IQ = fix-location where internal parameters were stored
3287 ///*-* IR = external number of parameter being restored
3288 ///*-* IS = internal number of parameter being restored
3289 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3290 
3292 {
3293  /* Local variables */
3294  Double_t grdv, xv, dirinv, g2v, gstepv, xtv;
3295  Int_t i, ipsav, ka, lc, ik, iq, ir, is;
3296 
3297  if (k > 1) {
3298  Printf(" CALL TO MNFREE IGNORED. ARGUMENT GREATER THAN ONE");
3299  }
3300  if (fNpfix < 1) {
3301  Printf(" CALL TO MNFREE IGNORED. THERE ARE NO FIXED PARAMETERS");
3302  }
3303  if (k == 1 || k == 0) goto L40;
3304 
3305 //*-*- release parameter with specified external number
3306  ka = abs(k);
3307  if (fNiofex[ka-1] == 0) goto L15;
3308  Printf(" IGNORED. PARAMETER SPECIFIED IS ALREADY VARIABLE.");
3309  return;
3310 L15:
3311  if (fNpfix < 1) goto L21;
3312  for (ik = 1; ik <= fNpfix; ++ik) { if (fIpfix[ik-1] == ka) goto L24; }
3313 L21:
3314  Printf(" PARAMETER %4d NOT FIXED. CANNOT BE RELEASED.",ka);
3315  return;
3316 L24:
3317  if (ik == fNpfix) goto L40;
3318 
3319 //*-*- move specified parameter to end of list
3320  ipsav = ka;
3321  xv = fXs[ik-1];
3322  xtv = fXts[ik-1];
3323  dirinv = fDirins[ik-1];
3324  grdv = fGrds[ik-1];
3325  g2v = fG2s[ik-1];
3326  gstepv = fGsteps[ik-1];
3327  for (i = ik + 1; i <= fNpfix; ++i) {
3328  fIpfix[i-2] = fIpfix[i-1];
3329  fXs[i-2] = fXs[i-1];
3330  fXts[i-2] = fXts[i-1];
3331  fDirins[i-2] = fDirins[i-1];
3332  fGrds[i-2] = fGrds[i-1];
3333  fG2s[i-2] = fG2s[i-1];
3334  fGsteps[i-2] = fGsteps[i-1];
3335  }
3336  fIpfix[fNpfix-1] = ipsav;
3337  fXs[fNpfix-1] = xv;
3338  fXts[fNpfix-1] = xtv;
3339  fDirins[fNpfix-1] = dirinv;
3340  fGrds[fNpfix-1] = grdv;
3341  fG2s[fNpfix-1] = g2v;
3342  fGsteps[fNpfix-1] = gstepv;
3343 //*-*- restore last parameter in fixed list -- IPFIX(NPFIX)
3344 L40:
3345  if (fNpfix < 1) goto L300;
3346  ir = fIpfix[fNpfix-1];
3347  is = 0;
3348  for (ik = fNu; ik >= ir; --ik) {
3349  if (fNiofex[ik-1] > 0) {
3350  lc = fNiofex[ik-1] + 1;
3351  is = lc - 1;
3352  fNiofex[ik-1] = lc;
3353  fNexofi[lc-1] = ik;
3354  fX[lc-1] = fX[lc-2];
3355  fXt[lc-1] = fXt[lc-2];
3356  fDirin[lc-1] = fDirin[lc-2];
3357  fWerr[lc-1] = fWerr[lc-2];
3358  fGrd[lc-1] = fGrd[lc-2];
3359  fG2[lc-1] = fG2[lc-2];
3360  fGstep[lc-1] = fGstep[lc-2];
3361  }
3362  }
3363  ++fNpar;
3364  if (is == 0) is = fNpar;
3365  fNiofex[ir-1] = is;
3366  fNexofi[is-1] = ir;
3367  iq = fNpfix;
3368  fX[is-1] = fXs[iq-1];
3369  fXt[is-1] = fXts[iq-1];
3370  fDirin[is-1] = fDirins[iq-1];
3371  fWerr[is-1] = fDirins[iq-1];
3372  fGrd[is-1] = fGrds[iq-1];
3373  fG2[is-1] = fG2s[iq-1];
3374  fGstep[is-1] = fGsteps[iq-1];
3375  --fNpfix;
3376  fISW[1] = 0;
3377  fDcovar = 1;
3378  if (fISW[4] - fItaur >= 1) {
3379  Printf(" PARAMETER %4d %s RESTORED TO VARIABLE.",ir,
3380  (const char*)fCpnam[ir-1]);
3381  }
3382  if (k == 0) goto L40;
3383 L300:
3384 //*-*- if different from internal, external values are taken
3385  mnexin(fX);
3386 } /* mnfree_ */
3387 
3388 ////////////////////////////////////////////////////////////////////////////////
3389 ///*-*-*-*-*-*-*-*-*-*Interprets the SET GRAD command*-*-*-*-*-*-*-*-*-*-*-*-*
3390 ///*-* ===============================
3391 ///*-* Called from MNSET
3392 ///*-* Interprets the SET GRAD command, which informs MINUIT whether
3393 ///*-* the first derivatives of FCN will be calculated by the user
3394 ///*-* inside FCN. It can check the user derivative calculation
3395 ///*-* by comparing it with a finite difference approximation.
3396 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3397 
3399 {
3400  /* Local variables */
3401  Double_t fzero, err;
3402  Int_t i, nparx, lc, istsav;
3403  Bool_t lnone;
3404  static TString cwd = " ";
3405 
3406  fISW[2] = 1;
3407  nparx = fNpar;
3408  if (fWord7[0] > 0) goto L2000;
3409 
3410 //*-*- get user-calculated first derivatives from FCN
3411  for (i = 1; i <= fNu; ++i) { fGin[i-1] = fUndefi; }
3412  mninex(fX);
3413  Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
3414  mnderi();
3415  for (i = 1; i <= fNpar; ++i) { fGRADgf[i-1] = fGrd[i-1]; }
3416 //*-*- get MINUIT-calculated first derivatives
3417  fISW[2] = 0;
3418  istsav = fIstrat;
3419  fIstrat = 2;
3420  mnhes1();
3421  fIstrat = istsav;
3422  Printf(" CHECK OF GRADIENT CALCULATION IN FCN");
3423  Printf(" PARAMETER G(IN FCN) G(MINUIT) DG(MINUIT) AGREEMENT");
3424  fISW[2] = 1;
3425  lnone = kFALSE;
3426  for (lc = 1; lc <= fNpar; ++lc) {
3427  i = fNexofi[lc-1];
3428  cwd = "GOOD";
3429  err = fDgrd[lc-1];
3430  if (TMath::Abs(fGRADgf[lc-1] - fGrd[lc-1]) > err) cwd = " BAD";
3431  if (fGin[i-1] == fUndefi) {
3432  cwd = "NONE";
3433  lnone = kTRUE;
3434  fGRADgf[lc-1] = 0;
3435  }
3436  if (cwd != "GOOD") fISW[2] = 0;
3437  Printf(" %5d %10s%12.4e%12.4e%12.4e %s",i
3438  ,(const char*)fCpnam[i-1]
3439  ,fGRADgf[lc-1],fGrd[lc-1],err,(const char*)cwd);
3440  }
3441  if (lnone) {
3442  Printf(" AGREEMENT=NONE MEANS FCN DID NOT CALCULATE THE DERIVATIVE");
3443  }
3444  if (fISW[2] == 0) {
3445  Printf(" MINUIT DOES NOT ACCEPT DERIVATIVE CALCULATIONS BY FCN");
3446  Printf(" TO FORCE ACCEPTANCE, ENTER *SET GRAD 1*");
3447  }
3448 
3449 L2000:
3450  return;
3451 } /* mngrad_ */
3452 
3453 ////////////////////////////////////////////////////////////////////////////////
3454 ///interface to Minuit help
3455 
3456 void TMinuit::mnhelp(const char *command)
3457 {
3458  TString comd = command;
3459  mnhelp(comd);
3460 }
3461 
3462 ////////////////////////////////////////////////////////////////////////////////
3463 ///*-*-*-*-*-*-*-*HELP routine for MINUIT interactive commands*-*-*-*-*-*-*-*-*
3464 ///*-* ============================================
3465 ///*-*
3466 ///*-* COMD ='*' or "" prints a global help for all commands
3467 ///*-* COMD =Command_name: print detailed help for one command.
3468 ///*-* Note that at least 3 characters must be given for the command
3469 ///*-* name.
3470 ///*-*
3471 ///*-* Author: Rene Brun
3472 ///*-* comments extracted from the MINUIT documentation file.
3473 ///*-*
3474 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
3475 
3477 {
3478 //*-*.......................................................................
3479 //*-*
3480 //*-* Global HELP: Summary of all commands
3481 //*-* ====================================
3482 //*-*
3483  comd.ToUpper();
3484  if( comd.Length() == 0 || comd[0] == '*' || comd[0] == '?' || comd[0] == 0 || comd=="HELP" ) {
3485  Printf(" ==>List of MINUIT Interactive commands:");
3486  Printf(" CLEar Reset all parameter names and values undefined");
3487  Printf(" CONtour Make contour map of the user function");
3488  Printf(" EXIT Exit from Interactive Minuit");
3489  Printf(" FIX Cause parameter(s) to remain constant");
3490  Printf(" HESse Calculate the Hessian or error matrix.");
3491  Printf(" IMPROVE Search for a new minimum around current minimum");
3492  Printf(" MIGrad Minimize by the method of Migrad");
3493  Printf(" MINImize MIGRAD + SIMPLEX method if Migrad fails");
3494  Printf(" MINOs Exact (non-linear) parameter error analysis");
3495  Printf(" MNContour Calculate one MINOS function contour");
3496  Printf(" PARameter Define or redefine new parameters and values");
3497  Printf(" RELease Make previously FIXed parameters variable again");
3498  Printf(" REStore Release last parameter fixed");
3499  Printf(" SAVe Save current parameter values on a file");
3500  Printf(" SCAn Scan the user function by varying parameters");
3501  Printf(" SEEk Minimize by the method of Monte Carlo");
3502  Printf(" SET Set various MINUIT constants or conditions");
3503  Printf(" SHOw Show values of current constants or conditions");
3504  Printf(" SIMplex Minimize by the method of Simplex");
3505  goto L99;
3506  }
3507 
3508 //*-* __________________________________________________________________
3509 //*-*
3510 //*-* -- Command CLEAR
3511 //*-* -- =============
3512 //*-*
3513  if( !strncmp(comd.Data(),"CLE",3) ) {
3514  Printf(" ***>CLEAR");
3515  Printf(" Resets all parameter names and values to undefined.");
3516  Printf(" Must normally be followed by a PARameters command or ");
3517  Printf(" equivalent, in order to define parameter values.");
3518  goto L99;
3519  }
3520 //*-* __________________________________________________________________
3521 //*-* --
3522 //*-* -- Command CONTOUR
3523 //*-* -- ===============
3524 //*-* .
3525  if( !strncmp(comd.Data(),"CON",3) ) {
3526  Printf(" ***>CONTOUR <par1> <par2> [devs] [ngrid]");
3527  Printf(" Instructs Minuit to trace contour lines of the user function");
3528  Printf(" with respect to the two parameters whose external numbers");
3529  Printf(" are <par1> and <par2>.");
3530  Printf(" Other variable parameters of the function, if any, will have");
3531  Printf(" their values fixed at the current values during the contour");
3532  Printf(" tracing. The optional parameter [devs] (default value 2.)");
3533  Printf(" gives the number of standard deviations in each parameter");
3534  Printf(" which should lie entirely within the plotting area.");
3535  Printf(" Optional parameter [ngrid] (default value 25 unless page");
3536  Printf(" size is too small) determines the resolution of the plot,");
3537  Printf(" i.e. the number of rows and columns of the grid at which the");
3538  Printf(" function will be evaluated. [See also MNContour.]");
3539  goto L99;
3540  }
3541 //*-* __________________________________________________________________
3542 //*-* --
3543 //*-* -- Command END
3544 //*-* -- ===========
3545 //*-* .
3546  if( !strncmp(comd.Data(),"END",3) ) {
3547  Printf(" ***>END");
3548  Printf(" Signals the end of a data block (i.e., the end of a fit),");
3549  Printf(" and implies that execution should continue, because another");
3550  Printf(" Data Block follows. A Data Block is a set of Minuit data");
3551  Printf(" consisting of");
3552  Printf(" (1) A Title,");
3553  Printf(" (2) One or more Parameter Definitions,");
3554  Printf(" (3) A blank line, and");
3555  Printf(" (4) A set of Minuit Commands.");
3556  Printf(" The END command is used when more than one Data Block is to");
3557  Printf(" be used with the same FCN function. It first causes Minuit");
3558  Printf(" to issue a CALL FCN with IFLAG=3, in order to allow FCN to");
3559  Printf(" perform any calculations associated with the final fitted");
3560  Printf(" parameter values, unless a CALL FCN 3 command has already");
3561  Printf(" been executed at the current FCN value.");
3562  goto L99;
3563  }
3564 //*-* __________________________________________________________________
3565 //*-* .
3566 //*-* --
3567 //*-* -- Command EXIT
3568 //*-* -- ============
3569  if( !strncmp(comd.Data(),"EXI",3) ) {
3570  Printf(" ***>EXIT");
3571  Printf(" Signals the end of execution.");
3572  Printf(" The EXIT command first causes Minuit to issue a CALL FCN");
3573  Printf(" with IFLAG=3, to allow FCN to perform any calculations");
3574  Printf(" associated with the final fitted parameter values, unless a");
3575  Printf(" CALL FCN 3 command has already been executed.");
3576  goto L99;
3577  }
3578 //*-* __________________________________________________________________
3579 //*-* --
3580 //*-* -- Command FIX
3581 //*-* -- ===========
3582 //*-* .
3583  if( !strncmp(comd.Data(),"FIX",3) ) {
3584  Printf(" ***>FIX} <parno> [parno] ... [parno]");
3585  Printf(" Causes parameter(s) <parno> to be removed from the list of");
3586  Printf(" variable parameters, and their value(s) will remain constant");
3587  Printf(" during subsequent minimizations, etc., until another command");
3588  Printf(" changes their value(s) or status.");
3589  goto L99;
3590  }
3591 //*-* __________________________________________________________________
3592 //*-* --
3593 //*-* -- Command HESSE
3594 //*-* -- =============
3595 //*-* .
3596  if( !strncmp(comd.Data(),"HES",3) ) {
3597  Printf(" ***>HESse [maxcalls]");
3598  Printf(" Calculate, by finite differences, the Hessian or error matrix.");
3599  Printf(" That is, it calculates the full matrix of second derivatives");
3600  Printf(" of the function with respect to the currently variable");
3601  Printf(" parameters, and inverts it, printing out the resulting error");
3602  Printf(" matrix. The optional argument [maxcalls] specifies the");
3603  Printf(" (approximate) maximum number of function calls after which");
3604  Printf(" the calculation will be stopped.");
3605  goto L99;
3606  }
3607 //*-* __________________________________________________________________
3608 //*-* --
3609 //*-* -- Command IMPROVE
3610 //*-* -- ===============
3611 //*-* .
3612  if( !strncmp(comd.Data(),"IMP",3) ) {
3613  Printf(" ***>IMPROVE [maxcalls]");
3614  Printf(" If a previous minimization has converged, and the current");
3615  Printf(" values of the parameters therefore correspond to a local");
3616  Printf(" minimum of the function, this command requests a search for");
3617  Printf(" additional distinct local minima.");
3618  Printf(" The optional argument [maxcalls] specifies the (approximate");
3619  Printf(" maximum number of function calls after which the calculation");
3620  Printf(" will be stopped.");
3621  goto L99;
3622  }
3623 //*-* __________________________________________________________________
3624 //*-* --
3625 //*-* -- Command MIGRAD
3626 //*-* -- ==============
3627 //*-* .
3628  if( !strncmp(comd.Data(),"MIG",3) ) {
3629  Printf(" ***>MIGrad [maxcalls] [tolerance]");
3630  Printf(" Causes minimization of the function by the method of Migrad,");
3631  Printf(" the most efficient and complete single method, recommended");
3632  Printf(" for general functions (see also MINImize).");
3633  Printf(" The minimization produces as a by-product the error matrix");
3634  Printf(" of the parameters, which is usually reliable unless warning");
3635  Printf(" messages are produced.");
3636  Printf(" The optional argument [maxcalls] specifies the (approximate)");
3637  Printf(" maximum number of function calls after which the calculation");
3638  Printf(" will be stopped even if it has not yet converged.");
3639  Printf(" The optional argument [tolerance] specifies required tolerance");
3640  Printf(" on the function value at the minimum.");
3641  Printf(" The default tolerance is 0.1, and the minimization will stop");
3642  Printf(" when the estimated vertical distance to the minimum (EDM) is");
3643  Printf(" less than 0.001*[tolerance]*UP (see [SET ERRordef]).");
3644  goto L99;
3645  }
3646 //*-* __________________________________________________________________
3647 //*-* --
3648 //*-* -- Command MINIMIZE
3649 //*-* -- ================
3650 //*-* .
3651  if( !strncmp(comd.Data(),"MINI",4) ) {
3652  Printf(" ***>MINImize [maxcalls] [tolerance]");
3653  Printf(" Causes minimization of the function by the method of Migrad,");
3654  Printf(" as does the MIGrad command, but switches to the SIMplex method");
3655  Printf(" if Migrad fails to converge. Arguments are as for MIGrad.");
3656  Printf(" Note that command requires four characters to be unambiguous.");
3657  goto L99;
3658  }
3659 //*-* __________________________________________________________________
3660 //*-* --
3661 //*-* -- Command MINOS
3662 //*-* -- =============
3663 //*-* .
3664  if( !strncmp(comd.Data(),"MIN0",4) ) {
3665  Printf(" ***>MINOs [maxcalls] [parno] [parno] ...");
3666  Printf(" Causes a Minos error analysis to be performed on the parameters");
3667  Printf(" whose numbers [parno] are specified. If none are specified,");
3668  Printf(" Minos errors are calculated for all variable parameters.");
3669  Printf(" Minos errors may be expensive to calculate, but are very");
3670  Printf(" reliable since they take account of non-linearities in the");
3671  Printf(" problem as well as parameter correlations, and are in general");
3672  Printf(" asymmetric.");
3673  Printf(" The optional argument [maxcalls] specifies the (approximate)");
3674  Printf(" maximum number of function calls per parameter requested,");
3675  Printf(" after which the calculation will stop for that parameter.");
3676  goto L99;
3677  }
3678 //*-* __________________________________________________________________
3679 //*-* --
3680 //*-* -- Command MNCONTOUR
3681 //*-* -- =================
3682 //*-* .
3683  if( !strncmp(comd.Data(),"MNC",3) ) {
3684  Printf(" ***>MNContour <par1> <par2> [npts]");
3685  Printf(" Calculates one function contour of FCN with respect to");
3686  Printf(" parameters par1 and par2, with FCN minimized always with");
3687  Printf(" respect to all other NPAR-2 variable parameters (if any).");
3688  Printf(" Minuit will try to find npts points on the contour (default 20)");
3689  Printf(" If only two parameters are variable at the time, it is not");
3690  Printf(" necessary to specify their numbers. To calculate more than");
3691  Printf(" one contour, it is necessary to SET ERRordef to the appropriate");
3692  Printf(" value and issue the MNContour command for each contour.");
3693  goto L99;
3694  }
3695 //*-* __________________________________________________________________
3696 //*-* --
3697 //*-* -- Command PARAMETER
3698 //*-* -- =================
3699 //*-* .
3700  if( !strncmp(comd.Data(),"PAR",3) ) {
3701  Printf(" ***>PARameters");
3702  Printf(" followed by one or more parameter definitions.");
3703  Printf(" Parameter definitions are of the form:");
3704  Printf(" <number> ''name'' <value> <step> [lolim] [uplim] ");
3705  Printf(" for example:");
3706  Printf(" 3 ''K width'' 1.2 0.1");
3707  Printf(" the last definition is followed by a blank line or a zero.");
3708  goto L99;
3709  }
3710 //*-* __________________________________________________________________
3711 //*-* --
3712 //*-* -- Command RELEASE
3713 //*-* -- ===============
3714 //*-* .
3715  if( !strncmp(comd.Data(),"REL",3) ) {
3716  Printf(" ***>RELease <parno> [parno] ... [parno]");
3717  Printf(" If <parno> is the number of a previously variable parameter");
3718  Printf(" which has been fixed by a command: FIX <parno>, then that");
3719  Printf(" parameter will return to variable status. Otherwise a warning");
3720  Printf(" message is printed and the command is ignored.");
3721  Printf(" Note that this command operates only on parameters which were");
3722  Printf(" at one time variable and have been FIXed. It cannot make");
3723  Printf(" constant parameters variable; that must be done by redefining");
3724  Printf(" the parameter with a PARameters command.");
3725  goto L99;
3726  }
3727 //*-* __________________________________________________________________
3728 //*-* --
3729 //*-* -- Command RESTORE
3730 //*-* -- ===============
3731 //*-* .
3732  if( !strncmp(comd.Data(),"RES",3) ) {
3733  Printf(" ***>REStore [code]");
3734  Printf(" If no [code] is specified, this command restores all previously");
3735  Printf(" FIXed parameters to variable status. If [code]=1, then only");
3736  Printf(" the last parameter FIXed is restored to variable status.");
3737  Printf(" If code is neither zero nor one, the command is ignored.");
3738  goto L99;
3739  }
3740 //*-* __________________________________________________________________
3741 //*-* --
3742 //*-* -- Command RETURN
3743 //*-* -- ==============
3744 //*-* .
3745  if( !strncmp(comd.Data(),"RET",3) ) {
3746  Printf(" ***>RETURN");
3747  Printf(" Signals the end of a data block, and instructs Minuit to return");
3748  Printf(" to the program which called it. The RETurn command first");
3749  Printf(" causes Minuit to CALL FCN with IFLAG=3, in order to allow FCN");
3750  Printf(" to perform any calculations associated with the final fitted");
3751  Printf(" parameter values, unless a CALL FCN 3 command has already been");
3752  Printf(" executed at the current FCN value.");
3753  goto L99;
3754  }
3755 //*-* __________________________________________________________________
3756 //*-* --
3757 //*-* -- Command SAVE
3758 //*-* -- ============
3759 //*-* .
3760  if( !strncmp(comd.Data(),"SAV",3) ) {
3761  Printf(" ***>SAVe");
3762  Printf(" Causes the current parameter values to be saved on a file in");
3763  Printf(" such a format that they can be read in again as Minuit");
3764  Printf(" parameter definitions. If the covariance matrix exists, it is");
3765  Printf(" also output in such a format. The unit number is by default 7,");
3766  Printf(" or that specified by the user in their call to MINTIO or");
3767  Printf(" MNINIT. The user is responsible for opening the file previous");
3768  Printf(" to issuing the [SAVe] command (except where this can be done");
3769  Printf(" interactively).");
3770  goto L99;
3771  }
3772 //*-* __________________________________________________________________
3773 //*-* --
3774 //*-* -- Command SCAN
3775 //*-* -- ============
3776 //*-* .
3777  if( !strncmp(comd.Data(),"SCA",3) ) {
3778  Printf(" ***>SCAn [parno] [numpts] [from] [to]");
3779  Printf(" Scans the value of the user function by varying parameter");
3780  Printf(" number [parno], leaving all other parameters fixed at the");
3781  Printf(" current value. If [parno] is not specified, all variable");
3782  Printf(" parameters are scanned in sequence.");
3783  Printf(" The number of points [numpts] in the scan is 40 by default,");
3784  Printf(" and cannot exceed 100. The range of the scan is by default");
3785  Printf(" 2 standard deviations on each side of the current best value,");
3786  Printf(" but can be specified as from [from] to [to].");
3787  Printf(" After each scan, if a new minimum is found, the best parameter");
3788  Printf(" values are retained as start values for future scans or");
3789  Printf(" minimizations. The curve resulting from each scan is plotted");
3790  Printf(" on the output unit in order to show the approximate behaviour");
3791  Printf(" of the function.");
3792  Printf(" This command is not intended for minimization, but is sometimes");
3793  Printf(" useful for debugging the user function or finding a");
3794  Printf(" reasonable starting point.");
3795  goto L99;
3796  }
3797 //*-* __________________________________________________________________
3798 //*-* --
3799 //*-* -- Command SEEK
3800 //*-* -- ============
3801 //*-* .
3802  if( !strncmp(comd.Data(),"SEE",3) ) {
3803  Printf(" ***>SEEk [maxcalls] [devs]");
3804  Printf(" Causes a Monte Carlo minimization of the function, by choosing");
3805  Printf(" random values of the variable parameters, chosen uniformly");
3806  Printf(" over a hypercube centered at the current best value.");
3807  Printf(" The region size is by default 3 standard deviations on each");
3808  Printf(" side, but can be changed by specifying the value of [devs].");
3809  goto L99;
3810  }
3811 //*-* __________________________________________________________________
3812 //*-* --
3813 //*-* -- Command SET
3814 //*-* -- ===========
3815 //*-* .
3816  if( !strncmp(comd.Data(),"SET",3) ) {
3817  Printf(" ***>SET <option_name>");
3818  Printf(" SET BATch");
3819  Printf(" Informs Minuit that it is running in batch mode.");
3820 
3821  Printf(" ");
3822  Printf(" SET EPSmachine <accuracy>");
3823  Printf(" Informs Minuit that the relative floating point arithmetic");
3824  Printf(" precision is <accuracy>. Minuit determines the nominal");
3825  Printf(" precision itself, but the SET EPSmachine command can be");
3826  Printf(" used to override Minuit own determination, when the user");
3827  Printf(" knows that the FCN function value is not calculated to");
3828  Printf(" the nominal machine accuracy. Typical values of <accuracy>");
3829  Printf(" are between 10**-5 and 10**-14.");
3830 
3831  Printf(" ");
3832  Printf(" SET ERRordef <up>");
3833  Printf(" Sets the value of UP (default value= 1.), defining parameter");
3834  Printf(" errors. Minuit defines parameter errors as the change");
3835  Printf(" in parameter value required to change the function value");
3836  Printf(" by UP. Normally, for chisquared fits UP=1, and for negative");
3837  Printf(" log likelihood, UP=0.5.");
3838 
3839  Printf(" ");
3840  Printf(" SET GRAdient [force]");
3841  Printf(" Informs Minuit that the user function is prepared to");
3842  Printf(" calculate its own first derivatives and return their values");
3843  Printf(" in the array GRAD when IFLAG=2 (see specs of FCN).");
3844  Printf(" If [force] is not specified, Minuit will calculate");
3845  Printf(" the FCN derivatives by finite differences at the current");
3846  Printf(" point and compare with the user calculation at that point,");
3847  Printf(" accepting the user values only if they agree.");
3848  Printf(" If [force]=1, Minuit does not do its own derivative");
3849  Printf(" calculation, and uses the derivatives calculated in FCN.");
3850 
3851  Printf(" ");
3852  Printf(" SET INPut [unitno] [filename]");
3853  Printf(" Causes Minuit, in data-driven mode only, to read subsequent");
3854  Printf(" commands (or parameter definitions) from a different input");
3855  Printf(" file. If no [unitno] is specified, reading reverts to the");
3856  Printf(" previous input file, assuming that there was one.");
3857  Printf(" If [unitno] is specified, and that unit has not been opened,");
3858  Printf(" then Minuit attempts to open the file [filename]} if a");
3859  Printf(" name is specified. If running in interactive mode and");
3860  Printf(" [filename] is not specified and [unitno] is not opened,");
3861  Printf(" Minuit prompts the user to enter a file name.");
3862  Printf(" If the word REWIND is added to the command (note:no blanks");
3863  Printf(" between INPUT and REWIND), the file is rewound before");
3864  Printf(" reading. Note that this command is implemented in standard");
3865  Printf(" Fortran 77 and the results may depend on the system;");
3866  Printf(" for example, if a filename is given under VM/CMS, it must");
3867  Printf(" be preceded by a slash.");
3868 
3869  Printf(" ");
3870  Printf(" SET INTeractive");
3871  Printf(" Informs Minuit that it is running interactively.");
3872 
3873  Printf(" ");
3874  Printf(" SET LIMits [parno] [lolim] [uplim]");
3875  Printf(" Allows the user to change the limits on one or all");
3876  Printf(" parameters. If no arguments are specified, all limits are");
3877  Printf(" removed from all parameters. If [parno] alone is specified,");
3878  Printf(" limits are removed from parameter [parno].");
3879  Printf(" If all arguments are specified, then parameter [parno] will");
3880  Printf(" be bounded between [lolim] and [uplim].");
3881  Printf(" Limits can be specified in either order, Minuit will take");
3882  Printf(" the smaller as [lolim] and the larger as [uplim].");
3883  Printf(" However, if [lolim] is equal to [uplim], an error condition");
3884  Printf(" results.");
3885 
3886  Printf(" ");
3887  Printf(" SET LINesperpage");
3888  Printf(" Sets the number of lines for one page of output.");
3889  Printf(" Default value is 24 for interactive mode");
3890 
3891  Printf(" ");
3892  Printf(" SET NOGradient");
3893  Printf(" The inverse of SET GRAdient, instructs Minuit not to");
3894  Printf(" use the first derivatives calculated by the user in FCN.");
3895 
3896  Printf(" ");
3897  Printf(" SET NOWarnings");
3898  Printf(" Supresses Minuit warning messages.");
3899 
3900  Printf(" ");
3901  Printf(" SET OUTputfile <unitno>");
3902  Printf(" Instructs Minuit to write further output to unit <unitno>.");
3903 
3904  Printf(" ");
3905  Printf(" SET PAGethrow <integer>");
3906  Printf(" Sets the carriage control character for ``new page'' to");
3907  Printf(" <integer>. Thus the value 1 produces a new page, and 0");
3908  Printf(" produces a blank line, on some devices (see TOPofpage)");
3909 
3910 
3911  Printf(" ");
3912  Printf(" SET PARameter <parno> <value>");
3913  Printf(" Sets the value of parameter <parno> to <value>.");
3914  Printf(" The parameter in question may be variable, fixed, or");
3915  Printf(" constant, but must be defined.");
3916 
3917  Printf(" ");
3918  Printf(" SET PRIntout <level>");
3919  Printf(" Sets the print level, determining how much output will be");
3920  Printf(" produced. Allowed values and their meanings are displayed");
3921  Printf(" after a SHOw PRInt command, and are currently <level>=:");
3922  Printf(" [-1] no output except from SHOW commands");
3923  Printf(" [0] minimum output");
3924  Printf(" [1] default value, normal output");
3925  Printf(" [2] additional output giving intermediate results.");
3926  Printf(" [3] maximum output, showing progress of minimizations.");
3927  Printf(" Note: See also the SET WARnings command.");
3928 
3929  Printf(" ");
3930  Printf(" SET RANdomgenerator <seed>");
3931  Printf(" Sets the seed of the random number generator used in SEEk.");
3932  Printf(" This can be any integer between 10000 and 900000000, for");
3933  Printf(" example one which was output from a SHOw RANdom command of");
3934  Printf(" a previous run.");
3935 
3936  Printf(" ");
3937  Printf(" SET STRategy <level>");
3938  Printf(" Sets the strategy to be used in calculating first and second");
3939  Printf(" derivatives and in certain minimization methods.");
3940  Printf(" In general, low values of <level> mean fewer function calls");
3941  Printf(" and high values mean more reliable minimization.");
3942  Printf(" Currently allowed values are 0, 1 (default), and 2.");
3943 
3944  Printf(" ");
3945  Printf(" SET TITle");
3946  Printf(" Informs Minuit that the next input line is to be considered");
3947  Printf(" the (new) title for this task or sub-task. This is for");
3948  Printf(" the convenience of the user in reading their output.");
3949 
3950  Printf(" ");
3951  Printf(" SET WARnings");
3952  Printf(" Instructs Minuit to output warning messages when suspicious");
3953  Printf(" conditions arise which may indicate unreliable results.");
3954  Printf(" This is the default.");
3955 
3956  Printf(" ");
3957  Printf(" SET WIDthpage");
3958  Printf(" Informs Minuit of the output page width.");
3959  Printf(" Default values are 80 for interactive jobs");
3960  goto L99;
3961  }
3962 //*-* __________________________________________________________________
3963 //*-* --
3964 //*-* -- Command SHOW
3965 //*-* -- ============
3966 //*-* .
3967  if( !strncmp(comd.Data(),"SHO",3) ) {
3968  Printf(" ***>SHOw <option_name>");
3969  Printf(" All SET XXXX commands have a corresponding SHOw XXXX command.");
3970  Printf(" In addition, the SHOw commands listed starting here have no");
3971  Printf(" corresponding SET command for obvious reasons.");
3972 
3973  Printf(" ");
3974  Printf(" SHOw CORrelations");
3975  Printf(" Calculates and prints the parameter correlations from the");
3976  Printf(" error matrix.");
3977 
3978  Printf(" ");
3979  Printf(" SHOw COVariance");
3980  Printf(" Prints the (external) covariance (error) matrix.");
3981 
3982  Printf(" ");
3983  Printf(" SHOw EIGenvalues");
3984  Printf(" Calculates and prints the eigenvalues of the covariance");
3985  Printf(" matrix.");
3986 
3987  Printf(" ");
3988  Printf(" SHOw FCNvalue");
3989  Printf(" Prints the current value of FCN.");
3990  goto L99;
3991  }
3992 //*-* __________________________________________________________________
3993 //*-* --
3994 //*-* -- Command SIMPLEX
3995 //*-* -- ===============
3996 //*-* .
3997  if( !strncmp(comd.Data(),"SIM",3) ) {
3998  Printf(" ***>SIMplex [maxcalls] [tolerance]");
3999  Printf(" Performs a function minimization using the simplex method of");
4000  Printf(" Nelder and Mead. Minimization terminates either when the");
4001  Printf(" function has been called (approximately) [maxcalls] times,");
4002  Printf(" or when the estimated vertical distance to minimum (EDM) is");
4003  Printf(" less than [tolerance].");
4004  Printf(" The default value of [tolerance] is 0.1*UP(see SET ERRordef).");
4005  goto L99;
4006  }
4007 //*-* __________________________________________________________________
4008 //*-* --
4009 //*-* -- Command STANDARD
4010 //*-* -- ================
4011 //*-* .
4012  if( !strncmp(comd.Data(),"STA",3) ) {
4013  Printf(" ***>STAndard");
4014  goto L99;
4015  }
4016 //*-* __________________________________________________________________
4017 //*-* --
4018 //*-* -- Command STOP
4019 //*-* -- ============
4020 //*-* .
4021  if( !strncmp(comd.Data(),"STO",3) ) {
4022  Printf(" ***>STOP");
4023  Printf(" Same as EXIT.");
4024  goto L99;
4025  }
4026 //*-* __________________________________________________________________
4027 //*-* --
4028 //*-* -- Command TOPOFPAGE
4029 //*-* -- =================
4030 //*-* .
4031  if( !strncmp(comd.Data(),"TOP",3) ) {
4032  Printf(" ***>TOPofpage");
4033  Printf(" Causes Minuit to write the character specified in a");
4034  Printf(" SET PAGethrow command (default = 1) to column 1 of the output");
4035  Printf(" file, which may or may not position your output medium to");
4036  Printf(" the top of a page depending on the device and system.");
4037  goto L99;
4038  }
4039 //*-* __________________________________________________________________
4040  Printf(" Unknown MINUIT command. Type HELP for list of commands.");
4041 
4042 L99:
4043  return;
4044 } /* mnhelp_ */
4045 
4046 ////////////////////////////////////////////////////////////////////////////////
4047 ///*-*-*-*-*-*Calculates the full second-derivative matrix of FCN*-*-*-*-*-*-*-*
4048 ///*-* ===================================================
4049 ///*-* by taking finite differences. When calculating diagonal
4050 ///*-* elements, it may iterate so that step size is nearly that
4051 ///*-* which gives function change= UP/10. The first derivatives
4052 ///*-* of course come as a free side effect, but with a smaller
4053 ///*-* step size in order to obtain a known accuracy.
4054 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4055 
4057 {
4058  /* Local variables */
4059  Double_t dmin_, dxdi, elem, wint, tlrg2, d, dlast, ztemp, g2bfor;
4060  Double_t df, aimsag, fs1, tlrstp, fs2, stpinm, g2i, sag=0, xtf, xti, xtj;
4061  Int_t icyc, ncyc, ndex, idrv, iext, npar2, i, j, ifail, npard, nparx, id, multpy;
4062  Bool_t ldebug;
4063 
4064  ldebug = fIdbg[3] >= 1;
4065  if (fAmin == fUndefi) {
4066  mnamin();
4067  }
4068  if (fIstrat <= 0) {
4069  ncyc = 3;
4070  tlrstp = .5;
4071  tlrg2 = .1;
4072  } else if (fIstrat == 1) {
4073  ncyc = 5;
4074  tlrstp = .3;
4075  tlrg2 = .05;
4076  } else {
4077  ncyc = 7;
4078  tlrstp = .1;
4079  tlrg2 = .02;
4080  }
4081  if (fISW[4] >= 2 || ldebug) {
4082  Printf(" START COVARIANCE MATRIX CALCULATION.");
4083  }
4084  fCfrom = "HESSE ";
4085  fNfcnfr = fNfcn;
4086  fCstatu = "OK ";
4087  npard = fNpar;
4088 //*-*- make sure starting at the right place
4089  mninex(fX);
4090  nparx = fNpar;
4091  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4092  if (fs1 != fAmin) {
4093  df = fAmin - fs1;
4094  mnwarn("D", "MNHESS", TString::Format("function value differs from AMIN by %g",df));
4095  }
4096  fAmin = fs1;
4097  if (ldebug) {
4098  Printf(" PAR D GSTEP D G2 GRD SAG ");
4099  }
4100 //*-*- . . . . . . diagonal elements .
4101 
4102 //*-*- fISW[1] = 1 if approx, 2 if not posdef, 3 if ok
4103 //*-*- AIMSAG is the sagitta we are aiming for in second deriv calc.
4104 
4105  aimsag = TMath::Sqrt(fEpsma2)*(TMath::Abs(fAmin) + fUp);
4106 //*-*- Zero the second derivative matrix
4107  npar2 = fNpar*(fNpar + 1) / 2;
4108  for (i = 1; i <= npar2; ++i) { fVhmat[i-1] = 0; }
4109 
4110 //*-*- Loop over variable parameters for second derivatives
4111  idrv = 2;
4112  for (id = 1; id <= npard; ++id) {
4113  i = id + fNpar - npard;
4114  iext = fNexofi[i-1];
4115  if (fG2[i-1] == 0) {
4116  mnwarn("W", "HESSE", Form("Second derivative enters zero, param %d",iext));
4117  wint = fWerr[i-1];
4118  if (fNvarl[iext-1] > 1) {
4119  mndxdi(fX[i-1], i-1, dxdi);
4120  if (TMath::Abs(dxdi) < .001) wint = .01;
4121  else wint /= TMath::Abs(dxdi);
4122  }
4123  fG2[i-1] = fUp / (wint*wint);
4124  }
4125  xtf = fX[i-1];
4126  dmin_ = fEpsma2*8*TMath::Abs(xtf);
4127 
4128 //*-*- find step which gives sagitta = AIMSAG
4129  d = TMath::Abs(fGstep[i-1]);
4130  int skip50 = 0;
4131  for (icyc = 1; icyc <= ncyc; ++icyc) {
4132 //*-*- loop here only if SAG=0
4133  for (multpy = 1; multpy <= 5; ++multpy) {
4134 //*-*- take two steps
4135  fX[i-1] = xtf + d;
4136  mninex(fX);
4137  nparx = fNpar;
4138  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4139  fX[i-1] = xtf - d;
4140  mninex(fX);
4141  Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
4142  fX[i-1] = xtf;
4143  sag = (fs1 + fs2 - fAmin*2)*.5;
4144  if (sag != 0) goto L30;
4145  if (fGstep[i-1] < 0) {
4146  if (d >= .5) goto L26;
4147  d *= 10;
4148  if (d > .5) d = .51;
4149  continue;
4150  }
4151  d *= 10;
4152  }
4153 L26:
4154  mnwarn("W", "HESSE", TString::Format("Second derivative zero for parameter%d",iext));
4155  goto L390;
4156 //*-*- SAG is not zero
4157 L30:
4158  g2bfor = fG2[i-1];
4159  fG2[i-1] = sag*2 / (d*d);
4160  fGrd[i-1] = (fs1 - fs2) / (d*2);
4161  if (ldebug) {
4162  Printf("%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],d,fG2[i-1],fGrd[i-1],sag);
4163  }
4164  if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(d);
4165  else fGstep[i-1] = -TMath::Abs(d);
4166  fDirin[i-1] = d;
4167  fHESSyy[i-1]= fs1;
4168  dlast = d;
4169  d = TMath::Sqrt(aimsag*2 / TMath::Abs(fG2[i-1]));
4170 //*-*- if parameter has limits, max int step size = 0.5
4171  stpinm = .5;
4172  if (fGstep[i-1] < 0) d = TMath::Min(d,stpinm);
4173  if (d < dmin_) d = dmin_;
4174 //*-*- see if converged
4175  if (TMath::Abs((d - dlast) / d) < tlrstp ||
4176  TMath::Abs((fG2[i-1] - g2bfor) / fG2[i-1]) < tlrg2) {
4177  skip50 = 1;
4178  break;
4179  }
4180  d = TMath::Min(d,dlast*102);
4181  d = TMath::Max(d,dlast*.1);
4182  }
4183 //*-*- end of step size loop
4184  if (!skip50)
4185  mnwarn("D", "MNHESS", TString::Format("Second Deriv. SAG,AIM= %d%g%g",iext,sag,aimsag));
4186 
4187  ndex = i*(i + 1) / 2;
4188  fVhmat[ndex-1] = fG2[i-1];
4189  }
4190 //*-*- end of diagonal second derivative loop
4191  mninex(fX);
4192 //*-*- refine the first derivatives
4193  if (fIstrat > 0) mnhes1();
4194  fISW[1] = 3;
4195  fDcovar = 0;
4196 //*-*- . . . . off-diagonal elements
4197 
4198  if (fNpar == 1) goto L214;
4199  for (i = 1; i <= fNpar; ++i) {
4200  for (j = 1; j <= i-1; ++j) {
4201  xti = fX[i-1];
4202  xtj = fX[j-1];
4203  fX[i-1] = xti + fDirin[i-1];
4204  fX[j-1] = xtj + fDirin[j-1];
4205  mninex(fX);
4206  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4207  fX[i-1] = xti;
4208  fX[j-1] = xtj;
4209  elem = (fs1 + fAmin - fHESSyy[i-1] - fHESSyy[j-1]) / (
4210  fDirin[i-1]*fDirin[j-1]);
4211  ndex = i*(i-1) / 2 + j;
4212  fVhmat[ndex-1] = elem;
4213  }
4214  }
4215 L214:
4216  mninex(fX);
4217 //*-*- verify matrix positive-definite
4218  mnpsdf();
4219  for (i = 1; i <= fNpar; ++i) {
4220  for (j = 1; j <= i; ++j) {
4221  ndex = i*(i-1) / 2 + j;
4222  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
4223  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
4224  }
4225  }
4226  mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
4227  if (ifail > 0) {
4228  mnwarn("W", "HESSE", "Matrix inversion fails.");
4229  goto L390;
4230  }
4231 //*-*- . . . . . . . calculate e d m
4232  fEDM = 0;
4233 
4234  for (i = 1; i <= fNpar; ++i) {
4235 //*-*- off-diagonal elements
4236  ndex = i*(i-1) / 2;
4237  for (j = 1; j <= i-1; ++j) {
4238  ++ndex;
4239  ztemp = fP[i + j*fMaxpar - fMaxpar-1]*2;
4240  fEDM += fGrd[i-1]*ztemp*fGrd[j-1];
4241  fVhmat[ndex-1] = ztemp;
4242  }
4243 //*-*- diagonal elements
4244  ++ndex;
4245  fVhmat[ndex-1] = fP[i + i*fMaxpar - fMaxpar-1]*2;
4246  fEDM += fP[i + i*fMaxpar - fMaxpar-1]*(fGrd[i-1]*fGrd[i-1]);
4247  }
4248  if (fISW[4] >= 1 && fISW[1] == 3 && fItaur == 0) {
4249  Printf(" COVARIANCE MATRIX CALCULATED SUCCESSFULLY");
4250  }
4251  goto L900;
4252 //*-*- failure to invert 2nd deriv matrix
4253 L390:
4254  fISW[1] = 1;
4255  fDcovar = 1;
4256  fCstatu = "FAILED ";
4257  if (fISW[4] >= 0) {
4258  Printf(" MNHESS FAILS AND WILL RETURN DIAGONAL MATRIX. ");
4259  }
4260  for (i = 1; i <= fNpar; ++i) {
4261  ndex = i*(i-1) / 2;
4262  for (j = 1; j <= i-1; ++j) {
4263  ++ndex;
4264  fVhmat[ndex-1] = 0;
4265  }
4266  ++ndex;
4267  g2i = fG2[i-1];
4268  if (g2i <= 0) g2i = 1;
4269  fVhmat[ndex-1] = 2 / g2i;
4270  }
4271 L900:
4272  return;
4273 } /* mnhess_ */
4274 
4275 ////////////////////////////////////////////////////////////////////////////////
4276 ///*-*-*-*Calculate first derivatives (GRD) and uncertainties (DGRD)*-*-*-*-*-*
4277 ///*-* ==========================================================
4278 ///*-* and appropriate step sizes GSTEP
4279 ///*-* Called from MNHESS and MNGRAD
4280 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4281 
4283 {
4284  /* Local variables */
4285  Double_t dmin_, d, dfmin, dgmin=0, change, chgold, grdold=0, epspri;
4286  Double_t fs1, optstp, fs2, grdnew=0, sag, xtf;
4287  Int_t icyc, ncyc=0, idrv, i, nparx;
4288  Bool_t ldebug;
4289 
4290  ldebug = fIdbg[5] >= 1;
4291  if (fIstrat <= 0) ncyc = 1;
4292  if (fIstrat == 1) ncyc = 2;
4293  if (fIstrat > 1) ncyc = 6;
4294  idrv = 1;
4295  nparx = fNpar;
4296  dfmin = fEpsma2*4*(TMath::Abs(fAmin) + fUp);
4297 //*-*- main loop over parameters
4298  for (i = 1; i <= fNpar; ++i) {
4299  xtf = fX[i-1];
4300  dmin_ = fEpsma2*4*TMath::Abs(xtf);
4301  epspri = fEpsma2 + TMath::Abs(fGrd[i-1]*fEpsma2);
4302  optstp = TMath::Sqrt(dfmin / (TMath::Abs(fG2[i-1]) + epspri));
4303  d = TMath::Abs(fGstep[i-1])*.2;
4304  if (d > optstp) d = optstp;
4305  if (d < dmin_) d = dmin_;
4306  chgold = 1e4;
4307 //*-*- iterate reducing step size
4308  for (icyc = 1; icyc <= ncyc; ++icyc) {
4309  fX[i-1] = xtf + d;
4310  mninex(fX);
4311  Eval(nparx, fGin, fs1, fU, 4); ++fNfcn;
4312  fX[i-1] = xtf - d;
4313  mninex(fX);
4314  Eval(nparx, fGin, fs2, fU, 4); ++fNfcn;
4315  fX[i-1] = xtf;
4316 //*-*- check if step sizes appropriate
4317  sag = (fs1 + fs2 - fAmin*2)*.5;
4318  grdold = fGrd[i-1];
4319  grdnew = (fs1 - fs2) / (d*2);
4320  dgmin = fEpsmac*(TMath::Abs(fs1) + TMath::Abs(fs2)) / d;
4321  if (ldebug) {
4322  Printf("%4d%2d%12.5g%12.5g%12.5g%12.5g%12.5g",i,idrv,fGstep[i-1],d,fG2[i-1],grdnew,sag);
4323  }
4324  if (grdnew == 0) goto L60;
4325  change = TMath::Abs((grdold - grdnew) / grdnew);
4326  if (change > chgold && icyc > 1) goto L60;
4327  chgold = change;
4328  fGrd[i-1] = grdnew;
4329  if (fGstep[i-1] > 0) fGstep[i-1] = TMath::Abs(d);
4330  else fGstep[i-1] = -TMath::Abs(d);
4331 //*-*- decrease step until first derivative changes by <5%
4332  if (change < .05) goto L60;
4333  if (TMath::Abs(grdold - grdnew) < dgmin) goto L60;
4334  if (d < dmin_) {
4335  mnwarn("D", "MNHES1", "Step size too small for 1st drv.");
4336  goto L60;
4337  }
4338  d *= .2;
4339  }
4340 //*-*- loop satisfied = too many iter
4341  mnwarn("D", "MNHES1", TString::Format("Too many iterations on D1.%g%g",grdold,grdnew));
4342 L60:
4343  fDgrd[i-1] = TMath::Max(dgmin,TMath::Abs(grdold - grdnew));
4344  }
4345 //*-*- end of first deriv. loop
4346  mninex(fX);
4347 } /* mnhes1_ */
4348 
4349 ////////////////////////////////////////////////////////////////////////////////
4350 ///*-*-*-*-*-*-*Attempts to improve on a good local minimum*-*-*-*-*-*-*-*-*-*
4351 ///*-* ===========================================
4352 ///*-* Attempts to improve on a good local minimum by finding a
4353 ///*-* better one. The quadratic part of FCN is removed by MNCALF
4354 ///*-* and this transformed function is minimized using the simplex
4355 ///*-* method from several random starting points.
4356 ///*-* ref. -- Goldstein and Price, Math.Comp. 25, 569 (1971)
4357 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4358 
4360 {
4361  /* Initialized data */
4362 
4363  static Double_t rnum = 0;
4364 
4365  /* Local variables */
4366  Double_t amax, ycalf, ystar, ystst;
4367  Double_t pb, ep, wg, xi, sigsav, reg, sig2;
4368  Int_t npfn, ndex, loop=0, i, j, ifail, iseed=0;
4369  Int_t jhold, nloop, nparx, nparp1, jh, jl, iswtr;
4370 
4371  if (fNpar <= 0) return;
4372  if (fAmin == fUndefi) mnamin();
4373  fCstatu = "UNCHANGED ";
4374  fItaur = 1;
4375  fEpsi = fUp*.1;
4376  npfn = fNfcn;
4377  nloop = Int_t(fWord7[1]);
4378  if (nloop <= 0) nloop = fNpar + 4;
4379  nparx = fNpar;
4380  nparp1 = fNpar + 1;
4381  wg = 1 / Double_t(fNpar);
4382  sigsav = fEDM;
4383  fApsi = fAmin;
4384  iswtr = fISW[4] - 2*fItaur;
4385  for (i = 1; i <= fNpar; ++i) {
4386  fXt[i-1] = fX[i-1];
4387  fIMPRdsav[i-1] = fWerr[i-1];
4388  for (j = 1; j <= i; ++j) {
4389  ndex = i*(i-1) / 2 + j;
4390  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1];
4391  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
4392  }
4393  }
4394  mnvert(fP, fMaxint, fMaxint, fNpar, ifail);
4395  if (ifail >= 1) goto L280;
4396 //*-*- Save inverted matrix in VT
4397  for (i = 1; i <= fNpar; ++i) {
4398  ndex = i*(i-1) / 2;
4399  for (j = 1; j <= i; ++j) {
4400  ++ndex;
4401  fVthmat[ndex-1] = fP[i + j*fMaxpar - fMaxpar-1];
4402  }
4403  }
4404  loop = 0;
4405 
4406 L20:
4407  for (i = 1; i <= fNpar; ++i) {
4408  fDirin[i-1] = fIMPRdsav[i-1]*2;
4409  mnrn15(rnum, iseed);
4410  fX[i-1] = fXt[i-1] + fDirin[i-1]*2*(rnum - .5);
4411  }
4412  ++loop;
4413  reg = 2;
4414  if (fISW[4] >= 0) {
4415  Printf("START ATTEMPT NO.%2d TO FIND NEW MINIMUM",loop);
4416  }
4417 L30:
4418  mncalf(fX, ycalf);
4419  fAmin = ycalf;
4420 //*-*- . . . . set up random simplex
4421  jl = nparp1;
4422  jh = nparp1;
4423  fIMPRy[nparp1-1] = fAmin;
4424  amax = fAmin;
4425  for (i = 1; i <= fNpar; ++i) {
4426  xi = fX[i-1];
4427  mnrn15(rnum, iseed);
4428  fX[i-1] = xi - fDirin[i-1]*(rnum - .5);
4429  mncalf(fX, ycalf);
4430  fIMPRy[i-1] = ycalf;
4431  if (fIMPRy[i-1] < fAmin) {
4432  fAmin = fIMPRy[i-1];
4433  jl = i;
4434  } else if (fIMPRy[i-1] > amax) {
4435  amax = fIMPRy[i-1];
4436  jh = i;
4437  }
4438  for (j = 1; j <= fNpar; ++j) { fP[j + i*fMaxpar - fMaxpar-1] = fX[j-1]; }
4439  fP[i + nparp1*fMaxpar - fMaxpar-1] = xi;
4440  fX[i-1] = xi;
4441  }
4442 
4443  fEDM = fAmin;
4444  sig2 = fEDM;
4445 //*-*- . . . . . . . start main loop
4446 L50:
4447  if (fAmin < 0) goto L95;
4448  if (fISW[1] <= 2) goto L280;
4449  ep = fAmin*.1;
4450  if (sig2 < ep && fEDM < ep) goto L100;
4451  sig2 = fEDM;
4452  if (fNfcn - npfn > fNfcnmx) goto L300;
4453 //*-*- calculate new point * by reflection
4454  for (i = 1; i <= fNpar; ++i) {
4455  pb = 0;
4456  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
4457  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
4458  fPstar[i-1] = fPbar[i-1]*2 - fP[i + jh*fMaxpar - fMaxpar-1]*1;
4459  }
4460  mncalf(fPstar, ycalf);
4461  ystar = ycalf;
4462  if (ystar >= fAmin) goto L70;
4463 //*-*- point * better than jl, calculate new point **
4464  for (i = 1; i <= fNpar; ++i) {
4465  fPstst[i-1] = fPstar[i-1]*2 + fPbar[i- 1]*-1;
4466  }
4467  mncalf(fPstst, ycalf);
4468  ystst = ycalf;
4469  if (ystst < fIMPRy[jl-1]) goto L67;
4470  mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4471  goto L50;
4472 L67:
4473  mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4474  goto L50;
4475 //*-*- point * is not as good as jl
4476 L70:
4477  if (ystar >= fIMPRy[jh-1]) goto L73;
4478  jhold = jh;
4479  mnrazz(ystar, fPstar, fIMPRy, jh, jl);
4480  if (jhold != jh) goto L50;
4481 //*-*- calculate new point **
4482 L73:
4483  for (i = 1; i <= fNpar; ++i) {
4484  fPstst[i-1] = fP[i + jh*fMaxpar - fMaxpar-1]*.5 + fPbar[i-1]*.5;
4485  }
4486  mncalf(fPstst, ycalf);
4487  ystst = ycalf;
4488  if (ystst > fIMPRy[jh-1]) goto L30;
4489 //*-*- point ** is better than jh
4490  if (ystst < fAmin) goto L67;
4491  mnrazz(ystst, fPstst, fIMPRy, jh, jl);
4492  goto L50;
4493 //*-*- . . . . . . end main loop
4494 L95:
4495  if (fISW[4] >= 0) {
4496  Printf(" AN IMPROVEMENT ON THE PREVIOUS MINIMUM HAS BEEN FOUND");
4497  }
4498  reg = .1;
4499 //*-*- . . . . . ask if point is new
4500 L100:
4501  mninex(fX);
4502  Eval(nparx, fGin, fAmin, fU, 4); ++fNfcn;
4503  for (i = 1; i <= fNpar; ++i) {
4504  fDirin[i-1] = reg*fIMPRdsav[i-1];
4505  if (TMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L150;
4506  }
4507  goto L230;
4508 L150:
4509  fNfcnmx = fNfcnmx + npfn - fNfcn;
4510  npfn = fNfcn;
4511  mnsimp();
4512  if (fAmin >= fApsi) goto L325;
4513  for (i = 1; i <= fNpar; ++i) {
4514  fDirin[i-1] = fIMPRdsav[i-1]*.1;
4515  if (TMath::Abs(fX[i-1] - fXt[i-1]) > fDirin[i-1]) goto L250;
4516  }
4517 L230:
4518  if (fAmin < fApsi) goto L350;
4519  goto L325;
4520 /* . . . . . . truly new minimum */
4521 L250:
4522  fLnewmn = kTRUE;
4523  if (fISW[1] >= 1) {
4524  fISW[1] = 1;
4525  fDcovar = TMath::Max(fDcovar,.5);
4526  } else fDcovar = 1;
4527  fItaur = 0;
4528  fNfcnmx = fNfcnmx + npfn - fNfcn;
4529  fCstatu = "NEW MINIMU";
4530  if (fISW[4] >= 0) {
4531  Printf(" IMPROVE HAS FOUND A TRULY NEW MINIMUM");
4532  Printf(" *************************************");
4533  }
4534  return;
4535 //*-*- . . . return to previous region
4536 L280:
4537  if (fISW[4] > 0) {
4538  Printf(" COVARIANCE MATRIX WAS NOT POSITIVE-DEFINITE");
4539  }
4540  goto L325;
4541 L300:
4542  fISW[0] = 1;
4543 L325:
4544  for (i = 1; i <= fNpar; ++i) {
4545  fDirin[i-1] = fIMPRdsav[i-1]*.01;
4546  fX[i-1] = fXt[i-1];
4547  }
4548  fAmin = fApsi;
4549  fEDM = sigsav;
4550 L350:
4551  mninex(fX);
4552  if (fISW[4] > 0) {
4553  Printf(" IMPROVE HAS RETURNED TO REGION OF ORIGINAL MINIMUM");
4554  }
4555  fCstatu = "UNCHANGED ";
4556  mnrset(0);
4557  if (fISW[1] < 2) goto L380;
4558  if (loop < nloop && fISW[0] < 1) goto L20;
4559 L380:
4560  if (iswtr >= 0) mnprin(5, fAmin);
4561  fItaur = 0;
4562 } /* mnimpr_ */
4563 
4564 ////////////////////////////////////////////////////////////////////////////////
4565 ///*-*-*-*-*Transforms from internal coordinates (PINT) to external (U)*-*-*-*
4566 ///*-* ===========================================================
4567 ///*-* The minimizing routines which work in
4568 ///*-* internal coordinates call this routine before calling FCN.
4569 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4570 
4572 {
4573  Int_t i, j;
4574 
4575  for (j = 0; j < fNpar; ++j) {
4576  i = fNexofi[j]-1;
4577  if (fNvarl[i] == 1) {
4578  fU[i] = pint[j];
4579  } else {
4580  fU[i] = fAlim[i] + (TMath::Sin(pint[j]) + 1)*.5*(fBlim[i] - fAlim[i]);
4581  }
4582  }
4583 } /* mninex_ */
4584 
4585 ////////////////////////////////////////////////////////////////////////////////
4586 ///*-*-*-*-*-*Main initialization member function for MINUIT*-*-*-*-*-*-*-*-*
4587 ///*-* ==============================================
4588 ///*-* It initializes some constants
4589 ///*-* (including the logical I/O unit nos.),
4590 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4591 
4593 {
4594  /* Local variables */
4595  volatile Double_t epsp1;
4596  Double_t piby2, epstry, epsbak, distnn;
4597  Int_t i, idb;
4598 
4599 //*-*- I/O unit numbers
4600  fIsysrd = i1;
4601  fIsyswr = i2;
4602  fIstkwr[0] = fIsyswr;
4603  fNstkwr = 1;
4604  fIsyssa = i3;
4605  fNstkrd = 0;
4606 //*-*- version identifier
4607  fCvrsn = "95.03++ ";
4608 //*-*- some CONSTANT
4609  fMaxint = fMaxpar;
4610  fMaxext = 2*fMaxpar;
4611  fUndefi = -54321;
4612  fBigedm = 123456;
4613  fCundef = ")UNDEFINED";
4614  fCovmes[0] = "NO ERROR MATRIX ";
4615  fCovmes[1] = "ERR MATRIX APPROXIMATE";
4616  fCovmes[2] = "ERR MATRIX NOT POS-DEF";
4617  fCovmes[3] = "ERROR MATRIX ACCURATE ";
4618 //*-*- some starting values
4619  fNblock = 0;
4620  fIcomnd = 0;
4621  fCtitl = fCundef;
4622  fCfrom = "INPUT ";
4623  fNfcn = 0;
4624  fNfcnfr = fNfcn;
4625  fCstatu = "INITIALIZE";
4626  fISW[2] = 0;
4627  fISW[3] = 0;
4628  fISW[4] = 1;
4629 //*-*- fISW[5]=0 for batch jobs, =1 for interactive jobs
4630 //*-*- =-1 for originally interactive temporarily batch
4631 
4632  fISW[5] = 0;
4633 // if (intrac(&dummy)) fISW[5] = 1;
4634 //*-*- DEBUG options set to default values
4635  for (idb = 0; idb <= 10; ++idb) { fIdbg[idb] = 0; }
4636  fLrepor = kFALSE;
4637  fLwarn = kTRUE;
4638  fLimset = kFALSE;
4639  fLnewmn = kFALSE;
4640  fIstrat = 1;
4641  fItaur = 0;
4642 //*-*- default page dimensions and 'new page' carriage control integer
4643  fNpagwd = 120;
4644  fNpagln = 56;
4645  fNewpag = 1;
4646  if (fISW[5] > 0) {
4647  fNpagwd = 80;
4648  fNpagln = 30;
4649  fNewpag = 0;
4650  }
4651  fUp = 1;
4652  fUpdflt = fUp;
4653 //*-*- determine machine accuracy epsmac
4654  epstry = .5;
4655  for (i = 1; i <= 100; ++i) {
4656  epstry *= .5;
4657  epsp1 = epstry + 1;
4658  mntiny(epsp1, epsbak);
4659  if (epsbak < epstry) goto L35;
4660  }
4661  epstry = 1e-7;
4662  fEpsmac = epstry*4;
4663  Printf(" MNINIT UNABLE TO DETERMINE ARITHMETIC PRECISION. WILL ASSUME:%g",fEpsmac);
4664 L35:
4665  fEpsmac = epstry*8;
4667 //*-*- the vlims are a non-negligible distance from pi/2
4668 //*-*- used by MNPINT to set variables "near" the physical limits
4669  piby2 = TMath::ATan(1)*2;
4670  distnn = TMath::Sqrt(fEpsma2)*8;
4671  fVlimhi = piby2 - distnn;
4672  fVlimlo = -piby2 + distnn;
4673  mncler();
4674 // Printf(" MINUIT RELEASE %s INITIALIZED. DIMENSIONS 100/50 EPSMAC=%g",(const char*)fCvrsn,fEpsmac);
4675 } /* mninit_ */
4676 
4677 ////////////////////////////////////////////////////////////////////////////////
4678 ///*-*-*-*Interprets the SET LIM command, to reset the parameter limits*-*-*-*
4679 ///*-* =============================================================
4680 ///*-* Called from MNSET
4681 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4682 
4684 {
4685  /* Local variables */
4686  Double_t dxdi, snew;
4687  Int_t kint, i2, newcod, ifx=0, inu;
4688 
4689  fCfrom = "SET LIM ";
4690  fNfcnfr = fNfcn;
4691  fCstatu = "NO CHANGE ";
4692  i2 = Int_t(fWord7[0]);
4693  if (i2 > fMaxext || i2 < 0) goto L900;
4694  if (i2 > 0) goto L30;
4695 //*-*- set limits on all parameters
4696  newcod = 4;
4697  if (fWord7[1] == fWord7[2]) newcod = 1;
4698  for (inu = 1; inu <= fNu; ++inu) {
4699  if (fNvarl[inu-1] <= 0) continue;
4700  if (fNvarl[inu-1] == 1 && newcod == 1) continue;
4701  kint = fNiofex[inu-1];
4702 //*-*- see if parameter has been fixed
4703  if (kint <= 0) {
4704  if (fISW[4] >= 0) {
4705  Printf(" LIMITS NOT CHANGED FOR FIXED PARAMETER:%4d",inu);
4706  }
4707  continue;
4708  }
4709  if (newcod == 1) {
4710 //*-*- remove limits from parameter
4711  if (fISW[4] > 0) {
4712  Printf(" LIMITS REMOVED FROM PARAMETER :%3d",inu);
4713  }
4714  fCstatu = "NEW LIMITS";
4715  mndxdi(fX[kint-1], kint-1, dxdi);
4716  snew = fGstep[kint-1]*dxdi;
4717  fGstep[kint-1] = TMath::Abs(snew);
4718  fNvarl[inu-1] = 1;
4719  } else {
4720 //*-*- put limits on parameter
4721  fAlim[inu-1] = TMath::Min(fWord7[1],fWord7[2]);
4722  fBlim[inu-1] = TMath::Max(fWord7[1],fWord7[2]);
4723  if (fISW[4] > 0) {
4724  Printf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",inu,fAlim[inu-1],fBlim[inu-1]);
4725  }
4726  fNvarl[inu-1] = 4;
4727  fCstatu = "NEW LIMITS";
4728  fGstep[kint-1] = -.1;
4729  }
4730  }
4731  goto L900;
4732 //*-*- set limits on one parameter
4733 L30:
4734  if (fNvarl[i2-1] <= 0) {
4735  Printf(" PARAMETER %3d IS NOT VARIABLE.", i2);
4736  goto L900;
4737  }
4738  kint = fNiofex[i2-1];
4739 //*-*- see if parameter was fixed
4740  if (kint == 0) {
4741  Printf(" REQUEST TO CHANGE LIMITS ON FIXED PARAMETER:%3d",i2);
4742  for (ifx = 1; ifx <= fNpfix; ++ifx) {
4743  if (i2 == fIpfix[ifx-1]) goto L92;
4744  }
4745  Printf(" MINUIT BUG IN MNLIMS. SEE F. JAMES");
4746 L92:
4747  ;
4748  }
4749  if (fWord7[1] != fWord7[2]) goto L235;
4750 //*-*- remove limits
4751  if (fNvarl[i2-1] != 1) {
4752  if (fISW[4] > 0) {
4753  Printf(" LIMITS REMOVED FROM PARAMETER %2d",i2);
4754  }
4755  fCstatu = "NEW LIMITS";
4756  if (kint <= 0) {
4757  fGsteps[ifx-1] = TMath::Abs(fGsteps[ifx-1]);
4758  } else {
4759  mndxdi(fX[kint-1], kint-1, dxdi);
4760  if (TMath::Abs(dxdi) < .01) dxdi = .01;
4761  fGstep[kint-1] = TMath::Abs(fGstep[kint-1]*dxdi);
4762  fGrd[kint-1] *= dxdi;
4763  }
4764  fNvarl[i2-1] = 1;
4765  } else {
4766  Printf(" NO LIMITS SPECIFIED. PARAMETER %3d IS ALREADY UNLIMITED. NO CHANGE.",i2);
4767  }
4768  goto L900;
4769 //*-*- put on limits
4770 L235:
4771  fAlim[i2-1] = TMath::Min(fWord7[1],fWord7[2]);
4772  fBlim[i2-1] = TMath::Max(fWord7[1],fWord7[2]);
4773  fNvarl[i2-1] = 4;
4774  if (fISW[4] > 0) {
4775  Printf(" PARAMETER %3d LIMITS SET TO %15.5g%15.5g",i2,fAlim[i2-1],fBlim[i2-1]);
4776  }
4777  fCstatu = "NEW LIMITS";
4778  if (kint <= 0) fGsteps[ifx-1] = -.1;
4779  else fGstep[kint-1] = -.1;
4780 
4781 L900:
4782  if (fCstatu != "NO CHANGE ") {
4783  mnexin(fX);
4784  mnrset(1);
4785  }
4786 } /* mnlims_ */
4787 
4788 ////////////////////////////////////////////////////////////////////////////////
4789 ///*-*-*-*-*-*-*-*-*-*Perform a line search from position START*-*-*-*-*-*-*-*
4790 ///*-* =========================================
4791 ///*-* along direction STEP, where the length of vector STEP
4792 ///*-* gives the expected position of minimum.
4793 ///*-* FSTART is value of function at START
4794 ///*-* SLOPE (if non-zero) is df/dx along STEP at START
4795 ///*-* TOLER is initial tolerance of minimum in direction STEP
4796 ///*-*
4797 ///*-* SLAMBG and ALPHA control the maximum individual steps allowed.
4798 ///*-* The first step is always =1. The max length of second step is SLAMBG.
4799 ///*-* The max size of subsequent steps is the maximum previous successful
4800 ///*-* step multiplied by ALPHA + the size of most recent successful step,
4801 ///*-* but cannot be smaller than SLAMBG.
4802 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
4803 
4804 void TMinuit::mnline(Double_t *start, Double_t fstart, Double_t *step, Double_t slope, Double_t toler)
4805 {
4806  /* Local variables */
4807  Double_t xpq[12], ypq[12], slam, sdev, coeff[3], denom, flast;
4808  Double_t fvals[3], xvals[3], f1, fvmin, xvmin, ratio, f2, f3 = 0., fvmax;
4809  Double_t toler8, toler9, overal, undral, slamin, slamax, slopem;
4810  Int_t i, nparx=0, nvmax=0, nxypt, kk, ipt;
4811  Bool_t ldebug;
4812  TString cmess;
4813  char chpq[13];
4814  int l65, l70, l80;
4815 
4816  /* Function Body */
4817  l65 = 0; l70 = 0; l80 = 0;
4818  ldebug = fIdbg[1] >= 1;
4819 //*-*- starting values for overall limits on total step SLAM
4820  overal = 1e3;
4821  undral = -100;
4822 //*-*- debug check if start is ok
4823  if (ldebug) {
4824  mninex(&start[0]);
4825  Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4826  if (f1 != fstart) {
4827  Printf(" MNLINE start point not consistent, F values, parameters=");
4828  for (kk = 1; kk <= fNpar; ++kk) {
4829  Printf(" %14.5e",fX[kk-1]);
4830  }
4831  }
4832  }
4833 //*-*- . set up linear search along STEP
4834  fvmin = fstart;
4835  xvmin = 0;
4836  nxypt = 1;
4837  chpq[0] = charal[0];
4838  xpq[0] = 0;
4839  ypq[0] = fstart;
4840 //*-*- SLAMIN = smallest possible value of ABS(SLAM)
4841  slamin = 0;
4842  for (i = 1; i <= fNpar; ++i) {
4843  if (step[i-1] != 0) {
4844  ratio = TMath::Abs(start[i-1] / step[i-1]);
4845  if (slamin == 0) slamin = ratio;
4846  if (ratio < slamin) slamin = ratio;
4847  }
4848  fX[i-1] = start[i-1] + step[i-1];
4849  }
4850  if (slamin == 0) slamin = fEpsmac;
4851  slamin *= fEpsma2;
4852  nparx = fNpar;
4853 
4854  mninex(fX);
4855  Eval(nparx, fGin, f1, fU, 4); ++fNfcn;
4856  ++nxypt;
4857  chpq[nxypt-1] = charal[nxypt-1];
4858  xpq[nxypt-1] = 1;
4859  ypq[nxypt-1] = f1;
4860  if (f1 < fstart) {
4861  fvmin = f1;
4862  xvmin = 1;
4863  }
4864 //*-*- . quadr interp using slope GDEL and two points
4865  slam = 1;
4866  toler8 = toler;
4867  slamax = 5;
4868  flast = f1;
4869 //*-*- can iterate on two-points (cut) if no imprvmnt
4870 
4871  do {
4872  denom = (flast - fstart - slope*slam)*2 / (slam*slam);
4873  slam = 1;
4874  if (denom != 0) slam = -slope / denom;
4875  if (slam < 0) slam = slamax;
4876  if (slam > slamax) slam = slamax;
4877  if (slam < toler8) slam = toler8;
4878  if (slam < slamin) {
4879  l80 = 1;
4880  break;
4881  }
4882  if (TMath::Abs(slam - 1) < toler8 && f1 < fstart) {
4883  l70 = 1;
4884  break;
4885  }
4886  if (TMath::Abs(slam - 1) < toler8) slam = toler8 + 1;
4887  if (nxypt >= 12) {
4888  l65 = 1;
4889  break;
4890  }
4891  for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4892  mninex(fX);
4893  nparx = fNpar;
4894  Eval(nparx, fGin, f2, fU, 4); ++fNfcn;
4895  ++nxypt;
4896  chpq[nxypt-1] = charal[nxypt-1];
4897  xpq[nxypt-1] = slam;
4898  ypq[nxypt-1] = f2;
4899  if (f2 < fvmin) {
4900  fvmin = f2;
4901  xvmin = slam;
4902  }
4903  if (fstart == fvmin) {
4904  flast = f2;
4905  toler8 = toler*slam;
4906  overal = slam - toler8;
4907  slamax = overal;
4908  }
4909  } while (fstart == fvmin);
4910 
4911  if (!l65 && !l70 && !l80) {
4912 //*-*- . quadr interp using 3 points
4913  xvals[0] = xpq[0];
4914  fvals[0] = ypq[0];
4915  xvals[1] = xpq[nxypt-2];
4916  fvals[1] = ypq[nxypt-2];
4917  xvals[2] = xpq[nxypt-1];
4918  fvals[2] = ypq[nxypt-1];
4919 //*-*- begin iteration, calculate desired step
4920  do {
4921  slamax = TMath::Max(slamax,TMath::Abs(xvmin)*2);
4922  mnpfit(xvals, fvals, 3, coeff, sdev);
4923  if (coeff[2] <= 0) {
4924  slopem = coeff[2]*2*xvmin + coeff[1];
4925  if (slopem <= 0) slam = xvmin + slamax;
4926  else slam = xvmin - slamax;
4927  } else {
4928  slam = -coeff[1] / (coeff[2]*2);
4929  if (slam > xvmin + slamax) slam = xvmin + slamax;
4930  if (slam < xvmin - slamax) slam = xvmin - slamax;
4931  }
4932  if (slam > 0) {
4933  if (slam > overal)
4934  slam = overal;
4935  else if (slam < undral)
4936  slam = undral;
4937  }
4938 
4939 //*-*- come here if step was cut below
4940  do {
4941  toler9 = TMath::Max(toler8,TMath::Abs(toler8*slam));
4942  for (ipt = 1; ipt <= 3; ++ipt) {
4943  if (TMath::Abs(slam - xvals[ipt-1]) < toler9) {
4944  l70 = 1;
4945  break;
4946  }
4947  }
4948  if (l70) break;
4949 //*-*- take the step
4950  if (nxypt >= 12) {
4951  l65 = 1;
4952  break;
4953  }
4954  for (i = 1; i <= fNpar; ++i) { fX[i-1] = start[i-1] + slam*step[i-1]; }
4955  mninex(fX);
4956  Eval(nparx, fGin, f3, fU, 4); ++fNfcn;
4957  ++nxypt;
4958  chpq[nxypt-1] = charal[nxypt-1];
4959  xpq[nxypt-1] = slam;
4960  ypq[nxypt-1] = f3;
4961 //*-*- find worst previous point out of three
4962  fvmax = fvals[0];
4963  nvmax = 1;
4964  if (fvals[1] > fvmax) {
4965  fvmax = fvals[1];
4966  nvmax = 2;
4967  }
4968  if (fvals[2] > fvmax) {
4969  fvmax = fvals[2];
4970  nvmax = 3;
4971  }
4972 //*-*- if latest point worse than all three previous, cut step
4973  if (f3 >= fvmax) {
4974  if (nxypt >= 12) {
4975  l65 = 1;
4976  break;
4977  }
4978  if (slam > xvmin) overal = TMath::Min(overal,slam - toler8);
4979  if (slam < xvmin) undral = TMath::Max(undral,slam + toler8);
4980  slam = (slam + xvmin)*.5;
4981  }
4982  } while (f3 >= fvmax);
4983 
4984 //*-*- prepare another iteration, replace worst previous point
4985  if (l65 || l70) break;
4986 
4987  xvals[nvmax-1] = slam;
4988  fvals[nvmax-1] = f3;
4989  if (f3 < fvmin) {
4990  fvmin = f3;
4991  xvmin = slam;
4992  } else {
4993  if (slam > xvmin) overal = TMath::Min(overal,slam - toler8);
4994  if (slam < xvmin) undral = TMath::Max(undral,slam + toler8);
4995  }
4996  } while (nxypt < 12);
4997  }
4998 
4999 //*-*- . . end of iteration . . .
5000 //*-*- stop because too many iterations
5001  if (!l70 && !l80) {
5002  cmess = " LINE SEARCH HAS EXHAUSTED THE LIMIT OF FUNCTION CALLS ";
5003  if (ldebug) {
5004  Printf(" MNLINE DEBUG: steps=");
5005  for (kk = 1; kk <= fNpar; ++kk) {
5006  Printf(" %12.4g",step[kk-1]);
5007  }
5008  }
5009  }
5010 //*-*- stop because within tolerance
5011  if (l70) cmess = " LINE SEARCH HAS ATTAINED TOLERANCE ";
5012  if (l80) cmess = " STEP SIZE AT ARITHMETICALLY ALLOWED MINIMUM";
5013 
5014  fAmin = fvmin;
5015  for (i = 1; i <= fNpar; ++i) {
5016  fDirin[i-1] = step[i-1]*xvmin;
5017  fX[i-1] = start[i-1] + fDirin[i-1];
5018  }
5019  mninex(fX);
5020  if (xvmin < 0) {
5021  mnwarn("D", "MNLINE", " LINE MINIMUM IN BACKWARDS DIRECTION");
5022  }
5023  if (fvmin == fstart) {
5024  mnwarn("D", "MNLINE", " LINE SEARCH FINDS NO IMPROVEMENT ");
5025  }
5026  if (ldebug) {
5027  Printf(" AFTER %3d POINTS,%s",nxypt,(const char*)cmess);
5028  mnplot(xpq, ypq, chpq, nxypt, fNpagwd, fNpagln);
5029  }
5030 } /* mnline_ */
5031 
5032 ////////////////////////////////////////////////////////////////////////////////
5033 ///*-*-*-*-*-*-*-*Prints the covariance matrix v when KODE=1*-*-*-*-*-*-*-*-*
5034 ///*-* ==========================================
5035 ///*-* always prints the global correlations, and
5036 ///*-* calculates and prints the individual correlation coefficients
5037 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5038 
5040 {
5041  /* Local variables */
5042  Int_t ndex, i, j, m, n, ncoef, nparm, id, it, ix;
5043  Int_t nsofar, ndi, ndj, iso, isw2, isw5;
5044  TString ctemp;
5045 
5046  isw2 = fISW[1];
5047  if (isw2 < 1) {
5048  Printf("%s",(const char*)fCovmes[isw2]);
5049  return;
5050  }
5051  if (fNpar == 0) {
5052  Printf(" MNMATU: NPAR=0");
5053  return;
5054  }
5055 //*-*- . . . . .external error matrix
5056  if (kode == 1) {
5057  isw5 = fISW[4];
5058  fISW[4] = 2;
5059  mnemat(fP, fMaxint);
5060  if (isw2 < 3) {
5061  Printf("%s",(const char*)fCovmes[isw2]);
5062  }
5063  fISW[4] = isw5;
5064  }
5065 //*-*- . . . . . correlation coeffs. .
5066  if (fNpar <= 1) return;
5067  mnwerr();
5068 //*-*- NCOEF is number of coeff. that fit on one line, not to exceed 20
5069  ncoef = (fNpagwd - 19) / 6;
5070  ncoef = TMath::Min(ncoef,20);
5071  nparm = TMath::Min(fNpar,ncoef);
5072  Printf(" PARAMETER CORRELATION COEFFICIENTS ");
5073  ctemp = " NO. GLOBAL";
5074  for (id = 1; id <= nparm; ++id) {
5075  ctemp += TString::Format(" %6d",fNexofi[id-1]);
5076  }
5077  Printf("%s",(const char*)ctemp);
5078  for (i = 1; i <= fNpar; ++i) {
5079  ix = fNexofi[i-1];
5080  ndi = i*(i + 1) / 2;
5081  for (j = 1; j <= fNpar; ++j) {
5082  m = TMath::Max(i,j);
5083  n = TMath::Min(i,j);
5084  ndex = m*(m-1) / 2 + n;
5085  ndj = j*(j + 1) / 2;
5086  fMATUvline[j-1] = fVhmat[ndex-1] / TMath::Sqrt(TMath::Abs(fVhmat[ndi-1]*fVhmat[ndj-1]));
5087  }
5088  nparm = TMath::Min(fNpar,ncoef);
5089  ctemp.Form(" %3d %7.5f ",ix,fGlobcc[i-1]);
5090  for (it = 1; it <= nparm; ++it) {
5091  ctemp += TString::Format(" %6.3f",fMATUvline[it-1]);
5092  }
5093  Printf("%s",(const char*)ctemp);
5094  if (i <= nparm) continue;
5095  ctemp = " ";
5096  for (iso = 1; iso <= 10; ++iso) {
5097  nsofar = nparm;
5098  nparm = TMath::Min(fNpar,nsofar + ncoef);
5099  for (it = nsofar + 1; it <= nparm; ++it) {
5100  ctemp = ctemp + TString::Format(" %6.3f",fMATUvline[it-1]);
5101  }
5102  Printf("%s",(const char*)ctemp);
5103  if (i <= nparm) break;
5104  }
5105  }
5106  if (isw2 < 3) {
5107  Printf(" %s",(const char*)fCovmes[isw2]);
5108  }
5109 } /* mnmatu_ */
5110 
5111 ////////////////////////////////////////////////////////////////////////////////
5112 ///*-*-*-*-*-*-*-*-*Performs a local function minimization*-*-*-*-*-*-*-*-*-*
5113 ///*-* ======================================
5114 ///*-* Performs a local function minimization using basically the
5115 ///*-* method of Davidon-Fletcher-Powell as modified by Fletcher
5116 ///*-* ref. -- Fletcher, Comp.J. 13,317 (1970) "switching method"
5117 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5118 
5120 {
5121  /* Local variables */
5122  Double_t gdel, gami, vlen, dsum, gssq, vsum, d;
5123  Double_t fzero, fs, ri, delgam, rhotol;
5124  Double_t gdgssq, gvg, vgi;
5125  Int_t npfn, ndex, iext, i, j, m, n, npsdf, nparx;
5126  Int_t iswtr, lined2, kk, nfcnmg, nrstrt,iter;
5127  Bool_t ldebug;
5128  Double_t toler = 0.05;
5129 
5130  if (fNpar <= 0) return;
5131  if (fAmin == fUndefi) mnamin();
5132  ldebug = kFALSE; if ( fIdbg[4] >= 1) ldebug = kTRUE;
5133  fCfrom = "MIGRAD ";
5134  fNfcnfr = fNfcn;
5135  nfcnmg = fNfcn;
5136  fCstatu = "INITIATE ";
5137  iswtr = fISW[4] - 2*fItaur;
5138  npfn = fNfcn;
5139  nparx = fNpar;
5140  vlen = (Double_t) (fNpar*(fNpar + 1) / 2);
5141  nrstrt = 0;
5142  npsdf = 0;
5143  lined2 = 0;
5144  fISW[3] = -1;
5145  rhotol = fApsi*.001;
5146  if (iswtr >= 1) {
5147  Printf(" START MIGRAD MINIMIZATION. STRATEGY %2d. CONVERGENCE WHEN EDM .LT.%9.2e",fIstrat,rhotol);
5148  }
5149 //*-*- initialization strategy
5150  if (fIstrat < 2 || fISW[1] >= 3) goto L2;
5151 //*-*- come (back) here to restart completely
5152 L1:
5153  if (nrstrt > fIstrat) {
5154  fCstatu = "FAILED ";
5155  fISW[3] = -1;
5156  goto L230;
5157  }
5158 //*-*- . get full covariance and gradient
5159  mnhess();
5160  mnwerr();
5161  npsdf = 0;
5162  if (fISW[1] >= 1) goto L10;
5163 //*-*- . get gradient at start point
5164 L2:
5165  mninex(fX);
5166  if (fISW[2] == 1) {
5167  Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
5168  }
5169  mnderi();
5170  if (fISW[1] >= 1) goto L10;
5171 //*-*- sometimes start with diagonal matrix
5172  for (i = 1; i <= fNpar; ++i) {
5173  fMIGRxxs[i-1] = fX[i-1];
5174  fMIGRstep[i-1] = 0;
5175  }
5176 //*-*- do line search if second derivative negative
5177  ++lined2;
5178  if (lined2 < (fIstrat + 1)*fNpar) {
5179  for (i = 1; i <= fNpar; ++i) {
5180  if (fG2[i-1] > 0) continue;
5181  if (fGrd[i-1] > 0) fMIGRstep[i-1] = -TMath::Abs(fGstep[i-1]);
5182  else fMIGRstep[i-1] = TMath::Abs(fGstep[i-1]);
5183  gdel = fMIGRstep[i-1]*fGrd[i-1];
5184  fs = fAmin;
5185  mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
5186  mnwarn("D", "MNMIGR", "Negative G2 line search");
5187  iext = fNexofi[i-1];
5188  if (ldebug) {
5189  Printf(" Negative G2 line search, param %3d %13.3g%13.3g",iext,fs,fAmin);
5190  }
5191  goto L2;
5192  }
5193  }
5194 //*-*- make diagonal error matrix
5195  for (i = 1; i <= fNpar; ++i) {
5196  ndex = i*(i-1) / 2;
5197  for (j = 1; j <= i-1; ++j) {
5198  ++ndex;
5199  fVhmat[ndex-1] = 0;
5200  }
5201  ++ndex;
5202  if (fG2[i-1] <= 0) fG2[i-1] = 1;
5203  fVhmat[ndex-1] = 2 / fG2[i-1];
5204  }
5205  fDcovar = 1;
5206  if (ldebug) {
5207  Printf(" DEBUG MNMIGR, STARTING MATRIX DIAGONAL, VHMAT=");
5208  for (kk = 1; kk <= Int_t(vlen); ++kk) {
5209  Printf(" %10.2g",fVhmat[kk-1]);
5210  }
5211  }
5212 //*-*- ready to start first iteration
5213 L10:
5214  ++nrstrt;
5215  if (nrstrt > fIstrat + 1) {
5216  fCstatu = "FAILED ";
5217  goto L230;
5218  }
5219  fs = fAmin;
5220 //*-*- . . . get EDM and set up loop
5221  fEDM = 0;
5222  for (i = 1; i <= fNpar; ++i) {
5223  fMIGRgs[i-1] = fGrd[i-1];
5224  fMIGRxxs[i-1] = fX[i-1];
5225  ndex = i*(i-1) / 2;
5226  for (j = 1; j <= i-1; ++j) {
5227  ++ndex;
5228  fEDM += fMIGRgs[i-1]*fVhmat[ndex-1]*fMIGRgs[j-1];
5229  }
5230  ++ndex;
5231  fEDM += fMIGRgs[i-1]*fMIGRgs[i-1]*.5*fVhmat[ndex-1];
5232  }
5233  fEDM = fEDM*.5*(fDcovar*3 + 1);
5234  if (fEDM < 0) {
5235  mnwarn("W", "MIGRAD", "STARTING MATRIX NOT POS-DEFINITE.");
5236  fISW[1] = 0;
5237  fDcovar = 1;
5238  goto L2;
5239  }
5240  if (fISW[1] == 0) fEDM = fBigedm;
5241  iter = 0;
5242  mninex(fX);
5243  mnwerr();
5244  if (iswtr >= 1) mnprin(3, fAmin);
5245  if (iswtr >= 2) mnmatu(0);
5246 //*-*- . . . . . start main loop
5247 L24:
5248  if (fNfcn - npfn >= fNfcnmx) goto L190;
5249  gdel = 0;
5250  gssq = 0;
5251  for (i = 1; i <= fNpar; ++i) {
5252  ri = 0;
5253  gssq += fMIGRgs[i-1]*fMIGRgs[i-1];
5254  for (j = 1; j <= fNpar; ++j) {
5255  m = TMath::Max(i,j);
5256  n = TMath::Min(i,j);
5257  ndex = m*(m-1) / 2 + n;
5258  ri += fVhmat[ndex-1]*fMIGRgs[j-1];
5259  }
5260  fMIGRstep[i-1] = ri*-.5;
5261  gdel += fMIGRstep[i-1]*fMIGRgs[i-1];
5262  }
5263  if (gssq == 0) {
5264  mnwarn("D", "MIGRAD", " FIRST DERIVATIVES OF FCN ARE ALL ZERO");
5265  goto L300;
5266  }
5267 //*-*- if gdel positive, V not posdef
5268  if (gdel >= 0) {
5269  mnwarn("D", "MIGRAD", " NEWTON STEP NOT DESCENT.");
5270  if (npsdf == 1) goto L1;
5271  mnpsdf();
5272  npsdf = 1;
5273  goto L24;
5274  }
5275 //*-*- . . . . do line search
5276  mnline(fMIGRxxs, fs, fMIGRstep, gdel, toler);
5277  if (fAmin == fs) goto L200;
5278  fCfrom = "MIGRAD ";
5279  fNfcnfr = nfcnmg;
5280  fCstatu = "PROGRESS ";
5281 //*-*- . get gradient at new point
5282  mninex(fX);
5283  if (fISW[2] == 1) {
5284  Eval(nparx, fGin, fzero, fU, 2); ++fNfcn;
5285  }
5286  mnderi();
5287 //*-*- . calculate new EDM
5288  npsdf = 0;
5289 L81:
5290  fEDM = 0;
5291  gvg = 0;
5292  delgam = 0;
5293  gdgssq = 0;
5294  for (i = 1; i <= fNpar; ++i) {
5295  ri = 0;
5296  vgi = 0;
5297  for (j = 1; j <= fNpar; ++j) {
5298  m = TMath::Max(i,j);
5299  n = TMath::Min(i,j);
5300  ndex = m*(m-1) / 2 + n;
5301  vgi += fVhmat[ndex-1]*(fGrd[j-1] - fMIGRgs[j-1]);
5302  ri += fVhmat[ndex-1]*fGrd[j-1];
5303  }
5304  fMIGRvg[i-1] = vgi*.5;
5305  gami = fGrd[i-1] - fMIGRgs[i-1];
5306  gdgssq += gami*gami;
5307  gvg += gami*fMIGRvg[i-1];
5308  delgam += fDirin[i-1]*gami;
5309  fEDM += fGrd[i-1]*ri*.5;
5310  }
5311  fEDM = fEDM*.5*(fDcovar*3 + 1);
5312 //*-*- . if EDM negative, not positive-definite
5313  if (fEDM < 0 || gvg <= 0) {
5314  mnwarn("D", "MIGRAD", "NOT POS-DEF. EDM OR GVG NEGATIVE.");
5315  fCstatu = "NOT POSDEF";
5316  if (npsdf == 1) goto L230;
5317  mnpsdf();
5318  npsdf = 1;
5319  goto L81;
5320  }
5321 //*-*- print information about this iteration
5322  ++iter;
5323  if (iswtr >= 3 || (iswtr == 2 && iter % 10 == 1)) {
5324  mnwerr();
5325  mnprin(3, fAmin);
5326  }
5327  if (gdgssq == 0) {
5328  mnwarn("D", "MIGRAD", "NO CHANGE IN FIRST DERIVATIVES OVER LAST STEP");
5329  }
5330  if (delgam < 0) {
5331  mnwarn("D", "MIGRAD", "FIRST DERIVATIVES INCREASING ALONG SEARCH LINE");
5332  }
5333 //*-*- . update covariance matrix
5334  fCstatu = "IMPROVEMNT";
5335  if (ldebug) {
5336  Printf(" VHMAT 1 =");
5337  for (kk = 1; kk <= 10; ++kk) {
5338  Printf(" %10.2g",fVhmat[kk-1]);
5339  }
5340  }
5341  dsum = 0;
5342  vsum = 0;
5343  for (i = 1; i <= fNpar; ++i) {
5344  for (j = 1; j <= i; ++j) {
5345  if(delgam == 0 || gvg == 0) d = 0;
5346  else d = fDirin[i-1]*fDirin[j-1] / delgam - fMIGRvg[i-1]*fMIGRvg[j-1] / gvg;
5347  dsum += TMath::Abs(d);
5348  ndex = i*(i-1) / 2 + j;
5349  fVhmat[ndex-1] += d*2;
5350  vsum += TMath::Abs(fVhmat[ndex-1]);
5351  }
5352  }
5353 //*-*- smooth local fluctuations by averaging DCOVAR
5354  fDcovar = (fDcovar + dsum / vsum)*.5;
5355  if (iswtr >= 3 || ldebug) {
5356  Printf(" RELATIVE CHANGE IN COV. MATRIX=%5.1f per cent",fDcovar*100);
5357  }
5358  if (ldebug) {
5359  Printf(" VHMAT 2 =");
5360  for (kk = 1; kk <= 10; ++kk) {
5361  Printf(" %10.3g",fVhmat[kk-1]);
5362  }
5363  }
5364  if (delgam <= gvg) goto L135;
5365  for (i = 1; i <= fNpar; ++i) {
5366  fMIGRflnu[i-1] = fDirin[i-1] / delgam - fMIGRvg[i-1] / gvg;
5367  }
5368  for (i = 1; i <= fNpar; ++i) {
5369  for (j = 1; j <= i; ++j) {
5370  ndex = i*(i-1) / 2 + j;
5371  fVhmat[ndex-1] += gvg*2*fMIGRflnu[i-1]*fMIGRflnu[j-1];
5372  }
5373  }
5374 L135:
5375 //*-*- and see if converged
5376  if (fEDM < rhotol*.1) goto L300;
5377 //*-*- if not, prepare next iteration
5378  for (i = 1; i <= fNpar; ++i) {
5379  fMIGRxxs[i-1] = fX[i-1];
5380  fMIGRgs[i-1] = fGrd[i-1];
5381  }
5382  fs = fAmin;
5383  if (fISW[1] == 0 && fDcovar < .5) fISW[1] = 1;
5384  if (fISW[1] == 3 && fDcovar > .1) fISW[1] = 1;
5385  if (fISW[1] == 1 && fDcovar < .05) fISW[1] = 3;
5386  goto L24;
5387 //*-*- . . . . . end main loop
5388 //*-*- . . call limit in MNMIGR
5389 L190:
5390  fISW[0] = 1;
5391  if (fISW[4] >= 0) {
5392  Printf(" CALL LIMIT EXCEEDED IN MIGRAD.");
5393  }
5394  fCstatu = "CALL LIMIT";
5395  goto L230;
5396 //*-*- . . fails to improve . .
5397 L200:
5398  if (iswtr >= 1) {
5399  Printf(" MIGRAD FAILS TO FIND IMPROVEMENT");
5400  }
5401  for (i = 1; i <= fNpar; ++i) { fX[i-1] = fMIGRxxs[i-1]; }
5402  if (fEDM < rhotol) goto L300;
5403  if (fEDM < TMath::Abs(fEpsma2*fAmin)) {
5404  if (iswtr >= 0) {
5405  Printf(" MACHINE ACCURACY LIMITS FURTHER IMPROVEMENT.");
5406  }
5407  goto L300;
5408  }
5409  if (fIstrat < 1) {
5410  if (fISW[4] >= 0) {
5411  Printf(" MIGRAD FAILS WITH STRATEGY=0. WILL TRY WITH STRATEGY=1.");
5412  }
5413  fIstrat = 1;
5414  }
5415  goto L1;
5416 //*-*- . . fails to converge
5417 L230:
5418  if (iswtr >= 0) {
5419  Printf(" MIGRAD TERMINATED WITHOUT CONVERGENCE.");
5420  }
5421  if (fISW[1] == 3) fISW[1] = 1;
5422  fISW[3] = -1;
5423  goto L400;
5424 //*-*- . . apparent convergence
5425 L300:
5426  if (iswtr >= 0) {
5427  Printf(" MIGRAD MINIMIZATION HAS CONVERGED.");
5428  }
5429  if (fItaur == 0) {
5430  if (fIstrat >= 2 || (fIstrat == 1 && fISW[1] < 3)) {
5431  if (fISW[4] >= 0) {
5432  Printf(" MIGRAD WILL VERIFY CONVERGENCE AND ERROR MATRIX.");
5433  }
5434  mnhess();
5435  mnwerr();
5436  npsdf = 0;
5437  if (fEDM > rhotol) goto L10;
5438  }
5439  }
5440  fCstatu = "CONVERGED ";
5441  fISW[3] = 1;
5442 //*-*- come here in any case
5443 L400:
5444  fCfrom = "MIGRAD ";
5445  fNfcnfr = nfcnmg;
5446  mninex(fX);
5447  mnwerr();
5448  if (iswtr >= 0) mnprin(3, fAmin);
5449  if (iswtr >= 1) mnmatu(1);
5450 } /* mnmigr_ */
5451 
5452 ////////////////////////////////////////////////////////////////////////////////
5453 ///*-*-*-*-*-*-*-*-*-*-*Performs a MINOS error analysis*-*-*-*-*-*-*-*-*-*-*-*
5454 ///*-* ===============================
5455 ///*-* Performs a MINOS error analysis on those parameters for
5456 ///*-* which it is requested on the MINOS command by calling
5457 ///*-* MNMNOT for each parameter requested.
5458 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5459 
5461 {
5462  /* Local variables */
5463  Double_t val2mi, val2pl;
5464  Int_t nbad, ilax, ilax2, ngood, nfcnmi, iin, knt;
5465 
5466  if (fNpar <= 0) goto L700;
5467  ngood = 0;
5468  nbad = 0;
5469  nfcnmi = fNfcn;
5470 //*-*- . loop over parameters requested
5471  for (knt = 1; knt <= fNpar; ++knt) {
5472  if (Int_t(fWord7[1]) == 0) {
5473  ilax = fNexofi[knt-1];
5474  } else {
5475  if (knt >= 7) break;
5476  ilax = Int_t(fWord7[knt]);
5477  if (ilax == 0) break;
5478  if (ilax > 0 && ilax <= fNu) {
5479  if (fNiofex[ilax-1] > 0) goto L565;
5480  }
5481  Printf(" PARAMETER NUMBER %3d NOT A VARIABLE. IGNORED.",ilax);
5482  continue;
5483  }
5484 L565:
5485 //*-*- calculate one pair of M E s
5486  ilax2 = 0;
5487  mnmnot(ilax, ilax2, val2pl, val2mi);
5488  if (fLnewmn) goto L650;
5489 //*-*- update NGOOD and NBAD
5490  iin = fNiofex[ilax-1];
5491  if (fErp[iin-1] > 0) ++ngood;
5492  else ++nbad;
5493  if (fErn[iin-1] < 0) ++ngood;
5494  else ++nbad;
5495  }
5496 //*-*- end of loop . . . . . . .
5497 //*-*- . . . . printout final values .
5498  fCfrom = "MINOS ";
5499  fNfcnfr = nfcnmi;
5500  fCstatu = "UNCHANGED ";
5501  if (ngood == 0 && nbad == 0) goto L700;
5502  if (ngood > 0 && nbad == 0) fCstatu = "SUCCESSFUL";
5503  if (ngood == 0 && nbad > 0) fCstatu = "FAILURE ";
5504  if (ngood > 0 && nbad > 0) fCstatu = "PROBLEMS ";
5505  if (fISW[4] >= 0) mnprin(4, fAmin);
5506  if (fISW[4] >= 2) mnmatu(0);
5507  return;
5508 //*-*- . . . new minimum found . . . .
5509 L650:
5510  fCfrom = "MINOS ";
5511  fNfcnfr = nfcnmi;
5512  fCstatu = "NEW MINIMU";
5513  if (fISW[4] >= 0) mnprin(4, fAmin);
5514  Printf(" NEW MINIMUM FOUND. GO BACK TO MINIMIZATION STEP.");
5515  Printf(" =================================================");
5516  Printf(" V");
5517  Printf(" V");
5518  Printf(" V");
5519  Printf(" VVVVVVV");
5520  Printf(" VVVVV");
5521  Printf(" VVV");
5522  Printf(" V\n");
5523  return;
5524 L700:
5525  Printf(" THERE ARE NO MINOS ERRORS TO CALCULATE.");
5526 } /* mnmnos_ */
5527 
5528 ////////////////////////////////////////////////////////////////////////////////
5529 ///*-*-*-*-*-*Performs a MINOS error analysis on one parameter*-*-*-*-*-*-*-*-*
5530 ///*-* ================================================
5531 ///*-* The parameter ILAX is varied, and the minimum of the
5532 ///*-* function with respect to the other parameters is followed
5533 ///*-* until it crosses the value FMIN+UP.
5534 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5535 
5536 void TMinuit::mnmnot(Int_t ilax, Int_t ilax2, Double_t &val2pl, Double_t &val2mi)
5537 {
5538  /* System generated locals */
5539  Int_t i__1;
5540 
5541  /* Local variables */
5542  Double_t delu, aopt, eros;
5543  Double_t abest, xunit, dc, ut, sigsav, du1;
5544  Double_t fac, sig, sav;
5545  Int_t marc, isig, mpar, ndex, imax, indx, ierr, i, j;
5546  Int_t iercr, it, istrav, nfmxin, nlimit, isw2, isw4;
5547  TString csig;
5548 
5549 //*-*- . . save and prepare start vals
5550  isw2 = fISW[1];
5551  isw4 = fISW[3];
5552  sigsav = fEDM;
5553  istrav = fIstrat;
5554  dc = fDcovar;
5555  fLnewmn = kFALSE;
5556  fApsi = fEpsi*.5;
5557  abest = fAmin;
5558  mpar = fNpar;
5559  nfmxin = fNfcnmx;
5560  for (i = 1; i <= mpar; ++i) { fXt[i-1] = fX[i-1]; }
5561  i__1 = mpar*(mpar + 1) / 2;
5562  for (j = 1; j <= i__1; ++j) { fVthmat[j-1] = fVhmat[j-1]; }
5563  for (i = 1; i <= mpar; ++i) {
5564  fMNOTgcc[i-1] = fGlobcc[i-1];
5565  fMNOTw[i-1] = fWerr[i-1];
5566  }
5567  it = fNiofex[ilax-1];
5568  fErp[it-1] = 0;
5569  fErn[it-1] = 0;
5570  mninex(fXt);
5571  ut = fU[ilax-1];
5572  if (fNvarl[ilax-1] == 1) {
5573  fAlim[ilax-1] = ut - fMNOTw[it-1]*100;
5574  fBlim[ilax-1] = ut + fMNOTw[it-1]*100;
5575  }
5576  ndex = it*(it + 1) / 2;
5577  xunit = TMath::Sqrt(fUp / fVthmat[ndex-1]);
5578  marc = 0;
5579  for (i = 1; i <= mpar; ++i) {
5580  if (i == it) continue;
5581  ++marc;
5582  imax = TMath::Max(it,i);
5583  indx = imax*(imax-1) / 2 + TMath::Min(it,i);
5584  fMNOTxdev[marc-1] = xunit*fVthmat[indx-1];
5585  }
5586 //*-*- fix the parameter in question
5587  mnfixp(it-1, ierr);
5588  if (ierr > 0) {
5589  Printf(" MINUIT ERROR. CANNOT FIX PARAMETER %4d INTERNAL %3d",ilax,it);
5590  goto L700;
5591  }
5592 //*-*- . . . . . Nota Bene: from here on, NPAR=MPAR-1
5593 //*-*- Remember: MNFIXP squeezes IT out of X, XT, WERR, and VHMAT,
5594 //*-*- not W, VTHMAT
5595  for (isig = 1; isig <= 2; ++isig) {
5596  if (isig == 1) {
5597  sig = 1;
5598  csig = "POSI";
5599  } else {
5600  sig = -1;
5601  csig = "NEGA";
5602  }
5603 //*-*- . sig=sign of error being calcd
5604  if (fISW[4] > 1) {
5605  Printf(" DETERMINATION OF %sTIVE MINOS ERROR FOR PARAMETER %d %s"
5606  ,(const char*)csig,ilax
5607  ,(const char*)fCpnam[ilax-1]);
5608  }
5609  if (fISW[1] <= 0) {
5610  mnwarn("D", "MINOS", "NO COVARIANCE MATRIX.");
5611  }
5612  nlimit = fNfcn + nfmxin;
5613  fIstrat = TMath::Max(istrav-1,0);
5614  du1 = fMNOTw[it-1];
5615  fU[ilax-1] = ut + sig*du1;
5616  fU[ilax-1] = TMath::Min(fU[ilax-1],fBlim[ilax-1]);
5617  fU[ilax-1] = TMath::Max(fU[ilax-1],fAlim[ilax-1]);
5618  delu = fU[ilax-1] - ut;
5619 //*-*- stop if already at limit with negligible step size
5620  if (TMath::Abs(delu) / (TMath::Abs(ut) + TMath::Abs(fU[ilax-1])) < fEpsmac) goto L440;
5621  fac = delu / fMNOTw[it-1];
5622  for (i = 1; i <= fNpar; ++i) {
5623  fX[i-1] = fXt[i-1] + fac*fMNOTxdev[i-1];
5624  }
5625  if (fISW[4] > 1) {
5626  Printf(" PARAMETER %4d SET TO%11.3e + %10.3e = %12.3e",ilax,ut,delu,fU[ilax-1]);
5627  }
5628 //*-*- loop to hit AMIN+UP
5629  fKe1cr = ilax;
5630  fKe2cr = 0;
5631  fXmidcr = fU[ilax-1];
5632  fXdircr = delu;
5633 
5634  fAmin = abest;
5635  fNfcnmx = nlimit - fNfcn;
5636  mncros(aopt, iercr);
5637  if (abest - fAmin > fUp*.01) goto L650;
5638  if (iercr == 1) goto L440;
5639  if (iercr == 2) goto L450;
5640  if (iercr == 3) goto L460;
5641 //*-*- . error successfully calculated
5642  eros = fXmidcr - ut + aopt*fXdircr;
5643  if (fISW[4] > 1) {
5644  Printf(" THE %4sTIVE MINOS ERROR OF PARAMETER %3d %10s, IS %12.4e"
5645  ,(const char*)csig,ilax
5646  ,(const char*)fCpnam[ilax-1],eros);
5647  }
5648  goto L480;
5649 //*-*- . . . . . . . . failure returns
5650 L440:
5651  if (fISW[4] >= 1) {
5652  Printf(" THE %4sTIVE MINOS ERROR OF PARAMETER %3d, %s EXCEEDS ITS LIMIT."
5653  ,(const char*)csig,ilax
5654  ,(const char*)fCpnam[ilax-1]);
5655  }
5656  eros = fUndefi;
5657  goto L480;
5658 L450:
5659  if (fISW[4] >= 1) {
5660  Printf(" THE %4sTIVE MINOS ERROR %4d REQUIRES MORE THAN %5d FUNCTION CALLS."
5661  ,(const char*)csig,ilax,nfmxin);
5662  }
5663  eros = 0;
5664  goto L480;
5665 L460:
5666  if (fISW[4] >= 1) {
5667  Printf(" %4sTIVE MINOS ERROR NOT CALCULATED FOR PARAMETER %d"
5668  ,(const char*)csig,ilax);
5669  }
5670  eros = 0;
5671 
5672 L480:
5673  if (fISW[4] > 1) {
5674  Printf(" **************************************************************************");
5675  }
5676  if (sig < 0) {
5677  fErn[it-1] = eros;
5678  if (ilax2 > 0 && ilax2 <= fNu) val2mi = fU[ilax2-1];
5679  } else {
5680  fErp[it-1] = eros;
5681  if (ilax2 > 0 && ilax2 <= fNu) val2pl = fU[ilax2-1];
5682  }
5683  }
5684 //*-*- . . parameter finished. reset v
5685 //*-*- normal termination */
5686  fItaur = 1;
5687  mnfree(1);
5688  i__1 = mpar*(mpar + 1) / 2;
5689  for (j = 1; j <= i__1; ++j) { fVhmat[j-1] = fVthmat[j-1]; }
5690  for (i = 1; i <= mpar; ++i) {
5691  fWerr[i-1] = fMNOTw[i-1];
5692  fGlobcc[i-1] = fMNOTgcc[i-1];
5693  fX[i-1] = fXt[i-1];
5694  }
5695  mninex(fX);
5696  fEDM = sigsav;
5697  fAmin = abest;
5698  fISW[1] = isw2;
5699  fISW[3] = isw4;
5700  fDcovar = dc;
5701  goto L700;
5702 //*-*- new minimum
5703 L650:
5704  fLnewmn = kTRUE;
5705  fISW[1] = 0;
5706  fDcovar = 1;
5707  fISW[3] = 0;
5708  sav = fU[ilax-1];
5709  fItaur = 1;
5710  mnfree(1);
5711  fU[ilax-1] = sav;
5712  mnexin(fX);
5713  fEDM = fBigedm;
5714 //*-*- in any case
5715 L700:
5716  fItaur = 0;
5717  fNfcnmx = nfmxin;
5718  fIstrat = istrav;
5719 } /* mnmnot_ */
5720 
5721 ////////////////////////////////////////////////////////////////////////////////
5722 ///*-*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-*
5723 ///*-* ===================================
5724 ///*-* Called from MNPARS and user-callable
5725 ///*-* Implements one parameter definition, that is:
5726 ///*-* K (external) parameter number
5727 ///*-* CNAMK parameter name
5728 ///*-* UK starting value
5729 ///*-* WK starting step size or uncertainty
5730 ///*-* A, B lower and upper physical parameter limits
5731 ///*-* and sets up (updates) the parameter lists.
5732 ///*-* Output: IERFLG=0 if no problems
5733 ///*-* >0 if MNPARM unable to implement definition
5734 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5735 
5736 void TMinuit::mnparm(Int_t k1, TString cnamj, Double_t uk, Double_t wk, Double_t a, Double_t b, Int_t &ierflg)
5737 {
5738  /* Local variables */
5739  Double_t vplu, a_small, gsmin, pinti, vminu, danger, sav, sav2;
5740  Int_t ierr, kint, in, ix, ktofix, lastin, kinfix, nvl;
5741  TString cnamk, chbufi;
5742 
5743  Int_t k = k1+1;
5744  cnamk = cnamj;
5745  kint = fNpar;
5746  if (k < 1 || k > fMaxext) {
5747 //*-*- parameter number exceeds allowed maximum value
5748  Printf(" MINUIT USER ERROR. PARAMETER NUMBER IS %3d ALLOWED RANGE IS ONE TO %4d",k,fMaxext);
5749  goto L800;
5750  }
5751 //*-*- normal parameter request
5752  ktofix = 0;
5753  if (fNvarl[k-1] < 0) goto L50;
5754 //*-*- previously defined parameter is being redefined
5755 //*-*- find if parameter was fixed
5756  for (ix = 1; ix <= fNpfix; ++ix) {
5757  if (fIpfix[ix-1] == k) ktofix = k;
5758  }
5759  if (ktofix > 0) {
5760  mnwarn("W", "PARAM DEF", "REDEFINING A FIXED PARAMETER.");
5761  if (kint >= fMaxint) {
5762  Printf(" CANNOT RELEASE. MAX NPAR EXCEEDED.");
5763  goto L800;
5764  }
5765  mnfree(-k);
5766  }
5767 //*-*- if redefining previously variable parameter
5768  if (fNiofex[k-1] > 0) kint = fNpar - 1;
5769 L50:
5770 
5771 //*-*- . . .print heading
5772  if (fLphead && fISW[4] >= 0) {
5773  Printf(" PARAMETER DEFINITIONS:");
5774  Printf(" NO. NAME VALUE STEP SIZE LIMITS");
5775  fLphead = kFALSE;
5776  }
5777  if (wk > 0) goto L122;
5778 //*-*- . . .constant parameter . . . .
5779  if (fISW[4] >= 0) {
5780  Printf(" %5d %-10s %13.5e constant",k,(const char*)cnamk,uk);
5781  }
5782  nvl = 0;
5783  goto L200;
5784 L122:
5785  if (a == 0 && b == 0) {
5786 //*-*- variable parameter without limits
5787  nvl = 1;
5788  if (fISW[4] >= 0) {
5789  Printf(" %5d %-10s %13.5e%13.5e no limits",k,(const char*)cnamk,uk,wk);
5790  }
5791  } else {
5792 //*-*- variable parameter with limits
5793  nvl = 4;
5794  fLnolim = kFALSE;
5795  if (fISW[4] >= 0) {
5796  Printf(" %5d %-10s %13.5e%13.5e %13.5e%13.5e",k,(const char*)cnamk,uk,wk,a,b);
5797  }
5798  }
5799 //*-*- . . request for another variable parameter
5800  ++kint;
5801  if (kint > fMaxint) {
5802  Printf(" MINUIT USER ERROR. TOO MANY VARIABLE PARAMETERS.");
5803  goto L800;
5804  }
5805  if (nvl == 1) goto L200;
5806  if (a == b) {
5807  Printf(" USER ERROR IN MINUIT PARAMETER");
5808  Printf(" DEFINITION");
5809  Printf(" UPPER AND LOWER LIMITS EQUAL.");
5810  goto L800;
5811  }
5812  if (b < a) {
5813  sav = b;
5814  b = a;
5815  a = sav;
5816  mnwarn("W", "PARAM DEF", "PARAMETER LIMITS WERE REVERSED.");
5817  if (fLwarn) fLphead = kTRUE;
5818  }
5819  if (b - a > 1e7) {
5820  mnwarn("W", "PARAM DEF", TString::Format("LIMITS ON PARAM%d TOO FAR APART.",k));
5821  if (fLwarn) fLphead = kTRUE;
5822  }
5823  danger = (b - uk)*(uk - a);
5824  if (danger < 0) {
5825  mnwarn("W", "PARAM DEF", "STARTING VALUE OUTSIDE LIMITS.");
5826  }
5827  if (danger == 0) {
5828  mnwarn("W", "PARAM DEF", "STARTING VALUE IS AT LIMIT.");
5829  }
5830 L200:
5831 //*-*- . . . input OK, set values, arrange lists,
5832 //*-*- calculate step sizes GSTEP, DIRIN
5833  fCfrom = "PARAMETR";
5834  fNfcnfr = fNfcn;
5835  fCstatu = "NEW VALUES";
5836  fNu = TMath::Max(fNu,k);
5837  fCpnam[k-1] = cnamk;
5838  fU[k-1] = uk;
5839  fAlim[k-1] = a;
5840  fBlim[k-1] = b;
5841  fNvarl[k-1] = nvl;
5842  mnrset(1);
5843 //*-*- K is external number of new parameter
5844 //*-*- LASTIN is the number of var. params with ext. param. no.< K
5845  lastin = 0;
5846  for (ix = 1; ix <= k-1; ++ix) { if (fNiofex[ix-1] > 0) ++lastin; }
5847 //*-*- KINT is new number of variable params, NPAR is old
5848  if (kint == fNpar) goto L280;
5849  if (kint > fNpar) {
5850 //*-*- insert new variable parameter in list
5851  for (in = fNpar; in >= lastin + 1; --in) {
5852  ix = fNexofi[in-1];
5853  fNiofex[ix-1] = in + 1;
5854  fNexofi[in] = ix;
5855  fX[in] = fX[in-1];
5856  fXt[in] = fXt[in-1];
5857  fDirin[in] = fDirin[in-1];
5858  fG2[in] = fG2[in-1];
5859  fGstep[in] = fGstep[in-1];
5860  fWerr[in] = fWerr[in-1];
5861  fGrd[in] = fGrd[in-1];
5862  }
5863  } else {
5864 //*-*- remove variable parameter from list
5865  for (in = lastin + 1; in <= kint; ++in) {
5866  ix = fNexofi[in];
5867  fNiofex[ix-1] = in;
5868  fNexofi[in-1] = ix;
5869  fX[in-1] = fX[in];
5870  fXt[in-1] = fXt[in];
5871  fDirin[in-1] = fDirin[in];
5872  fG2[in-1] = fG2[in];
5873  fGstep[in-1] = fGstep[in];
5874  fWerr[in-1] = fWerr[in];
5875  fGrd[in-1] = fGrd[in];
5876  }
5877  }
5878 L280:
5879  ix = k;
5880  fNiofex[ix-1] = 0;
5881  fNpar = kint;
5882 //*-*- lists are now arranged . . . .
5883  if (nvl > 0) {
5884  in = lastin + 1;
5885  fNexofi[in-1] = ix;
5886  fNiofex[ix-1] = in;
5887  sav = fU[ix-1];
5888  mnpint(sav, ix-1, pinti);
5889  fX[in-1] = pinti;
5890  fXt[in-1] = fX[in-1];
5891  fWerr[in-1] = wk;
5892  sav2 = sav + wk;
5893  mnpint(sav2, ix-1, pinti);
5894  vplu = pinti - fX[in-1];
5895  sav2 = sav - wk;
5896  mnpint(sav2, ix-1, pinti);
5897  vminu = pinti - fX[in-1];
5898  fDirin[in-1] = (TMath::Abs(vplu) + TMath::Abs(vminu))*.5;
5899  fG2[in-1] = fUp*2 / (fDirin[in-1]*fDirin[in-1]);
5900  gsmin = fEpsma2*8*TMath::Abs(fX[in-1]);
5901  fGstep[in-1] = TMath::Max(gsmin,fDirin[in-1]*.1);
5902  if (fAmin != fUndefi) {
5903  a_small = TMath::Sqrt(fEpsma2*(fAmin + fUp) / fUp);
5904  fGstep[in-1] = TMath::Max(gsmin,a_small*fDirin[in-1]);
5905  }
5906  fGrd[in-1] = fG2[in-1]*fDirin[in-1];
5907 //*-*- if parameter has limits
5908  if (fNvarl[k-1] > 1) {
5909  if (fGstep[in-1] > .5) fGstep[in-1] = .5;
5910  fGstep[in-1] = -fGstep[in-1];
5911  }
5912  }
5913  if (ktofix > 0) {
5914  ierr = 0;
5915  kinfix = fNiofex[ktofix-1];
5916  if (kinfix > 0) mnfixp(kinfix-1, ierr);
5917  if (ierr > 0) goto L800;
5918  }
5919  ierflg = 0;
5920  return;
5921 //*-*- error on input, unable to implement request . . . .
5922 L800:
5923  ierflg = 1;
5924 } /* mnparm_ */
5925 
5926 ////////////////////////////////////////////////////////////////////////////////
5927 ///*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-*-*
5928 ///*-* =========== =======================
5929 ///*-* Called from MNREAD and user-callable
5930 ///*-* Implements one parameter definition, that is:
5931 ///*-* parses the string CRDBUF and calls MNPARM
5932 ///*-*
5933 ///*-* output conditions:
5934 ///*-* ICONDN = 0 all OK
5935 ///*-* ICONDN = 1 error, attempt to define parameter is ignored
5936 ///*-* ICONDN = 2 end of parameter definitions
5937 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5938 
5939 void TMinuit::mnpars(TString &crdbuf, Int_t &icondn)
5940 {
5941  /* Local variables */
5942  Double_t a=0, b=0, fk=0, uk=0, wk=0, xk=0;
5943  Int_t ierr, kapo1, kapo2;
5944  Int_t k, llist, ibegin, lenbuf, istart, lnc, icy;
5945  TString cnamk, comand, celmnt, ctemp;
5946  char stmp[128];
5947 
5948  lenbuf = strlen((const char*)crdbuf);
5949 //*-*- find out whether fixed or free-field format
5950  kapo1 = strspn((const char*)crdbuf, "'");
5951  if (kapo1 == 0) goto L150;
5952  kapo2 = strspn((const char*)crdbuf + kapo1, "'");
5953  if (kapo2 == 0) goto L150;
5954 //*-*- new (free-field) format
5955  kapo2 += kapo1;
5956 //*-*- skip leading blanks if any
5957  for (istart = 1; istart <= kapo1-1; ++istart) {
5958  if (crdbuf(istart-1,1) != ' ') goto L120;
5959  }
5960  goto L210;
5961 L120:
5962 //*-*- parameter number integer
5963  celmnt = crdbuf(istart-1, kapo1-istart);
5964  if (scanf((const char*)celmnt,&fk)) {;}
5965  k = Int_t(fk);
5966  if (k <= 0) goto L210;
5967  cnamk = "PARAM " + celmnt;
5968  if (kapo2 - kapo1 > 1) {
5969  cnamk = crdbuf(kapo1, kapo2-1-kapo1);
5970  }
5971 //*-* special handling if comma or blanks and a comma follow 'name'
5972  for (icy = kapo2 + 1; icy <= lenbuf; ++icy) {
5973  if (crdbuf(icy-1,1) == ',') goto L139;
5974  if (crdbuf(icy-1,1) != ' ') goto L140;
5975  }
5976  uk = 0;
5977  wk = 0;
5978  a = 0;
5979  b = 0;
5980  goto L170;
5981 L139:
5982  ++icy;
5983 L140:
5984  ibegin = icy;
5985  ctemp = crdbuf(ibegin-1,lenbuf-ibegin);
5986  mncrck(ctemp, 20, comand, lnc, fMaxpar, fPARSplist, llist, ierr, fIsyswr);
5987  if (ierr > 0) goto L180;
5988  uk = fPARSplist[0];
5989  wk = 0;
5990  if (llist >= 2) wk = fPARSplist[1];
5991  a = 0;
5992  if (llist >= 3) a = fPARSplist[2];
5993  b = 0;
5994  if (llist >= 4) b = fPARSplist[3];
5995  goto L170;
5996 //*-*- old (fixed-field) format
5997 L150:
5998  if (scanf((const char*)crdbuf,&xk,stmp,&uk,&wk,&a,&b)) {;}
5999  cnamk = stmp;
6000  k = Int_t(xk);
6001  if (k == 0) goto L210;
6002 //*-*- parameter format cracked, implement parameter definition
6003 L170:
6004  mnparm(k-1, cnamk, uk, wk, a, b, ierr);
6005  icondn = ierr;
6006  return;
6007 //*-*- format or other error
6008 L180:
6009  icondn = 1;
6010  return;
6011 //*-*- end of data
6012 L210:
6013  icondn = 2;
6014 } /* mnpars_ */
6015 
6016 ////////////////////////////////////////////////////////////////////////////////
6017 ///*-*-*-*-*-*-*-*-*-*To fit a parabola to npar2p points*-*-*-*-*-*-*-*-*-*-*
6018 ///*-* ==================================
6019 ///*-* npar2p no. of points
6020 ///*-* parx2p(i) x value of point i
6021 ///*-* pary2p(i) y value of point i
6022 ///*-*
6023 ///*-* coef2p(1...3) coefficients of the fitted parabola
6024 ///*-* y=coef2p(1) + coef2p(2)*x + coef2p(3)*x**2
6025 ///*-* sdev2p= variance
6026 ///*-* method : chi**2 = min equation solved explicitly
6027 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6028 
6029 void TMinuit::mnpfit(Double_t *parx2p, Double_t *pary2p, Int_t npar2p, Double_t *coef2p, Double_t &sdev2p)
6030 {
6031  /* Local variables */
6032  Double_t a, f, s, t, y, s2, x2, x3, x4, y2, cz[3], xm, xy, x2y;
6033  x2 = x3 = 0;
6034  Int_t i;
6035 
6036  /* Parameter adjustments */
6037  --coef2p;
6038  --pary2p;
6039  --parx2p;
6040 
6041  /* Function Body */
6042  for (i = 1; i <= 3; ++i) { cz[i-1] = 0; }
6043  sdev2p = 0;
6044  if (npar2p < 3) goto L10;
6045  f = (Double_t) (npar2p);
6046 //*-* --- center x values for reasons of machine precision
6047  xm = 0;
6048  for (i = 1; i <= npar2p; ++i) { xm += parx2p[i]; }
6049  xm /= f;
6050  x2 = 0;
6051  x3 = 0;
6052  x4 = 0;
6053  y = 0;
6054  y2 = 0;
6055  xy = 0;
6056  x2y = 0;
6057  for (i = 1; i <= npar2p; ++i) {
6058  s = parx2p[i] - xm;
6059  t = pary2p[i];
6060  s2 = s*s;
6061  x2 += s2;
6062  x3 += s*s2;
6063  x4 += s2*s2;
6064  y += t;
6065  y2 += t*t;
6066  xy += s*t;
6067  x2y += s2*t;
6068  }
6069  a = (f*x4 - x2*x2)*x2 - f*(x3*x3);
6070  if (a == 0) goto L10;
6071  cz[2] = (x2*(f*x2y - x2*y) - f*x3*xy) / a;
6072  cz[1] = (xy - x3*cz[2]) / x2;
6073  cz[0] = (y - x2*cz[2]) / f;
6074  if (npar2p == 3) goto L6;
6075  sdev2p = y2 - (cz[0]*y + cz[1]*xy + cz[2]*x2y);
6076  if (sdev2p < 0) sdev2p = 0;
6077  sdev2p /= f - 3;
6078 L6:
6079  cz[0] += xm*(xm*cz[2] - cz[1]);
6080  cz[1] -= xm*2*cz[2];
6081 L10:
6082  for (i = 1; i <= 3; ++i) { coef2p[i] = cz[i-1]; }
6083 } /* mnpfit_ */
6084 
6085 ////////////////////////////////////////////////////////////////////////////////
6086 ///*-*-*-*-*-*-*Calculates the internal parameter value PINTI*-*-*-*-*-*-*-*
6087 ///*-* =============================================
6088 ///*-* corresponding to the external value PEXTI for parameter I.
6089 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6090 
6091 void TMinuit::mnpint(Double_t &pexti, Int_t i1, Double_t &pinti)
6092 {
6093  /* Local variables */
6094  Double_t a, alimi, blimi, yy, yy2;
6095  Int_t igo;
6096  TString chbuf2, chbufi;
6097 
6098  Int_t i = i1+1;
6099  pinti = pexti;
6100  igo = fNvarl[i-1];
6101  if (igo == 4) {
6102 //*-* -- there are two limits
6103  alimi = fAlim[i-1];
6104  blimi = fBlim[i-1];
6105  yy = (pexti - alimi)*2 / (blimi - alimi) - 1;
6106  yy2 = yy*yy;
6107  if (yy2 >= 1 - fEpsma2) {
6108  if (yy < 0) {
6109  a = fVlimlo;
6110  chbuf2 = " IS AT ITS LOWER ALLOWED LIMIT.";
6111  } else {
6112  a = fVlimhi;
6113  chbuf2 = " IS AT ITS UPPER ALLOWED LIMIT.";
6114  }
6115  pinti = a;
6116  pexti = alimi + (blimi - alimi)*.5*(TMath::Sin(a) + 1);
6117  fLimset = kTRUE;
6118  if (yy2 > 1) chbuf2 = " BROUGHT BACK INSIDE LIMITS.";
6119  mnwarn("W", fCfrom, TString::Format("VARIABLE%d%s",i,chbuf2.Data()));
6120  } else {
6121  pinti = TMath::ASin(yy);
6122  }
6123  }
6124 } /* mnpint_ */
6125 
6126 ////////////////////////////////////////////////////////////////////////////////
6127 ///*-*-*-*Plots points in array xypt onto one page with labelled axes*-*-*-*-*
6128 ///*-* ===========================================================
6129 ///*-* NXYPT is the number of points to be plotted
6130 ///*-* XPT(I) = x-coord. of ith point
6131 ///*-* YPT(I) = y-coord. of ith point
6132 ///*-* CHPT(I) = character to be plotted at this position
6133 ///*-* the input point arrays XPT, YPT, CHPT are destroyed.
6134 ///*-*
6135 ///*-*
6136 ///*-* If fGraphicsmode is true (default), a TGraph object is produced
6137 ///*-* via the Plug-in handler. To get the plot, you can do:
6138 ///*-* TGraph *gr = (TGraph*)gMinuit->GetPlot();
6139 ///*-* gr->Draw("al");
6140 ///*-*
6141 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6142 
6143 void TMinuit::mnplot(Double_t *xpt, Double_t *ypt, char *chpt, Int_t nxypt, Int_t npagwd, Int_t npagln)
6144 {
6145 
6146  if (fGraphicsMode) {
6147  TPluginHandler *h;
6148  if ((h = gROOT->GetPluginManager()->FindHandler("TMinuitGraph"))) {
6149  //remove the first two points
6150  if (h->LoadPlugin() != -1)
6151  fPlot = (TObject*)h->ExecPlugin(3,nxypt-2,&xpt[2],&ypt[2]);
6152  }
6153  return;
6154  }
6155 
6156  static TString cdot = ".";
6157  static TString cslash = "/";
6158 
6159  /* Local variables */
6160  Double_t xmin, ymin, xmax, ymax, savx, savy, yprt;
6161  Double_t bwidx, bwidy, xbest, ybest, ax, ay, bx, by;
6162  Double_t xvalus[12], any, dxx, dyy;
6163  Int_t iten, i, j, k, maxnx, maxny, iquit, ni, linodd;
6164  Int_t nxbest, nybest, km1, ibk, isp1, nx, ny, ks, ix;
6165  TString chmess, ctemp;
6166  Bool_t overpr;
6167  char cline[120];
6168  char chsav, chbest;
6169 
6170  /* Function Body */
6171  //*-* Computing MIN
6172  maxnx = TMath::Min(npagwd-20,100);
6173  if (maxnx < 10) maxnx = 10;
6174  maxny = npagln;
6175  if (maxny < 10) maxny = 10;
6176  if (nxypt <= 1) return;
6177  xbest = xpt[0];
6178  ybest = ypt[0];
6179  chbest = chpt[0];
6180  //*-*- order the points by decreasing y
6181  km1 = nxypt - 1;
6182  for (i = 1; i <= km1; ++i) {
6183  iquit = 0;
6184  ni = nxypt - i;
6185  for (j = 1; j <= ni; ++j) {
6186  if (ypt[j-1] > ypt[j]) continue;
6187  savx = xpt[j-1];
6188  xpt[j-1] = xpt[j];
6189  xpt[j] = savx;
6190  savy = ypt[j-1];
6191  ypt[j-1] = ypt[j];
6192  ypt[j] = savy;
6193  chsav = chpt[j-1];
6194  chpt[j-1]= chpt[j];
6195  chpt[j] = chsav;
6196  iquit = 1;
6197  }
6198  if (iquit == 0) break;
6199  }
6200  //*-*- find extreme values
6201  xmax = xpt[0];
6202  xmin = xmax;
6203  for (i = 1; i <= nxypt; ++i) {
6204  if (xpt[i-1] > xmax) xmax = xpt[i-1];
6205  if (xpt[i-1] < xmin) xmin = xpt[i-1];
6206  }
6207  dxx = (xmax - xmin)*.001;
6208  xmax += dxx;
6209  xmin -= dxx;
6210  mnbins(xmin, xmax, maxnx, xmin, xmax, nx, bwidx);
6211  ymax = ypt[0];
6212  ymin = ypt[nxypt-1];
6213  if (ymax == ymin) ymax = ymin + 1;
6214  dyy = (ymax - ymin)*.001;
6215  ymax += dyy;
6216  ymin -= dyy;
6217  mnbins(ymin, ymax, maxny, ymin, ymax, ny, bwidy);
6218  any = (Double_t) ny;
6219  //*-*- if first point is blank, it is an 'origin'
6220  if (chbest == ' ') goto L50;
6221  xbest = (xmax + xmin)*.5;
6222  ybest = (ymax + ymin)*.5;
6223 L50:
6224  //*-*- find scale constants
6225  ax = 1 / bwidx;
6226  ay = 1 / bwidy;
6227  bx = -ax*xmin + 2;
6228  by = -ay*ymin - 2;
6229  //*-*- convert points to grid positions
6230  for (i = 1; i <= nxypt; ++i) {
6231  xpt[i-1] = ax*xpt[i-1] + bx;
6232  ypt[i-1] = any - ay*ypt[i-1] - by;
6233  }
6234  nxbest = Int_t((ax*xbest + bx));
6235  nybest = Int_t((any - ay*ybest - by));
6236  //*-*- print the points
6237  ny += 2;
6238  nx += 2;
6239  isp1 = 1;
6240  linodd = 1;
6241  overpr = kFALSE;
6242  for (i = 1; i <= ny; ++i) {
6243  for (ibk = 1; ibk <= nx; ++ibk) { cline[ibk-1] = ' '; }
6244  cline[nx] = '\0';
6245  cline[nx+1] = '\0';
6246  cline[0] = '.';
6247  // not needed - but to avoid a wrongly reported compiler warning (see ROOT-6496)
6248  if (nx>0) cline[nx-1] = '.';
6249  cline[nxbest-1] = '.';
6250  if (i != 1 && i != nybest && i != ny) goto L320;
6251  for (j = 1; j <= nx; ++j) { cline[j-1] = '.'; }
6252 L320:
6253  yprt = ymax - Double_t(i-1)*bwidy;
6254  if (isp1 > nxypt) goto L350;
6255  //*-*- find the points to be plotted on this line
6256  for (k = isp1; k <= nxypt; ++k) {
6257  ks = Int_t(ypt[k-1]);
6258  if (ks > i) goto L345;
6259  ix = Int_t(xpt[k-1]);
6260  if (cline[ix-1] == '.') goto L340;
6261  if (cline[ix-1] == ' ') goto L340;
6262  if (cline[ix-1] == chpt[k-1]) continue;
6263  overpr = kTRUE;
6264  //*-*- OVERPR is true if one or more positions contains more than
6265  //*-*- one point
6266  cline[ix-1] = '&';
6267  continue;
6268 L340:
6269  cline[ix-1] = chpt[k-1];
6270  }
6271  isp1 = nxypt + 1;
6272  goto L350;
6273 L345:
6274  isp1 = k;
6275 L350:
6276  if (linodd == 1 || i == ny) goto L380;
6277  linodd = 1;
6278  ctemp = cline;
6279  Printf(" %s",(const char*)ctemp);
6280  goto L400;
6281 L380:
6282  ctemp = cline;
6283  Printf(" %14.7g ..%s",yprt,(const char*)ctemp);
6284  linodd = 0;
6285 L400:
6286  ;
6287  }
6288  //*-*- print labels on x-axis every ten columns
6289  for (ibk = 1; ibk <= nx; ++ibk) {
6290  cline[ibk-1] = ' ';
6291  if (ibk % 10 == 1) cline[ibk-1] = '/';
6292  }
6293  Printf(" %s",cline);
6294 
6295  for (ibk = 1; ibk <= 12; ++ibk) {
6296  xvalus[ibk-1] = xmin + Double_t(ibk-1)*10*bwidx;
6297  }
6298  iten = (nx + 9) / 10;
6299  for (ibk = 1; ibk <= iten && ibk <= 12; ++ibk) {
6300  snprintf(cline + (ibk-1)*10, 11-(ibk == 12), "%#9.3g ", xvalus[ibk-1]);
6301  }
6302  Printf(" %s", cline);
6303  chmess = " ";
6304  if (overpr) chmess = " Overprint character is &";
6305  Printf(" ONE COLUMN=%13.7g%s",bwidx,(const char*)chmess);
6306 } /* mnplot_ */
6307 
6308 ////////////////////////////////////////////////////////////////////////////////
6309 ///*-*-*-*Provides the user with information concerning the current status*-*-*
6310 ///*-* ================================================================
6311 ///*-* of parameter number IUEXT. Namely, it returns:
6312 ///*-* CHNAM: the name of the parameter
6313 ///*-* VAL: the current (external) value of the parameter
6314 ///*-* ERR: the current estimate of the parameter uncertainty
6315 ///*-* XLOLIM: the lower bound (or zero if no limits)
6316 ///*-* XUPLIM: the upper bound (or zero if no limits)
6317 ///*-* IUINT: the internal parameter number (or zero if not variable,
6318 ///*-* or negative if undefined).
6319 ///*-* Note also: If IUEXT is negative, then it is -internal parameter
6320 ///*-* number, and IUINT is returned as the EXTERNAL number.
6321 ///*-* Except for IUINT, this is exactly the inverse of MNPARM
6322 ///*-* User-called
6323 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6324 
6325 void TMinuit::mnpout(Int_t iuext1, TString &chnam, Double_t &val, Double_t &err, Double_t &xlolim, Double_t &xuplim, Int_t &iuint) const
6326 {
6327  /* Local variables */
6328  Int_t iint, iext, nvl;
6329 
6330  Int_t iuext = iuext1 + 1;
6331  xlolim = 0;
6332  xuplim = 0;
6333  err = 0;
6334  if (iuext == 0) goto L100;
6335  if (iuext < 0) {
6336 //*-*- internal parameter number specified
6337  iint = -(iuext);
6338  if (iint > fNpar) goto L100;
6339  iext = fNexofi[iint-1];
6340  iuint = iext;
6341  } else {
6342 //*-*- external parameter number specified
6343  iext = iuext;
6344  if (iext > fNu) goto L100;
6345  iint = fNiofex[iext-1];
6346  iuint = iint;
6347  }
6348 //*-*- in both cases
6349  nvl = fNvarl[iext-1];
6350  if (nvl < 0) goto L100;
6351  chnam = fCpnam[iext-1];
6352  val = fU[iext-1];
6353  if (iint > 0) err = fWerr[iint-1];
6354  if (nvl == 4) {
6355  xlolim = fAlim[iext-1];
6356  xuplim = fBlim[iext-1];
6357  }
6358  return;
6359 //*-*- parameter is undefined
6360 L100:
6361  iuint = -1;
6362  chnam = "undefined";
6363  val = 0;
6364 } /* mnpout_ */
6365 
6366 ////////////////////////////////////////////////////////////////////////////////
6367 ///*-*-*-*Prints the values of the parameters at the time of the call*-*-*-*-*
6368 ///*-* ===========================================================
6369 ///*-* also prints other relevant information such as function value,
6370 ///*-* estimated distance to minimum, parameter errors, step sizes.
6371 ///*-*
6372 ///*-* According to the value of IKODE, the printout is:/
6373 ///*-* IKODE=INKODE= 0 only info about function value
6374 ///*-* 1 parameter values, errors, limits
6375 ///*-* 2 values, errors, step sizes, internal values
6376 ///*-* 3 values, errors, step sizes, first derivs.
6377 ///*-* 4 values, parabolic errors, MINOS errors
6378 ///*-* when INKODE=5, MNPRIN chooses IKODE=1,2, or 3, according to fISW[1]
6379 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6380 
6381 void TMinuit::mnprin(Int_t inkode, Double_t fval)
6382 {
6383  /* Initialized data */
6384 
6385  static TString cblank = " ";
6386  static TString cnambf = " ";
6387 
6388  /* Local variables */
6389  Double_t dcmax, x1, x2, x3, dc;
6390  x2 = x3 = 0;
6391  Int_t nadd, i, k, l, m, ikode, ic, nc, ntrail, lbl;
6392  TString chedm;
6393  TString colhdl[6], colhdu[6], cx2, cx3, cheval;
6394 
6395  if (fNu == 0) {
6396  Printf(" THERE ARE CURRENTLY NO PARAMETERS DEFINED");
6397  return;
6398  }
6399 //*-*- get value of IKODE based in INKODE, fISW[1]
6400  ikode = inkode;
6401  if (inkode == 5) {
6402  ikode = fISW[1] + 1;
6403  if (ikode > 3) ikode = 3;
6404  }
6405 //*-*- set 'default' column headings
6406  for (k = 1; k <= 6; ++k) {
6407  colhdu[k-1] = "UNDEFINED";
6408  colhdl[k-1] = "COLUMN HEAD";
6409  }
6410 //*-*- print title if Minos errors, and title exists.
6411  if (ikode == 4 && fCtitl != fCundef) {
6412  Printf(" MINUIT TASK: %s",(const char*)fCtitl);
6413  }
6414 //*-*- report function value and status
6415  if (fval == fUndefi) cheval = " unknown ";
6416  else cheval.Form("%g",fval);
6417 
6418  if (fEDM == fBigedm) chedm = " unknown ";
6419  else chedm.Form("%g",fEDM);
6420 
6421  nc = fNfcn - fNfcnfr;
6422  Printf(" FCN=%s FROM %8s STATUS=%10s %6d CALLS %9d TOTAL"
6423  ,(const char*)cheval
6424  ,(const char*)fCfrom
6425  ,(const char*)fCstatu,nc,fNfcn);
6426  m = fISW[1];
6427  if (m == 0 || m == 2 || fDcovar == 0) {
6428  Printf(" EDM=%s STRATEGY=%2d %s"
6429  ,(const char*)chedm,fIstrat
6430  ,(const char*)fCovmes[m]);
6431  } else {
6432  dcmax = 1;
6433  dc = TMath::Min(fDcovar,dcmax)*100;
6434  Printf(" EDM=%s STRATEGY=%2d ERROR MATRIX UNCERTAINTY %5.1f per cent"
6435  ,(const char*)chedm,fIstrat,dc);
6436  }
6437 
6438  if (ikode == 0) return;
6439 //*-*- find longest name (for Rene!)
6440  ntrail = 10;
6441  for (i = 1; i <= fNu; ++i) {
6442  if (fNvarl[i-1] < 0) continue;
6443  for (ic = 10; ic >= 1; --ic) {
6444  if (fCpnam[i-1](ic-1,1) != " ") goto L16;
6445  }
6446  ic = 1;
6447 L16:
6448  lbl = 10 - ic;
6449  if (lbl < ntrail) ntrail = lbl;
6450  }
6451  nadd = ntrail / 2 + 1;
6452  if (ikode == 1) {
6453  colhdu[0] = " ";
6454  colhdl[0] = " ERROR ";
6455  colhdu[1] = " PHYSICAL";
6456  colhdu[2] = " LIMITS ";
6457  colhdl[1] = " NEGATIVE ";
6458  colhdl[2] = " POSITIVE ";
6459  }
6460  if (ikode == 2) {
6461  colhdu[0] = " ";
6462  colhdl[0] = " ERROR ";
6463  colhdu[1] = " INTERNAL ";
6464  colhdl[1] = " STEP SIZE ";
6465  colhdu[2] = " INTERNAL ";
6466  colhdl[2] = " VALUE ";
6467  }
6468  if (ikode == 3) {
6469  colhdu[0] = " ";
6470  colhdl[0] = " ERROR ";
6471  colhdu[1] = " STEP ";
6472  colhdl[1] = " SIZE ";
6473  colhdu[2] = " FIRST ";
6474  colhdl[2] = " DERIVATIVE ";
6475  }
6476  if (ikode == 4) {
6477  colhdu[0] = " PARABOLIC ";
6478  colhdl[0] = " ERROR ";
6479  colhdu[1] = " MINOS ";
6480  colhdu[2] = "ERRORS ";
6481  colhdl[1] = " NEGATIVE ";
6482  colhdl[2] = " POSITIVE ";
6483  }
6484 
6485  if (ikode != 4) {
6486  if (fISW[1] < 3) colhdu[0] = " APPROXIMATE ";
6487  if (fISW[1] < 1) colhdu[0] = " CURRENT GUESS";
6488  }
6489  Printf(" EXT PARAMETER %-14s%-14s%-14s",(const char*)colhdu[0]
6490  ,(const char*)colhdu[1]
6491  ,(const char*)colhdu[2]);
6492  Printf(" NO. NAME VALUE %-14s%-14s%-14s",(const char*)colhdl[0]
6493  ,(const char*)colhdl[1]
6494  ,(const char*)colhdl[2]);
6495 //*-*- . . . loop over parameters . .
6496  for (i = 1; i <= fNu; ++i) {
6497  if (fNvarl[i-1] < 0) continue;
6498  l = fNiofex[i-1];
6499  cnambf = cblank(0,nadd) + fCpnam[i-1];
6500  if (l == 0) goto L55;
6501 //*-*- variable parameter.
6502  x1 = fWerr[l-1];
6503  cx2 = "PLEASE GET X..";
6504  cx3 = "PLEASE GET X..";
6505  if (ikode == 1) {
6506  if (fNvarl[i-1] <= 1) {
6507  Printf("%4d %-11s%14.5e%14.5e",i,(const char*)cnambf,fU[i-1],x1);
6508  continue;
6509  } else {
6510  x2 = fAlim[i-1];
6511  x3 = fBlim[i-1];
6512  }
6513  }
6514  if (ikode == 2) {
6515  x2 = fDirin[l-1];
6516  x3 = fX[l-1];
6517  }
6518  if (ikode == 3) {
6519  x2 = fDirin[l-1];
6520  x3 = fGrd[l-1];
6521  if (fNvarl[i-1] > 1 && TMath::Abs(TMath::Cos(fX[l-1])) < .001) {
6522  cx3 = "** at limit **";
6523  }
6524  }
6525  if (ikode == 4) {
6526  x2 = fErn[l-1];
6527  if (x2 == 0) cx2 = " ";
6528  if (x2 == fUndefi) cx2 = " at limit ";
6529  x3 = fErp[l-1];
6530  if (x3 == 0) cx3 = " ";
6531  if (x3 == fUndefi) cx3 = " at limit ";
6532  }
6533  if (cx2 == "PLEASE GET X..") cx2.Form("%14.5e",x2);
6534  if (cx3 == "PLEASE GET X..") cx3.Form("%14.5e",x3);
6535  Printf("%4d %-11s%14.5e%14.5e%-14s%-14s",i
6536  ,(const char*)cnambf,fU[i-1],x1
6537  ,(const char*)cx2,(const char*)cx3);
6538 
6539 //*-*- check if parameter is at limit
6540  if (fNvarl[i-1] <= 1 || ikode == 3) continue;
6541  if (TMath::Abs(TMath::Cos(fX[l-1])) < .001) {
6542  Printf(" WARNING - - ABOVE PARAMETER IS AT LIMIT.");
6543  }
6544  continue;
6545 
6546 //*-*- print constant or fixed parameter.
6547 L55:
6548  colhdu[0] = " constant ";
6549  if (fNvarl[i-1] > 0) colhdu[0] = " fixed ";
6550  if (fNvarl[i-1] == 4 && ikode == 1) {
6551  Printf("%4d %-11s%14.5e%-14s%14.5e%14.5e",i
6552  ,(const char*)cnambf,fU[i-1]
6553  ,(const char*)colhdu[0],fAlim[i-1],fBlim[i-1]);
6554  } else {
6555  Printf("%4d %-11s%14.5e%s",i
6556  ,(const char*)cnambf,fU[i-1],(const char*)colhdu[0]);
6557  }
6558  }
6559 
6560  if (fUp != fUpdflt) {
6561  Printf(" ERR DEF= %g",fUp);
6562  }
6563  return;
6564 } /* mnprin_ */
6565 
6566 ////////////////////////////////////////////////////////////////////////////////
6567 ///*-*-*-*-*-*Calculates the eigenvalues of v to see if positive-def*-*-*-*-*
6568 ///*-* ======================================================
6569 ///*-* if not, adds constant along diagonal to make positive.
6570 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6571 
6573 {
6574  /* Local variables */
6575  Double_t dgmin, padd, pmin, pmax, dg, epspdf, epsmin;
6576  Int_t ndex, i, j, ndexd, ip, ifault;
6577  TString chbuff, ctemp;
6578 
6579  epsmin = 1e-6;
6580  epspdf = TMath::Max(epsmin,fEpsma2);
6581  dgmin = fVhmat[0];
6582 //*-*- Check if negative or zero on diagonal
6583  for (i = 1; i <= fNpar; ++i) {
6584  ndex = i*(i + 1) / 2;
6585  if (fVhmat[ndex-1] <= 0) {
6586  mnwarn("W", fCfrom, TString::Format("Negative diagonal element %d in Error Matrix",i));
6587  }
6588  if (fVhmat[ndex-1] < dgmin) dgmin = fVhmat[ndex-1];
6589  }
6590  if (dgmin <= 0) {
6591  dg = epspdf + 1 - dgmin;
6592  mnwarn("W", fCfrom, TString::Format("%g added to diagonal of error matrix",dg));
6593  } else {
6594  dg = 0;
6595  }
6596 //*-*- Store VHMAT in P, make sure diagonal pos.
6597  for (i = 1; i <= fNpar; ++i) {
6598  ndex = i*(i-1) / 2;
6599  ndexd = ndex + i;
6600  fVhmat[ndexd-1] += dg;
6601  if (fVhmat[ndexd-1]==0) {
6602  fPSDFs[i-1] = 1 / 1e-19; // a totally arbitrary silly small value
6603  } else {
6604  fPSDFs[i-1] = 1 / TMath::Sqrt(fVhmat[ndexd-1]);
6605  }
6606  for (j = 1; j <= i; ++j) {
6607  ++ndex;
6608  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[ndex-1]*fPSDFs[i-1]*fPSDFs[j-1];
6609  }
6610  }
6611 //*-*- call eigen (p,p,maxint,npar,pstar,-npar)
6612  mneig(fP, fMaxint, fNpar, fMaxint, fPstar, epspdf, ifault);
6613  pmin = fPstar[0];
6614  pmax = fPstar[0];
6615  for (ip = 2; ip <= fNpar; ++ip) {
6616  if (fPstar[ip-1] < pmin) pmin = fPstar[ip-1];
6617  if (fPstar[ip-1] > pmax) pmax = fPstar[ip-1];
6618  }
6619  pmax = TMath::Max(TMath::Abs(pmax),Double_t(1));
6620  if ((pmin <= 0 && fLwarn) || fISW[4] >= 2) {
6621  Printf(" EIGENVALUES OF SECOND-DERIVATIVE MATRIX:");
6622  ctemp = " ";
6623  for (ip = 1; ip <= fNpar; ++ip) {
6624  ctemp += TString::Format(" %11.4e",fPstar[ip-1]);
6625  }
6626  Printf("%s", ctemp.Data());
6627  }
6628  if (pmin > epspdf*pmax) return;
6629  if (fISW[1] == 3) fISW[1] = 2;
6630  padd = pmax*.001 - pmin;
6631  for (ip = 1; ip <= fNpar; ++ip) {
6632  ndex = ip*(ip + 1) / 2;
6633  fVhmat[ndex-1] *= padd + 1;
6634  }
6635  fCstatu = "NOT POSDEF";
6636  mnwarn("W", fCfrom, Form("MATRIX FORCED POS-DEF BY ADDING %f TO DIAGONAL.",padd));
6637 
6638 } /* mnpsdf_ */
6639 
6640 ////////////////////////////////////////////////////////////////////////////////
6641 ///*-*-*-*-*Called only by MNSIMP (and MNIMPR) to add a new point*-*-*-*-*-*-*
6642 ///*-* =====================================================
6643 ///*-* and remove an old one from the current simplex, and get the
6644 ///*-* estimated distance to minimum.
6645 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6646 
6647 void TMinuit::mnrazz(Double_t ynew, Double_t *pnew, Double_t *y, Int_t &jh, Int_t &jl)
6648 {
6649  /* Local variables */
6650  Double_t pbig, plit;
6651  Int_t i, j, nparp1;
6652 
6653  /* Function Body */
6654  for (i = 1; i <= fNpar; ++i) { fP[i + jh*fMaxpar - fMaxpar-1] = pnew[i-1]; }
6655  y[jh-1] = ynew;
6656  if (ynew < fAmin) {
6657  for (i = 1; i <= fNpar; ++i) { fX[i-1] = pnew[i-1]; }
6658  mninex(fX);
6659  fAmin = ynew;
6660  fCstatu = "PROGRESS ";
6661  jl = jh;
6662  }
6663  jh = 1;
6664  nparp1 = fNpar + 1;
6665  for (j = 2; j <= nparp1; ++j) { if (y[j-1] > y[jh-1]) jh = j; }
6666  fEDM = y[jh-1] - y[jl-1];
6667  if (fEDM <= 0) goto L45;
6668  for (i = 1; i <= fNpar; ++i) {
6669  pbig = fP[i-1];
6670  plit = pbig;
6671  for (j = 2; j <= nparp1; ++j) {
6672  if (fP[i + j*fMaxpar - fMaxpar-1] > pbig) pbig = fP[i + j*fMaxpar - fMaxpar-1];
6673  if (fP[i + j*fMaxpar - fMaxpar-1] < plit) plit = fP[i + j*fMaxpar - fMaxpar-1];
6674  }
6675  fDirin[i-1] = pbig - plit;
6676  }
6677 L40:
6678  return;
6679 L45:
6680  Printf(" FUNCTION VALUE DOES NOT SEEM TO DEPEND ON ANY OF THE %d VARIABLE PARAMETERS.",fNpar);
6681  Printf(" VERIFY THAT STEP SIZES ARE BIG ENOUGH AND CHECK FCN LOGIC.");
6682  Printf(" *******************************************************************************");
6683  Printf(" *******************************************************************************");
6684  goto L40;
6685 } /* mnrazz_ */
6686 
6687 ////////////////////////////////////////////////////////////////////////////////
6688 ///*-*-*-*-*-*-*This is a super-portable random number generator*-*-*-*-*-*-*
6689 ///*-* ================================================
6690 ///*-* It should not overflow on any 32-bit machine.
6691 ///*-* The cycle is only ~10**9, so use with care!
6692 ///*-* Note especially that VAL must not be undefined on input.
6693 ///*-* Set Default Starting Seed
6694 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6695 
6696 void TMinuit::mnrn15(Double_t &val, Int_t &inseed)
6697 {
6698  /* Initialized data */
6699 
6700  static Int_t iseed = 12345;
6701 
6702  Int_t k;
6703 
6704  if (val == 3) goto L100;
6705  inseed = iseed;
6706  k = iseed / 53668;
6707  iseed = (iseed - k*53668)*40014 - k*12211;
6708  if (iseed < 0) iseed += 2147483563;
6709  val = Double_t(iseed*4.656613e-10);
6710  return;
6711 //*-* "entry" to set seed, flag is VAL=3
6712 L100:
6713  iseed = inseed;
6714 } /* mnrn15_ */
6715 
6716 ////////////////////////////////////////////////////////////////////////////////
6717 ///*-*-*-*-*-*-*-*Resets function value and errors to UNDEFINED*-*-*-*-*-*-*-*
6718 ///*-* =============================================
6719 ///*-* If IOPT=1,
6720 ///*-* If IOPT=0, sets only MINOS errors to undefined
6721 ///*-* Called from MNCLER and whenever problem changes, for example
6722 ///*-* after SET LIMITS, SET PARAM, CALL FCN 6
6723 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6724 
6726 {
6727  Int_t iext, i;
6728 
6729  fCstatu = "RESET ";
6730  if (iopt >= 1) {
6731  fAmin = fUndefi;
6732  fFval3 = TMath::Abs(fAmin)*2 + 1;
6733  fEDM = fBigedm;
6734  fISW[3] = 0;
6735  fISW[1] = 0;
6736  fDcovar = 1;
6737  fISW[0] = 0;
6738  }
6739  fLnolim = kTRUE;
6740  for (i = 1; i <= fNpar; ++i) {
6741  iext = fNexofi[i-1];
6742  if (fNvarl[iext-1] >= 4) fLnolim = kFALSE;
6743  fErp[i-1] = 0;
6744  fErn[i-1] = 0;
6745  fGlobcc[i-1] = 0;
6746  }
6747  if (fISW[1] >= 1) {
6748  fISW[1] = 1;
6749  fDcovar = TMath::Max(fDcovar,.5);
6750  }
6751 } /* mnrset_ */
6752 
6753 ////////////////////////////////////////////////////////////////////////////////
6754 ///*-*-*-*Writes current parameter values and step sizes onto file ISYSSA*-*-*
6755 ///*-* ===============================================================
6756 ///*-* in format which can be reread by Minuit for restarting.
6757 ///*-* The covariance matrix is also output if it exists.
6758 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6759 
6761 {
6762  Printf("mnsave is dummy in TMinuit");
6763 
6764 } /* mnsave_ */
6765 
6766 ////////////////////////////////////////////////////////////////////////////////
6767 ///*-*-*-*-*Scans the values of FCN as a function of one parameter*-*-*-*-*-*
6768 ///*-* ======================================================
6769 ///*-* and plots the resulting values as a curve using MNPLOT.
6770 ///*-* It may be called to scan one parameter or all parameters.
6771 ///*-* retains the best function and parameter values found.
6772 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6773 
6775 {
6776  /* Local variables */
6777  Double_t step, uhigh, xhreq, xlreq, ubest, fnext, unext, xh, xl;
6778  Int_t ipar, iint, icall, ncall, nbins, nparx;
6779  Int_t nxypt, nccall, iparwd;
6780 
6781  xlreq = TMath::Min(fWord7[2],fWord7[3]);
6782  xhreq = TMath::Max(fWord7[2],fWord7[3]);
6783  ncall = Int_t((fWord7[1] + .01));
6784  if (ncall <= 1) ncall = 41;
6785  if (ncall > 98) ncall = 98;
6786  nccall = ncall;
6787  if (fAmin == fUndefi) mnamin();
6788  iparwd = Int_t((fWord7[0] + .1));
6789  ipar = TMath::Max(iparwd,0);
6790  fCstatu = "NO CHANGE";
6791  if (iparwd > 0) goto L200;
6792 
6793 //*-*- equivalent to a loop over parameters requested
6794 L100:
6795  ++ipar;
6796  if (ipar > fNu) goto L900;
6797  iint = fNiofex[ipar-1];
6798  if (iint <= 0) goto L100;
6799 //*-*- set up range for parameter IPAR
6800 L200:
6801  iint = fNiofex[ipar-1];
6802  ubest = fU[ipar-1];
6803  fXpt[0] = ubest;
6804  fYpt[0] = fAmin;
6805  fChpt[0] = ' ';
6806  fXpt[1] = ubest;
6807  fYpt[1] = fAmin;
6808  fChpt[1] = 'X';
6809  nxypt = 2;
6810  if (fNvarl[ipar-1] > 1) goto L300;
6811 
6812 //*-*- no limits on parameter
6813  if (xlreq == xhreq) goto L250;
6814  unext = xlreq;
6815  step = (xhreq - xlreq) / Double_t(ncall-1);
6816  goto L500;
6817 L250:
6818  xl = ubest - fWerr[iint-1];
6819  xh = ubest + fWerr[iint-1];
6820  mnbins(xl, xh, ncall, unext, uhigh, nbins, step);
6821  nccall = nbins + 1;
6822  goto L500;
6823 //*-*- limits on parameter
6824 L300:
6825  if (xlreq == xhreq) goto L350;
6826 //*-* Computing MAX
6827  xl = TMath::Max(xlreq,fAlim[ipar-1]);
6828 //*-* Computing MIN
6829  xh = TMath::Min(xhreq,fBlim[ipar-1]);
6830  if (xl >= xh) goto L700;
6831  unext = xl;
6832  step = (xh - xl) / Double_t(ncall-1);
6833  goto L500;
6834 L350:
6835  unext = fAlim[ipar-1];
6836  step = (fBlim[ipar-1] - fAlim[ipar-1]) / Double_t(ncall-1);
6837 //*-*- main scanning loop over parameter IPAR
6838 L500:
6839  for (icall = 1; icall <= nccall; ++icall) {
6840  fU[ipar-1] = unext;
6841  nparx = fNpar;
6842  Eval(nparx, fGin, fnext, fU, 4); ++fNfcn;
6843  ++nxypt;
6844  fXpt[nxypt-1] = unext;
6845  fYpt[nxypt-1] = fnext;
6846  fChpt[nxypt-1] = '*';
6847  if (fnext < fAmin) {
6848  fAmin = fnext;
6849  ubest = unext;
6850  fCstatu = "IMPROVED ";
6851  }
6852  unext += step;
6853  }
6854  fChpt[nccall] = 0;
6855 
6856 //*-*- finished with scan of parameter IPAR
6857  fU[ipar-1] = ubest;
6858  mnexin(fX);
6859  if (fISW[4] >= 1)
6860  Printf("%dSCAN OF PARAMETER NO. %d, %s"
6861  ,fNewpag,ipar,(const char*)fCpnam[ipar-1]);
6862  mnplot(fXpt, fYpt, fChpt, nxypt, fNpagwd, fNpagln);
6863  goto L800;
6864 L700:
6865  Printf(" REQUESTED RANGE OUTSIDE LIMITS FOR PARAMETER %d",ipar);
6866 L800:
6867  if (iparwd <= 0) goto L100;
6868 //*-*- finished with all parameters
6869 L900:
6870  if (fISW[4] >= 0) mnprin(5, fAmin);
6871 } /* mnscan_ */
6872 
6873 ////////////////////////////////////////////////////////////////////////////////
6874 ///*-*-*-*Performs a rough (but global) minimization by monte carlo search*-*
6875 ///*-* ================================================================
6876 ///*-* Each time a new minimum is found, the search area is shifted
6877 ///*-* to be centered at the best value. Random points are chosen
6878 ///*-* uniformly over a hypercube determined by current step sizes.
6879 ///*-* The Metropolis algorithm accepts a worse point with probability
6880 ///*-* exp(-d/UP), where d is the degradation. Improved points
6881 ///*-* are of course always accepted. Actual steps are random
6882 ///*-* multiples of the nominal steps (DIRIN).
6883 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6884 
6886 {
6887  /* Local variables */
6888  Double_t dxdi, rnum, ftry, rnum1, rnum2, alpha;
6889  Double_t flast, bar;
6890  Int_t ipar, iext, j, ifail, iseed=0, nparx, istep, ib, mxfail, mxstep;
6891 
6892  mxfail = Int_t(fWord7[0]);
6893  if (mxfail <= 0) mxfail = fNpar*20 + 100;
6894  mxstep = mxfail*10;
6895  if (fAmin == fUndefi) mnamin();
6896  alpha = fWord7[1];
6897  if (alpha <= 0) alpha = 3;
6898  if (fISW[4] >= 1) {
6899  Printf(" MNSEEK: MONTE CARLO MINIMIZATION USING METROPOLIS ALGORITHM");
6900  Printf(" TO STOP AFTER %6d SUCCESSIVE FAILURES, OR %7d STEPS",mxfail,mxstep);
6901  Printf(" MAXIMUM STEP SIZE IS %9.3f ERROR BARS.",alpha);
6902  }
6903  fCstatu = "INITIAL ";
6904  if (fISW[4] >= 2) mnprin(2, fAmin);
6905  fCstatu = "UNCHANGED ";
6906  ifail = 0;
6907  rnum = 0;
6908  rnum1 = 0;
6909  rnum2 = 0;
6910  nparx = fNpar;
6911  flast = fAmin;
6912 //*-*- set up step sizes, starting values
6913  for (ipar = 1; ipar <= fNpar; ++ipar) {
6914  iext = fNexofi[ipar-1];
6915  fDirin[ipar-1] = alpha*2*fWerr[ipar-1];
6916  if (fNvarl[iext-1] > 1) {
6917 //*-*- parameter with limits
6918  mndxdi(fX[ipar-1], ipar-1, dxdi);
6919  if (dxdi == 0) dxdi = 1;
6920  fDirin[ipar-1] = alpha*2*fWerr[ipar-1] / dxdi;
6921  if (TMath::Abs(fDirin[ipar-1]) > 6.2831859999999997) {
6922  fDirin[ipar-1] = 6.2831859999999997;
6923  }
6924  }
6925  fSEEKxmid[ipar-1] = fX[ipar-1];
6926  fSEEKxbest[ipar-1] = fX[ipar-1];
6927  }
6928 //*-*- search loop
6929  for (istep = 1; istep <= mxstep; ++istep) {
6930  if (ifail >= mxfail) break;
6931  for (ipar = 1; ipar <= fNpar; ++ipar) {
6932  mnrn15(rnum1, iseed);
6933  mnrn15(rnum2, iseed);
6934  fX[ipar-1] = fSEEKxmid[ipar-1] + (rnum1 + rnum2 - 1)*.5*fDirin[ipar-1];
6935  }
6936  mninex(fX);
6937  Eval(nparx, fGin, ftry, fU, 4); ++fNfcn;
6938  if (ftry < flast) {
6939  if (ftry < fAmin) {
6940  fCstatu = "IMPROVEMNT";
6941  fAmin = ftry;
6942  for (ib = 1; ib <= fNpar; ++ib) { fSEEKxbest[ib-1] = fX[ib-1]; }
6943  ifail = 0;
6944  if (fISW[4] >= 2) mnprin(2, fAmin);
6945  }
6946  goto L300;
6947  } else {
6948  ++ifail;
6949 //*-*- Metropolis algorithm
6950  bar = (fAmin - ftry) / fUp;
6951  mnrn15(rnum, iseed);
6952  if (bar < TMath::Log(rnum)) continue;
6953  }
6954 //*-*- Accept new point, move there
6955 L300:
6956  for (j = 1; j <= fNpar; ++j) { fSEEKxmid[j-1] = fX[j-1]; }
6957  flast = ftry;
6958  }
6959 //*-*- end search loop
6960  if (fISW[4] > 1) {
6961  Printf(" MNSEEK: %5d SUCCESSIVE UNSUCCESSFUL TRIALS.",ifail);
6962  }
6963  for (ib = 1; ib <= fNpar; ++ib) { fX[ib-1] = fSEEKxbest[ib-1]; }
6964  mninex(fX);
6965  if (fISW[4] >= 1) mnprin(2, fAmin);
6966  if (fISW[4] == 0) mnprin(0, fAmin);
6967 } /* mnseek_ */
6968 
6969 ////////////////////////////////////////////////////////////////////////////////
6970 ///*-*-*-*-*Interprets the commands that start with SET and SHOW*-*-*-*-*-*-*
6971 ///*-* ====================================================
6972 ///*-* Called from MNEXCM
6973 ///*-* file characteristics for SET INPUT
6974 ///*-* 'SET ' or 'SHOW', 'ON ' or 'OFF', 'SUPPRESSED' or 'REPORTED '
6975 ///*-* explanation of print level numbers -1:3 and strategies 0:2
6976 ///*-* identification of debug options
6977 ///*-* things that can be set or shown
6978 ///*-* options not intended for normal users
6979 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
6980 
6982 {
6983  /* Initialized data */
6984 
6985  static const char *cname[30] = {
6986  "FCN value ",
6987  "PARameters",
6988  "LIMits ",
6989  "COVariance",
6990  "CORrelatio",
6991  "PRInt levl",
6992  "NOGradient",
6993  "GRAdient ",
6994  "ERRor def ",
6995  "INPut file",
6996  "WIDth page",
6997  "LINes page",
6998  "NOWarnings",
6999  "WARnings ",
7000  "RANdom gen",
7001  "TITle ",
7002  "STRategy ",
7003  "EIGenvalue",
7004  "PAGe throw",
7005  "MINos errs",
7006  "EPSmachine",
7007  "OUTputfile",
7008  "BATch ",
7009  "INTeractiv",
7010  "VERsion ",
7011  "reserve ",
7012  "NODebug ",
7013  "DEBug ",
7014  "SHOw ",
7015  "SET "};
7016 
7017  static Int_t nname = 25;
7018  static Int_t nntot = 30;
7019  static TString cprlev[5] = {
7020  "-1: NO OUTPUT EXCEPT FROM SHOW ",
7021  " 0: REDUCED OUTPUT ",
7022  " 1: NORMAL OUTPUT ",
7023  " 2: EXTRA OUTPUT FOR PROBLEM CASES",
7024  " 3: MAXIMUM OUTPUT "};
7025 
7026  static TString cstrat[3] = {
7027  " 0: MINIMIZE THE NUMBER OF CALLS TO FUNCTION",
7028  " 1: TRY TO BALANCE SPEED AGAINST RELIABILITY",
7029  " 2: MAKE SURE MINIMUM TRUE, ERRORS CORRECT "};
7030 
7031  static TString cdbopt[7] = {
7032  "REPORT ALL EXCEPTIONAL CONDITIONS ",
7033  "MNLINE: LINE SEARCH MINIMIZATION ",
7034  "MNDERI: FIRST DERIVATIVE CALCULATIONS ",
7035  "MNHESS: SECOND DERIVATIVE CALCULATIONS ",
7036  "MNMIGR: COVARIANCE MATRIX UPDATES ",
7037  "MNHES1: FIRST DERIVATIVE UNCERTAINTIES ",
7038  "MNCONT: MNCONTOUR PLOT (MNCROS SEARCH) "};
7039 
7040  /* System generated locals */
7041  //Int_t f_inqu();
7042 
7043  /* Local variables */
7044  Double_t val;
7045  Int_t iset, iprm, i, jseed, kname, iseed, iunit, id, ii, kk;
7046  Int_t ikseed, idbopt, igrain=0, iswsav, isw2;
7047  TString cfname, cmode, ckind, cwarn, copt, ctemp, ctemp2;
7048  Bool_t lname=kFALSE;
7049 
7050  for (i = 1; i <= nntot; ++i) {
7051  ctemp = cname[i-1];
7052  ckind = ctemp(0,3);
7053  ctemp2 = fCword(4,6);
7054  if (strstr(ctemp2.Data(),ckind.Data())) goto L5;
7055  }
7056  i = 0;
7057 L5:
7058  kname = i;
7059 
7060 //*-*- Command could be SET xxx, SHOW xxx, HELP SET or HELP SHOW
7061  ctemp2 = fCword(0,3);
7062  if ( ctemp2.Contains("HEL")) goto L2000;
7063  if ( ctemp2.Contains("SHO")) goto L1000;
7064  if (!ctemp2.Contains("SET")) goto L1900;
7065 //*-*- ---
7066  ckind = "SET ";
7067 //*-*- . . . . . . . . . . set unknown
7068  if (kname <= 0) goto L1900;
7069 //*-*- . . . . . . . . . . set known
7070  switch ((int)kname) {
7071  case 1: goto L3000;
7072  case 2: goto L20;
7073  case 3: goto L30;
7074  case 4: goto L40;
7075  case 5: goto L3000;
7076  case 6: goto L60;
7077  case 7: goto L70;
7078  case 8: goto L80;
7079  case 9: goto L90;
7080  case 10: goto L100;
7081  case 11: goto L110;
7082  case 12: goto L120;
7083  case 13: goto L130;
7084  case 14: goto L140;
7085  case 15: goto L150;
7086  case 16: goto L160;
7087  case 17: goto L170;
7088  case 18: goto L3000;
7089  case 19: goto L190;
7090  case 20: goto L3000;
7091  case 21: goto L210;
7092  case 22: goto L220;
7093  case 23: goto L230;
7094  case 24: goto L240;
7095  case 25: goto L3000;
7096  case 26: goto L1900;
7097  case 27: goto L270;
7098  case 28: goto L280;
7099  case 29: goto L290;
7100  case 30: goto L300;
7101  }
7102 
7103 //*-*- . . . . . . . . . . set param
7104 L20:
7105  iprm = Int_t(fWord7[0]);
7106  if (iprm > fNu) goto L25;
7107  if (iprm <= 0) goto L25;
7108  if (fNvarl[iprm-1] < 0) goto L25;
7109  fU[iprm-1] = fWord7[1];
7110  mnexin(fX);
7111  isw2 = fISW[1];
7112  mnrset(1);
7113 //*-*- Keep approximate covariance matrix, even if new param value
7114  fISW[1] = TMath::Min(isw2,1);
7115  fCfrom = "SET PARM";
7116  fNfcnfr = fNfcn;
7117  fCstatu = "NEW VALUES";
7118  return;
7119 L25:
7120  Printf(" UNDEFINED PARAMETER NUMBER. IGNORED.");
7121  return;
7122 //*-*- . . . . . . . . . . set limits
7123 L30:
7124  mnlims();
7125  return;
7126 //*-*- . . . . . . . . . . set covar
7127 L40:
7128 //*-* this command must be handled by MNREAD, and is not Fortran-callable
7129  goto L3000;
7130 //*-*- . . . . . . . . . . set print
7131 L60:
7132  fISW[4] = Int_t(fWord7[0]);
7133  return;
7134 //*-*- . . . . . . . . . . set nograd
7135 L70:
7136  fISW[2] = 0;
7137  return;
7138 //*-*- . . . . . . . . . . set grad
7139 L80:
7140  mngrad();
7141  return;
7142 //*-*- . . . . . . . . . . set errdef
7143 L90:
7144  if (fWord7[0] == fUp) return;
7145  if (fWord7[0] <= 0) {
7146  if (fUp == fUpdflt) return;
7147  fUp = fUpdflt;
7148  } else {
7149  fUp = fWord7[0];
7150  }
7151  for (i = 1; i <= fNpar; ++i) {
7152  fErn[i-1] = 0;
7153  fErp[i-1] = 0;
7154  }
7155  mnwerr();
7156  return;
7157 //*-*- . . . . . . . . . . set input
7158 //*-* This command must be handled by MNREAD. If it gets this far,
7159 //*-*- it is illegal.
7160 L100:
7161  goto L3000;
7162 //*-*- . . . . . . . . . . set width
7163 L110:
7164  fNpagwd = Int_t(fWord7[0]);
7165  fNpagwd = TMath::Max(fNpagwd,50);
7166  return;
7167 
7168 L120:
7169  fNpagln = Int_t(fWord7[0]);
7170  return;
7171 //*-*- . . . . . . . . . . set nowarn
7172 
7173 L130:
7174  fLwarn = kFALSE;
7175  return;
7176 //*-*- . . . . . . . . . . set warn
7177 L140:
7178  fLwarn = kTRUE;
7179  mnwarn("W", "SHO", "SHO");
7180  return;
7181 //*-*- . . . . . . . . . . set random
7182 L150:
7183  jseed = Int_t(fWord7[0]);
7184  val = 3;
7185  mnrn15(val, jseed);
7186  if (fISW[4] > 0) {
7187  Printf(" MINUIT RANDOM NUMBER SEED SET TO %d",jseed);
7188  }
7189  return;
7190 //*-*- . . . . . . . . . . set title
7191 L160:
7192 //*-* this command must be handled by MNREAD, and is not Fortran-callable
7193  goto L3000;
7194 //*-*- . . . . . . . . . set strategy
7195 L170:
7196  fIstrat = Int_t(fWord7[0]);
7197  fIstrat = TMath::Max(fIstrat,0);
7198  fIstrat = TMath::Min(fIstrat,2);
7199  if (fISW[4] > 0) goto L1172;
7200  return;
7201 //*-*- . . . . . . . . . set page throw
7202 L190:
7203  fNewpag = Int_t(fWord7[0]);
7204  goto L1190;
7205 //*-*- . . . . . . . . . . set epsmac
7206 L210:
7207  if (fWord7[0] > 0 && fWord7[0] < .1) {
7208  fEpsmac = fWord7[0];
7209  }
7211  goto L1210;
7212 //*-*- . . . . . . . . . . set outputfile
7213 L220:
7214  iunit = Int_t(fWord7[0]);
7215  fIsyswr = iunit;
7216  fIstkwr[0] = iunit;
7217  if (fISW[4] >= 0) goto L1220;
7218  return;
7219 //*-*- . . . . . . . . . . set batch
7220 L230:
7221  fISW[5] = 0;
7222  if (fISW[4] >= 0) goto L1100;
7223  return;
7224 //*-*- . . . . . . . . . . set interactive
7225 L240:
7226  fISW[5] = 1;
7227  if (fISW[4] >= 0) goto L1100;
7228  return;
7229 //*-*- . . . . . . . . . . set nodebug
7230 L270:
7231  iset = 0;
7232  goto L281;
7233 //*-*- . . . . . . . . . . set debug
7234 L280:
7235  iset = 1;
7236 L281:
7237  idbopt = Int_t(fWord7[0]);
7238  if (idbopt > 6) goto L288;
7239  if (idbopt >= 0) {
7240  fIdbg[idbopt] = iset;
7241  if (iset == 1) fIdbg[0] = 1;
7242  } else {
7243 //*-*- SET DEBUG -1 sets all debug options
7244  for (id = 0; id <= 6; ++id) { fIdbg[id] = iset; }
7245  }
7246  fLrepor = fIdbg[0] >= 1;
7247  mnwarn("D", "SHO", "SHO");
7248  return;
7249 L288:
7250  Printf(" UNKNOWN DEBUG OPTION %d REQUESTED. IGNORED",idbopt);
7251  return;
7252 //*-*- . . . . . . . . . . set show
7253 L290:
7254 //*-*- . . . . . . . . . . set set
7255 L300:
7256  goto L3000;
7257 //*-*- -----------------------------------------------------
7258 L1000:
7259 //*-*- at this point, CWORD must be 'SHOW'
7260  ckind = "SHOW";
7261  if (kname <= 0) goto L1900;
7262 
7263  switch ((int)kname) {
7264  case 1: goto L1010;
7265  case 2: goto L1020;
7266  case 3: goto L1030;
7267  case 4: goto L1040;
7268  case 5: goto L1050;
7269  case 6: goto L1060;
7270  case 7: goto L1070;
7271  case 8: goto L1070;
7272  case 9: goto L1090;
7273  case 10: goto L1100;
7274  case 11: goto L1110;
7275  case 12: goto L1120;
7276  case 13: goto L1130;
7277  case 14: goto L1130;
7278  case 15: goto L1150;
7279  case 16: goto L1160;
7280  case 17: goto L1170;
7281  case 18: goto L1180;
7282  case 19: goto L1190;
7283  case 20: goto L1200;
7284  case 21: goto L1210;
7285  case 22: goto L1220;
7286  case 23: goto L1100;
7287  case 24: goto L1100;
7288  case 25: goto L1250;
7289  case 26: goto L1900;
7290  case 27: goto L1270;
7291  case 28: goto L1270;
7292  case 29: goto L1290;
7293  case 30: goto L1300;
7294  }
7295 
7296 //*-*- . . . . . . . . . . show fcn
7297 L1010:
7298  if (fAmin == fUndefi) mnamin();
7299  mnprin(0, fAmin);
7300  return;
7301 //*-*- . . . . . . . . . . show param
7302 L1020:
7303  if (fAmin == fUndefi) mnamin();
7304  mnprin(5, fAmin);
7305  return;
7306 //*-*- . . . . . . . . . . show limits
7307 L1030:
7308  if (fAmin == fUndefi) mnamin();
7309  mnprin(1, fAmin);
7310  return;
7311 //*-*- . . . . . . . . . . show covar
7312 L1040:
7313  mnmatu(1);
7314  return;
7315 //*-*- . . . . . . . . . . show corre
7316 L1050:
7317  mnmatu(0);
7318  return;
7319 //*-*- . . . . . . . . . . show print
7320 L1060:
7321  if (fISW[4] < -1) fISW[4] = -1;
7322  if (fISW[4] > 3) fISW[4] = 3;
7323  Printf(" ALLOWED PRINT LEVELS ARE:");
7324  Printf(" %s",cprlev[0].Data());
7325  Printf(" %s",cprlev[1].Data());
7326  Printf(" %s",cprlev[2].Data());
7327  Printf(" %s",cprlev[3].Data());
7328  Printf(" %s",cprlev[4].Data());
7329  Printf(" CURRENT PRINTOUT LEVEL IS %s",cprlev[fISW[4]+1].Data());
7330  return;
7331 //*-*- . . . . . . . show nograd, grad
7332 L1070:
7333  if (fISW[2] <= 0) {
7334  Printf(" NOGRAD IS SET. DERIVATIVES NOT COMPUTED IN FCN.");
7335  } else {
7336  Printf(" GRAD IS SET. USER COMPUTES DERIVATIVES IN FCN.");
7337  }
7338  return;
7339 //*-*- . . . . . . . . . . show errdef
7340 L1090:
7341  Printf(" ERRORS CORRESPOND TO FUNCTION CHANGE OF %g",fUp);
7342  return;
7343 //*-*- . . . . . . . . . . show input,
7344 //*-*- batch, or interactive
7345 L1100:
7346 // ioin__1.inerr = 0;
7347 // ioin__1.inunit = fIsysrd;
7348 // ioin__1.infile = 0;
7349 // ioin__1.inex = 0;
7350 // ioin__1.inopen = 0;
7351 // ioin__1.innum = 0;
7352 // ioin__1.innamed = &lname;
7353 // ioin__1.innamlen = 64;
7354 // ioin__1.inname = cfname;
7355 // ioin__1.inacc = 0;
7356 // ioin__1.inseq = 0;
7357 // ioin__1.indir = 0;
7358 // ioin__1.infmt = 0;
7359 // ioin__1.inform = 0;
7360 // ioin__1.inunf = 0;
7361 // ioin__1.inrecl = 0;
7362 // ioin__1.innrec = 0;
7363 // ioin__1.inblank = 0;
7364 // f_inqu(&ioin__1);
7365  cmode = "BATCH MODE ";
7366  if (fISW[5] == 1) cmode = "INTERACTIVE MODE";
7367  if (! lname) cfname = "unknown";
7368  Printf(" INPUT NOW BEING READ IN %s FROM UNIT NO. %d FILENAME: %s"
7369  ,(const char*)cmode,fIsysrd,(const char*)cfname);
7370  return;
7371 //*-*- . . . . . . . . . . show width
7372 L1110:
7373  Printf(" PAGE WIDTH IS SET TO %d COLUMNS",fNpagwd);
7374  return;
7375 //*-*- . . . . . . . . . . show lines
7376 L1120:
7377  Printf(" PAGE LENGTH IS SET TO %d LINES",fNpagln);
7378  return;
7379 //*-*- . . . . . . .show nowarn, warn
7380 L1130:
7381  cwarn = "SUPPRESSED";
7382  if (fLwarn) cwarn = "REPORTED ";
7383  Printf("%s",(const char*)cwarn);
7384  if (! fLwarn) mnwarn("W", "SHO", "SHO");
7385  return;
7386 //*-*- . . . . . . . . . . show random
7387 L1150:
7388  val = 0;
7389  mnrn15(val, igrain);
7390  ikseed = igrain;
7391  Printf(" MINUIT RNDM SEED IS CURRENTLY=%d",ikseed);
7392  val = 3;
7393  iseed = ikseed;
7394  mnrn15(val, iseed);
7395  return;
7396 //*-*- . . . . . . . . . show title
7397 L1160:
7398  Printf(" TITLE OF CURRENT TASK IS:%s",(const char*)fCtitl);
7399  return;
7400 //*-*- . . . . . . . show strategy
7401 L1170:
7402  Printf(" ALLOWED STRATEGIES ARE:");
7403  Printf(" %s",cstrat[0].Data());
7404  Printf(" %s",cstrat[1].Data());
7405  Printf(" %s",cstrat[2].Data());
7406 L1172:
7407  Printf(" NOW USING STRATEGY %s",(const char*)cstrat[fIstrat]);
7408  return;
7409 //*-*- . . . . . show eigenvalues
7410 L1180:
7411  iswsav = fISW[4];
7412  fISW[4] = 3;
7413  if (fISW[1] < 1) {
7414  Printf("%s",(const char*)fCovmes[0]);
7415  } else {
7416  mnpsdf();
7417  }
7418  fISW[4] = iswsav;
7419  return;
7420 //*-*- . . . . . show page throw
7421 L1190:
7422  Printf(" PAGE THROW CARRIAGE CONTROL = %d",fNewpag);
7423  if (fNewpag == 0) {
7424  Printf(" NO PAGE THROWS IN MINUIT OUTPUT");
7425  }
7426  return;
7427 //*-*- . . . . . . show minos errors
7428 L1200:
7429  for (ii = 1; ii <= fNpar; ++ii) {
7430  if (fErp[ii-1] > 0 || fErn[ii-1] < 0) goto L1204;
7431  }
7432  Printf(" THERE ARE NO MINOS ERRORS CURRENTLY VALID.");
7433  return;
7434 L1204:
7435  mnprin(4, fAmin);
7436  return;
7437 //*-*- . . . . . . . . . show epsmac
7438 L1210:
7439  Printf(" FLOATING-POINT NUMBERS ASSUMED ACCURATE TO %g",fEpsmac);
7440  return;
7441 //*-*- . . . . . . show outputfiles
7442 L1220:
7443  Printf(" MINUIT PRIMARY OUTPUT TO UNIT %d",fIsyswr);
7444  return;
7445 //*-*- . . . . . . show version
7446 L1250:
7447  Printf(" THIS IS MINUIT VERSION:%s",(const char*)fCvrsn);
7448  return;
7449 //*-*- . . . . . . show nodebug, debug
7450 L1270:
7451  for (id = 0; id <= 6; ++id) {
7452  copt = "OFF";
7453  if (fIdbg[id] >= 1) copt = "ON ";
7454  Printf(" DEBUG OPTION %3d IS %3s :%s"
7455  ,id,(const char*)copt,(const char*)cdbopt[id]);
7456  }
7457  if (! fLrepor) mnwarn("D", "SHO", "SHO");
7458  return;
7459 //*-*- . . . . . . . . . . show show
7460 L1290:
7461  ckind = "SHOW";
7462  goto L2100;
7463 //*-*- . . . . . . . . . . show set
7464 L1300:
7465  ckind = "SET ";
7466  goto L2100;
7467 //*-*- -----------------------------------------------------
7468 //*-*- UNKNOWN COMMAND
7469 L1900:
7470  Printf(" THE COMMAND:%10s IS UNKNOWN.",(const char*)fCword);
7471  goto L2100;
7472 //*-*- -----------------------------------------------------
7473 //*-*- HELP SHOW, HELP SET, SHOW SET, or SHOW SHOW
7474 L2000:
7475  ckind = "SET ";
7476  ctemp2 = fCword(3,7);
7477  if (strcmp(ctemp2.Data(), "SHO")) ckind = "SHOW";
7478 L2100:
7479  Printf(" THE FORMAT OF THE %4s COMMAND IS:",(const char*)ckind);
7480  Printf(" %s xxx [numerical arguments if any]",(const char*)ckind);
7481  Printf(" WHERE xxx MAY BE ONE OF THE FOLLOWING:");
7482  for (kk = 1; kk <= nname; ++kk) {
7483  Printf(" %s",cname[kk-1]);
7484  }
7485  return;
7486 //*-*- -----------------------------------------------------
7487 //*-*- ILLEGAL COMMAND
7488 L3000:
7489  Printf(" ABOVE COMMAND IS ILLEGAL. IGNORED");
7490 
7491 } /* mnset_ */
7492 
7493 ////////////////////////////////////////////////////////////////////////////////
7494 ///*-*-*-*-*Minimization using the simplex method of Nelder and Mead*-*-*-*-*
7495 ///*-* ========================================================
7496 ///*-* Performs a minimization using the simplex method of Nelder
7497 ///*-* and Mead (ref. -- Comp. J. 7,308 (1965)).
7498 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7499 
7501 {
7502  /* Initialized data */
7503 
7504  static Double_t alpha = 1;
7505  static Double_t beta = .5;
7506  static Double_t gamma = 2;
7507  static Double_t rhomin = 4;
7508  static Double_t rhomax = 8;
7509 
7510  /* Local variables */
7511  Double_t dmin_, dxdi, yrho, f, ynpp1, aming, ypbar;
7512  Double_t bestx, ystar, y1, y2, ystst, pb, wg;
7513  Double_t absmin, rho, sig2, rho1, rho2;
7514  Int_t npfn, i, j, k, jhold, ncycl, nparx;
7515  Int_t nparp1, kg, jh, nf, jl, ns;
7516 
7517  if (fNpar <= 0) return;
7518  if (fAmin == fUndefi) mnamin();
7519  fCfrom = "SIMPLEX ";
7520  fNfcnfr = fNfcn;
7521  fCstatu = "UNCHANGED ";
7522  npfn = fNfcn;
7523  nparp1 = fNpar + 1;
7524  nparx = fNpar;
7525  rho1 = alpha + 1;
7526  rho2 = rho1 + alpha*gamma;
7527  wg = 1 / Double_t(fNpar);
7528  if (fISW[4] >= 0) {
7529  Printf(" START SIMPLEX MINIMIZATION. CONVERGENCE WHEN EDM .LT. %g",fEpsi);
7530  }
7531  for (i = 1; i <= fNpar; ++i) {
7532  fDirin[i-1] = fWerr[i-1];
7533  mndxdi(fX[i-1], i-1, dxdi);
7534  if (dxdi != 0) fDirin[i-1] = fWerr[i-1] / dxdi;
7535  dmin_ = fEpsma2*TMath::Abs(fX[i-1]);
7536  if (fDirin[i-1] < dmin_) fDirin[i-1] = dmin_;
7537  }
7538 //*-* ** choose the initial simplex using single-parameter searches
7539 L1:
7540  ynpp1 = fAmin;
7541  jl = nparp1;
7542  fSIMPy[nparp1-1] = fAmin;
7543  absmin = fAmin;
7544  for (i = 1; i <= fNpar; ++i) {
7545  aming = fAmin;
7546  fPbar[i-1] = fX[i-1];
7547  bestx = fX[i-1];
7548  kg = 0;
7549  ns = 0;
7550  nf = 0;
7551 L4:
7552  fX[i-1] = bestx + fDirin[i-1];
7553  mninex(fX);
7554  Eval(nparx, fGin, f, fU, 4); ++fNfcn;
7555  if (f <= aming) goto L6;
7556 //*-*- failure
7557  if (kg == 1) goto L8;
7558  kg = -1;
7559  ++nf;
7560  fDirin[i-1] *= -.4;
7561  if (nf < 3) goto L4;
7562  ns = 6;
7563 //*-*- success
7564 L6:
7565  bestx = fX[i-1];
7566  fDirin[i-1] *= 3;
7567  aming = f;
7568  fCstatu = "PROGRESS ";
7569  kg = 1;
7570  ++ns;
7571  if (ns < 6) goto L4;
7572 //*-*- local minimum found in ith direction
7573 L8:
7574  fSIMPy[i-1] = aming;
7575  if (aming < absmin) jl = i;
7576  if (aming < absmin) absmin = aming;
7577  fX[i-1] = bestx;
7578  for (k = 1; k <= fNpar; ++k) { fP[k + i*fMaxpar - fMaxpar-1] = fX[k-1]; }
7579  }
7580  jh = nparp1;
7581  fAmin = fSIMPy[jl-1];
7582  mnrazz(ynpp1, fPbar, fSIMPy, jh, jl);
7583  for (i = 1; i <= fNpar; ++i) { fX[i-1] = fP[i + jl*fMaxpar - fMaxpar-1]; }
7584  mninex(fX);
7585  fCstatu = "PROGRESS ";
7586  if (fISW[4] >= 1) mnprin(5, fAmin);
7587  fEDM = fBigedm;
7588  sig2 = fEDM;
7589  ncycl = 0;
7590 //*-*- . . . . . start main loop
7591 L50:
7592  if (sig2 < fEpsi && fEDM < fEpsi) goto L76;
7593  sig2 = fEDM;
7594  if (fNfcn - npfn > fNfcnmx) goto L78;
7595 //*-*- calculate new point * by reflection
7596  for (i = 1; i <= fNpar; ++i) {
7597  pb = 0;
7598  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7599  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7600  fPstar[i-1] = (alpha + 1)*fPbar[i-1] - alpha*fP[i + jh*fMaxpar - fMaxpar-1];
7601  }
7602  mninex(fPstar);
7603  Eval(nparx, fGin, ystar, fU, 4); ++fNfcn;
7604  if (ystar >= fAmin) goto L70;
7605 //*-*- point * better than jl, calculate new point **
7606  for (i = 1; i <= fNpar; ++i) {
7607  fPstst[i-1] = gamma*fPstar[i-1] + (1 - gamma)*fPbar[i-1];
7608  }
7609  mninex(fPstst);
7610  Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7611 //*-*- try a parabola through ph, pstar, pstst. min = prho
7612  y1 = (ystar - fSIMPy[jh-1])*rho2;
7613  y2 = (ystst - fSIMPy[jh-1])*rho1;
7614  rho = (rho2*y1 - rho1*y2)*.5 / (y1 - y2);
7615  if (rho < rhomin) goto L66;
7616  if (rho > rhomax) rho = rhomax;
7617  for (i = 1; i <= fNpar; ++i) {
7618  fPrho[i-1] = rho*fPbar[i-1] + (1 - rho)*fP[i + jh*fMaxpar - fMaxpar-1];
7619  }
7620  mninex(fPrho);
7621  Eval(nparx, fGin, yrho, fU, 4); ++fNfcn;
7622  if (yrho < fSIMPy[jl-1] && yrho < ystst) goto L65;
7623  if (ystst < fSIMPy[jl-1]) goto L67;
7624  if (yrho > fSIMPy[jl-1]) goto L66;
7625 //*-*- accept minimum point of parabola, PRHO
7626 L65:
7627  mnrazz(yrho, fPrho, fSIMPy, jh, jl);
7628  goto L68;
7629 L66:
7630  if (ystst < fSIMPy[jl-1]) goto L67;
7631  mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7632  goto L68;
7633 L67:
7634  mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7635 L68:
7636  ++ncycl;
7637  if (fISW[4] < 2) goto L50;
7638  if (fISW[4] >= 3 || ncycl % 10 == 0) {
7639  mnprin(5, fAmin);
7640  }
7641  goto L50;
7642 //*-*- point * is not as good as jl
7643 L70:
7644  if (ystar >= fSIMPy[jh-1]) goto L73;
7645  jhold = jh;
7646  mnrazz(ystar, fPstar, fSIMPy, jh, jl);
7647  if (jhold != jh) goto L50;
7648 //*-*- calculate new point **
7649 L73:
7650  for (i = 1; i <= fNpar; ++i) {
7651  fPstst[i-1] = beta*fP[i + jh*fMaxpar - fMaxpar-1] + (1 - beta)*fPbar[i-1];
7652  }
7653  mninex(fPstst);
7654  Eval(nparx, fGin, ystst, fU, 4); ++fNfcn;
7655  if (ystst > fSIMPy[jh-1]) goto L1;
7656 //*-*- point ** is better than jh
7657  if (ystst < fAmin) goto L67;
7658  mnrazz(ystst, fPstst, fSIMPy, jh, jl);
7659  goto L50;
7660 //*-*- . . . . . . end main loop
7661 L76:
7662  if (fISW[4] >= 0) {
7663  Printf(" SIMPLEX MINIMIZATION HAS CONVERGED.");
7664  }
7665  fISW[3] = 1;
7666  goto L80;
7667 L78:
7668  if (fISW[4] >= 0) {
7669  Printf(" SIMPLEX TERMINATES WITHOUT CONVERGENCE.");
7670  }
7671  fCstatu = "CALL LIMIT";
7672  fISW[3] = -1;
7673  fISW[0] = 1;
7674 L80:
7675  for (i = 1; i <= fNpar; ++i) {
7676  pb = 0;
7677  for (j = 1; j <= nparp1; ++j) { pb += wg*fP[i + j*fMaxpar - fMaxpar-1]; }
7678  fPbar[i-1] = pb - wg*fP[i + jh*fMaxpar - fMaxpar-1];
7679  }
7680  mninex(fPbar);
7681  Eval(nparx, fGin, ypbar, fU, 4); ++fNfcn;
7682  if (ypbar < fAmin) mnrazz(ypbar, fPbar, fSIMPy, jh, jl);
7683  mninex(fX);
7684  if (fNfcnmx + npfn - fNfcn < fNpar*3) goto L90;
7685  if (fEDM > fEpsi*2) goto L1;
7686 L90:
7687  if (fISW[4] >= 0) mnprin(5, fAmin);
7688 } /* mnsimp_ */
7689 
7690 ////////////////////////////////////////////////////////////////////////////////
7691 ///*-*-*-*-*Returns concerning the current status of the minimization*-*-*-*-*
7692 ///*-* =========================================================
7693 ///*-* User-called
7694 ///*-* Namely, it returns:
7695 ///*-* FMIN: the best function value found so far
7696 ///*-* FEDM: the estimated vertical distance remaining to minimum
7697 ///*-* ERRDEF: the value of UP defining parameter uncertainties
7698 ///*-* NPARI: the number of currently variable parameters
7699 ///*-* NPARX: the highest (external) parameter number defined by user
7700 ///*-* ISTAT: a status integer indicating how good is the covariance
7701 ///*-* matrix: 0= not calculated at all
7702 ///*-* 1= approximation only, not accurate
7703 ///*-* 2= full matrix, but forced positive-definite
7704 ///*-* 3= full accurate covariance matrix
7705 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7706 
7707 void TMinuit::mnstat(Double_t &fmin, Double_t &fedm, Double_t &errdef, Int_t &npari, Int_t &nparx, Int_t &istat)
7708 {
7709  fmin = fAmin;
7710  fedm = fEDM;
7711  errdef = fUp;
7712  npari = fNpar;
7713  nparx = fNu;
7714  istat = fISW[1];
7715  if (fEDM == fBigedm) fedm = fUp;
7716  if (fAmin == fUndefi) {
7717  fmin = 0;
7718  fedm = fUp;
7719  istat = 0;
7720  }
7721 } /* mnstat_ */
7722 
7723 ////////////////////////////////////////////////////////////////////////////////
7724 ///*-*-*-*-*-*-*-*To find the machine precision*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7725 ///*-* =============================
7726 ///*-* Compares its argument with the value 1.0, and returns
7727 ///*-* the value .TRUE. if they are equal. To find EPSMAC
7728 ///*-* safely by foiling the Fortran optimizer
7729 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7730 
7731 void TMinuit::mntiny(volatile Double_t epsp1, Double_t &epsbak)
7732 {
7733  epsbak = epsp1 - 1;
7734 } /* mntiny_ */
7735 
7736 ////////////////////////////////////////////////////////////////////////////////
7737 ///*-*-*-*-*-*Returns .TRUE. if CFNAME contains unprintable characters*-*-*-*
7738 ///*-* ========================================================
7739 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7740 
7742 {
7743  Int_t i, l, ic;
7744  Bool_t ret_val;
7745  static TString cpt = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./;:[]$%*_!@#&+()";
7746 
7747  ret_val = kFALSE;
7748  l = strlen((const char*)cfname);
7749  for (i = 1; i <= l; ++i) {
7750  for (ic = 1; ic <= 80; ++ic) {
7751  if (cfname[i-1] == cpt[ic-1]) goto L100;
7752  }
7753  return kTRUE;
7754 L100:
7755  ;
7756  }
7757  return ret_val;
7758 } /* mnunpt_ */
7759 
7760 ////////////////////////////////////////////////////////////////////////////////
7761 ///*-*-*-*-*-*-*-*-*-*-*-*Inverts a symmetric matrix*-*-*-*-*-*-*-*-*-*-*-*-*
7762 ///*-* ==========================
7763 ///*-* inverts a symmetric matrix. matrix is first scaled to
7764 ///*-* have all ones on the diagonal (equivalent to change of units)
7765 ///*-* but no pivoting is done since matrix is positive-definite.
7766 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7767 
7769 {
7770  /* System generated locals */
7771  Int_t a_offset;
7772 
7773  /* Local variables */
7774  Double_t si;
7775  Int_t i, j, k, kp1, km1;
7776 
7777  /* Parameter adjustments */
7778  a_offset = l + 1;
7779  a -= a_offset;
7780 
7781  /* Function Body */
7782  ifail = 0;
7783  if (n < 1) goto L100;
7784  if (n > fMaxint) goto L100;
7785 //*-*- scale matrix by sqrt of diag elements
7786  for (i = 1; i <= n; ++i) {
7787  si = a[i + i*l];
7788  if (si <= 0) goto L100;
7789  fVERTs[i-1] = 1 / TMath::Sqrt(si);
7790  }
7791  for (i = 1; i <= n; ++i) {
7792  for (j = 1; j <= n; ++j) {
7793  a[i + j*l] = a[i + j*l]*fVERTs[i-1]*fVERTs[j-1];
7794  }
7795  }
7796 //*-*- . . . start main loop . . . .
7797  for (i = 1; i <= n; ++i) {
7798  k = i;
7799 //*-*- preparation for elimination step1
7800  if (a[k + k*l] != 0) fVERTq[k-1] = 1 / a[k + k*l];
7801  else goto L100;
7802  fVERTpp[k-1] = 1;
7803  a[k + k*l] = 0;
7804  kp1 = k + 1;
7805  km1 = k - 1;
7806  if (km1 < 0) goto L100;
7807  else if (km1 == 0) goto L50;
7808  else goto L40;
7809 L40:
7810  for (j = 1; j <= km1; ++j) {
7811  fVERTpp[j-1] = a[j + k*l];
7812  fVERTq[j-1] = a[j + k*l]*fVERTq[k-1];
7813  a[j + k*l] = 0;
7814  }
7815 L50:
7816  if (k - n < 0) goto L51;
7817  else if (k - n == 0) goto L60;
7818  else goto L100;
7819 L51:
7820  for (j = kp1; j <= n; ++j) {
7821  fVERTpp[j-1] = a[k + j*l];
7822  fVERTq[j-1] = -a[k + j*l]*fVERTq[k-1];
7823  a[k + j*l] = 0;
7824  }
7825 //*-*- elimination proper
7826 L60:
7827  for (j = 1; j <= n; ++j) {
7828  for (k = j; k <= n; ++k) { a[j + k*l] += fVERTpp[j-1]*fVERTq[k-1]; }
7829  }
7830  }
7831 //*-*- elements of left diagonal and unscaling
7832  for (j = 1; j <= n; ++j) {
7833  for (k = 1; k <= j; ++k) {
7834  a[k + j*l] = a[k + j*l]*fVERTs[k-1]*fVERTs[j-1];
7835  a[j + k*l] = a[k + j*l];
7836  }
7837  }
7838  return;
7839 //*-*- failure return
7840 L100:
7841  ifail = 1;
7842 } /* mnvert_ */
7843 
7844 ////////////////////////////////////////////////////////////////////////////////
7845 ///*-*-*-*-*-*-*-*-*-*-*-*Prints Warning messages*-*-*-*-*-*-*-*-*-*-*-*-*-*
7846 ///*-* =======================
7847 ///*-* If COPT='W', CMES is a WARning message from CORG.
7848 ///*-* If COPT='D', CMES is a DEBug message from CORG.
7849 ///*-* If SET WARnings is in effect (the default), this routine
7850 ///*-* prints the warning message CMES coming from CORG.
7851 ///*-* If SET NOWarnings is in effect, the warning message is
7852 ///*-* stored in a circular buffer of length kMAXMES.
7853 ///*-* If called with CORG=CMES='SHO', it prints the messages in
7854 ///*-* the circular buffer, FIFO, and empties the buffer.
7855 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7856 
7857 void TMinuit::mnwarn(const char *copt1, const char *corg1, const char *cmes1)
7858 {
7859  TString copt = copt1;
7860  TString corg = corg1;
7861  TString cmes = cmes1;
7862 
7863  const Int_t kMAXMES = 10;
7864  Int_t ityp, i, ic, nm;
7865  TString englsh, ctyp;
7866 
7867  if (corg(0,3) != "SHO" || cmes(0,3) != "SHO") {
7868 
7869 //*-*- Either print warning or put in buffer
7870  if (copt == "W") {
7871  ityp = 1;
7872  if (fLwarn) {
7873  Printf(" MINUIT WARNING IN %s",(const char*)corg);
7874  Printf(" ============== %s",(const char*)cmes);
7875  return;
7876  }
7877  } else {
7878  ityp = 2;
7879  if (fLrepor) {
7880  Printf(" MINUIT DEBUG FOR %s",(const char*)corg);
7881  Printf(" =============== %s ",(const char*)cmes);
7882  return;
7883  }
7884  }
7885 //*-*- if appropriate flag is off, fill circular buffer
7886  if (fNwrmes[ityp-1] == 0) fIcirc[ityp-1] = 0;
7887  ++fNwrmes[ityp-1];
7888  ++fIcirc[ityp-1];
7889  if (fIcirc[ityp-1] > 10) fIcirc[ityp-1] = 1;
7890  ic = fIcirc[ityp-1];
7891  fOrigin[ic] = corg;
7892  fWarmes[ic] = cmes;
7893  fNfcwar[ic] = fNfcn;
7894  return;
7895  }
7896 
7897 //*-*- 'SHO WARnings', ask if any suppressed mess in buffer
7898  if (copt == "W") {
7899  ityp = 1;
7900  ctyp = "WARNING";
7901  } else {
7902  ityp = 2;
7903  ctyp = "*DEBUG*";
7904  }
7905  if (fNwrmes[ityp-1] > 0) {
7906  englsh = " WAS SUPPRESSED. ";
7907  if (fNwrmes[ityp-1] > 1) englsh = "S WERE SUPPRESSED.";
7908  Printf(" %5d MINUIT %s MESSAGE%s",fNwrmes[ityp-1]
7909  ,(const char*)ctyp,(const char*)englsh);
7910  nm = fNwrmes[ityp-1];
7911  ic = 0;
7912  if (nm > kMAXMES) {
7913  Printf(" ONLY THE MOST RECENT 10 WILL BE LISTED BELOW.");
7914  nm = kMAXMES;
7915  ic = fIcirc[ityp-1];
7916  }
7917  Printf(" CALLS ORIGIN MESSAGE");
7918  for (i = 1; i <= nm; ++i) {
7919  ++ic;
7920  if (ic > kMAXMES) ic = 1;
7921  Printf(" %6d %s %s", fNfcwar[ic],fOrigin[ic].Data(),fWarmes[ic].Data());
7922  }
7923  fNwrmes[ityp-1] = 0;
7924  Printf(" ");
7925  }
7926 } /* mnwarn_ */
7927 
7928 ////////////////////////////////////////////////////////////////////////////////
7929 ///*-*-*-*-*-*-*-*Calculates the WERR, external parameter errors*-*-*-*-*-*-*
7930 ///*-* ==============================================
7931 ///*-* and the global correlation coefficients, to be called
7932 ///*-* whenever a new covariance matrix is available.
7933 ///*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
7934 
7936 {
7937  Double_t denom, ba, al, dx, du1, du2;
7938  Int_t ndex, ierr, i, j, k, l, ndiag, k1, iin;
7939 
7940 //*-*- calculate external error if v exists
7941  if (fISW[1] >= 1) {
7942  for (l = 1; l <= fNpar; ++l) {
7943  ndex = l*(l + 1) / 2;
7944  dx = TMath::Sqrt(TMath::Abs(fVhmat[ndex-1]*fUp));
7945  i = fNexofi[l-1];
7946  if (fNvarl[i-1] > 1) {
7947  al = fAlim[i-1];
7948  ba = fBlim[i-1] - al;
7949  du1 = al + 0.5*(TMath::Sin(fX[l-1] + dx) + 1)*ba - fU[i-1];
7950  du2 = al + 0.5*(TMath::Sin(fX[l-1] - dx) + 1)*ba - fU[i-1];
7951  if (dx > 1) du1 = ba;
7952  dx = 0.5*(TMath::Abs(du1) + TMath::Abs(du2));
7953  }
7954  fWerr[l-1] = dx;
7955  }
7956  }
7957 //*-*- global correlation coefficients
7958  if (fISW[1] >= 1) {
7959  for (i = 1; i <= fNpar; ++i) {
7960  fGlobcc[i-1] = 0;
7961  k1 = i*(i-1) / 2;
7962  for (j = 1; j <= i; ++j) {
7963  k = k1 + j;
7964  fP[i + j*fMaxpar - fMaxpar-1] = fVhmat[k-1];
7965  fP[j + i*fMaxpar - fMaxpar-1] = fP[i + j*fMaxpar - fMaxpar-1];
7966  }
7967  }
7968  mnvert(fP, fMaxint, fMaxint, fNpar, ierr);
7969  if (ierr == 0) {
7970  for (iin = 1; iin <= fNpar; ++iin) {
7971  ndiag = iin*(iin + 1) / 2;
7972  denom = fP[iin + iin*fMaxpar - fMaxpar-1]*fVhmat[ndiag-1];
7973  if (denom <= 1 && denom >= 0) fGlobcc[iin-1] = 0;
7974  else fGlobcc[iin-1] = TMath::Sqrt(1 - 1 / denom);
7975  }
7976  }
7977  }
7978 } /* mnwerr_ */
Double_t * fMNOTw
Definition: TMinuit.h:121
virtual void mnmnos()
*-*-*-*-*-*-*-*-*-*-*Performs a MINOS error analysis*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:5460
virtual void mnsimp()
*-*-*-*-*Minimization using the simplex method of Nelder and Mead*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:7500
const int nx
Definition: kalman.C:16
Double_t * fBlim
Definition: TMinuit.h:77
Double_t * fXpt
Definition: TMinuit.h:104
TString fCword
Definition: TMinuit.h:176
virtual Int_t GetNumFreePars() const
returns the number of currently free parameters
Definition: TMinuit.cxx:865
double par[1]
Definition: unuranDistr.cxx:38
Int_t fMaxext
Definition: TMinuit.h:49
virtual void mnstat(Double_t &fmin, Double_t &fedm, Double_t &errdef, Int_t &npari, Int_t &nparx, Int_t &istat)
*-*-*-*-*Returns concerning the current status of the minimization*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:7707
Double_t fDcovar
Definition: TMinuit.h:62
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void mneval(Double_t anext, Double_t &fnext, Int_t &ierev)
*-*-*-*-*-*-*Evaluates the function being analyzed by MNCROS*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:2650
Int_t fIstrat
Definition: TMinuit.h:157
Int_t * fIpfix
Definition: TMinuit.h:136
virtual void mnprin(Int_t inkode, Double_t fval)
*-*-*-*Prints the values of the parameters at the time of the call*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:6381
Double_t * fGlobcc
Definition: TMinuit.h:81
virtual Int_t SetPrintLevel(Int_t printLevel=0)
set Minuit print level printlevel = -1 quiet (also suppresse all warnings) = 0 normal = 1 verbose ...
Definition: TMinuit.cxx:974
float xmin
Definition: THbookFile.cxx:93
Double_t * fP
Definition: TMinuit.h:98
virtual void mnexin(Double_t *pint)
*-*-*-*-*Transforms the external parameter values U to internal values*-*-* *-* =====================...
Definition: TMinuit.cxx:3184
Double_t * fPrho
Definition: TMinuit.h:102
TString fCstatu
Definition: TMinuit.h:174
virtual void mnhes1()
*-*-*-*Calculate first derivatives (GRD) and uncertainties (DGRD)*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:4282
virtual void mnvert(Double_t *a, Int_t l, Int_t m, Int_t n, Int_t &ifail)
*-*-*-*-*-*-*-*-*-*-*-*Inverts a symmetric matrix*-*-*-*-*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:7768
Implementation in C++ of the Minuit package written by F.
Definition: TMinuit.h:34
Double_t * fCOMDplist
Definition: TMinuit.h:130
Double_t Log(Double_t x)
Definition: TMath.h:526
int idb
Definition: THbookFile.cxx:91
Int_t fKe2cr
Definition: TMinuit.h:163
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Double_t * fWord7
Definition: TMinuit.h:103
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
virtual void mnemat(Double_t *emat, Int_t ndim)
Calculates the external error matrix from the internal matrix.
Definition: TMinuit.cxx:2531
Double_t * fXs
Definition: TMinuit.h:85
void(* fFCN)(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
Definition: TMinuit.h:185
Double_t * fGrds
Definition: TMinuit.h:93
Bool_t fLnewmn
Definition: TMinuit.h:168
virtual void mnwarn(const char *copt, const char *corg, const char *cmes)
*-*-*-*-*-*-*-*-*-*-*-*Prints Warning messages*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* =======================...
Definition: TMinuit.cxx:7857
float ymin
Definition: THbookFile.cxx:93
Int_t fIdbg[11]
Definition: TMinuit.h:149
Int_t fIsyswr
Definition: TMinuit.h:139
TH1 * h
Definition: legend2.C:5
Int_t fItaur
Definition: TMinuit.h:156
virtual void mnline(Double_t *start, Double_t fstart, Double_t *step, Double_t slope, Double_t toler)
*-*-*-*-*-*-*-*-*-*Perform a line search from position START*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:4804
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1101
Double_t * fVhmat
Definition: TMinuit.h:96
virtual void mnseek()
*-*-*-*Performs a rough (but global) minimization by monte carlo search*-* *-* ======================...
Definition: TMinuit.cxx:6885
#define gROOT
Definition: TROOT.h:340
Int_t LoadPlugin()
Load the plugin library for this handler.
Int_t fNpagwd
Definition: TMinuit.h:141
Basic string class.
Definition: TString.h:137
Double_t * fMATUvline
Definition: TMinuit.h:114
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
Double_t * fGRADgf
Definition: TMinuit.h:110
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void mnderi()
*-*-*-*-*-*-*-*Calculates the first derivatives of FCN (GRD)*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:2207
virtual void mncros(Double_t &aopt, Int_t &iercr)
*-*-*-*-*-*-*-*-*-*-*Find point where MNEVAL=AMIN+UP*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:1825
virtual void mngrad()
*-*-*-*-*-*-*-*-*-*Interprets the SET GRAD command*-*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:3398
int nbins[3]
Double_t * fMNOTxdev
Definition: TMinuit.h:120
virtual void mnbins(Double_t a1, Double_t a2, Int_t naa, Double_t &bl, Double_t &bh, Int_t &nb, Double_t &bwid)
*-*-*-*-*-*-*-*-*-*-*Compute reasonable histogram intervals*-*-*-*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:1021
Double_t * fX
Definition: TMinuit.h:82
virtual void mnrset(Int_t iopt)
*-*-*-*-*-*-*-*Resets function value and errors to UNDEFINED*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:6725
TObject * fPlot
Definition: TMinuit.h:183
Long_t ExecPlugin(int nargs, const T &...params)
virtual void mntiny(volatile Double_t epsp1, Double_t &epsbak)
*-*-*-*-*-*-*-*To find the machine precision*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* =======================...
Definition: TMinuit.cxx:7731
Int_t fNfcnlc
Definition: TMinuit.h:154
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t fNblock
Definition: TMinuit.h:150
TString fCtitl
Definition: TMinuit.h:175
Int_t fNstkwr
Definition: TMinuit.h:147
Int_t fIcirc[2]
Definition: TMinuit.h:160
Double_t * fXts
Definition: TMinuit.h:86
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
Double_t * fDirin
Definition: TMinuit.h:84
double beta(double x, double y)
Calculates the beta function.
virtual Int_t GetNumPars() const
returns the total number of parameters that have been defined as fixed or free.
Definition: TMinuit.cxx:874
TString fOrigin[kMAXWARN]
Definition: TMinuit.h:180
virtual Int_t FixParameter(Int_t parNo)
fix a parameter
Definition: TMinuit.cxx:829
Double_t * fErn
Definition: TMinuit.h:79
virtual Int_t Eval(Int_t npar, Double_t *grad, Double_t &fval, Double_t *par, Int_t flag)
Evaluate the minimisation function Input parameters: npar: number of currently variable parameters pa...
Definition: TMinuit.cxx:802
virtual void mneig(Double_t *a, Int_t ndima, Int_t n, Int_t mits, Double_t *work, Double_t precis, Int_t &ifault)
*-*-*-*-*-*-*-*-*-*-*-*Compute matrix eigen values*-*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:2336
void SetParamPtrs(void *paramArr, Int_t nparam=-1)
ParamArr is an array containing the function argument values.
const char * Data() const
Definition: TString.h:349
virtual void mnmigr()
*-*-*-*-*-*-*-*-*Performs a local function minimization*-*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:5119
virtual void SetFCN(void *fcn)
*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:955
virtual void mnfree(Int_t k)
*-*-*-*Restores one or more fixed parameter(s) to variable status*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:3291
Double_t * fYpt
Definition: TMinuit.h:105
static const double x2[5]
Double_t fEpsmac
Definition: TMinuit.h:63
Int_t * fNexofi
Definition: TMinuit.h:135
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
Int_t fMaxint
Definition: TMinuit.h:47
void Class()
Definition: Class.C:29
Int_t fNpar
Definition: TMinuit.h:48
Double_t * fPstar
Definition: TMinuit.h:99
Int_t fKe1cr
Definition: TMinuit.h:162
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
Double_t * fVERTq
Definition: TMinuit.h:127
Double_t fUndefi
Definition: TMinuit.h:67
virtual void mncrck(TString crdbuf, Int_t maxcwd, TString &comand, Int_t &lnc, Int_t mxp, Double_t *plist, Int_t &llist, Int_t &ierr, Int_t isyswr)
*-*-*-*-*-*-*-*-*-*-*-*Cracks the free-format input*-*-*-*-*-*-*-*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:1703
const int ny
Definition: kalman.C:17
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
Double_t fBigedm
Definition: TMinuit.h:68
Int_t fIstkwr[10]
Definition: TMinuit.h:146
ClassImp(TMinuit) TMinuit
*-*-*-*-*-*-*-*-*-*-*Minuit normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:335
virtual void mnrn15(Double_t &val, Int_t &inseed)
*-*-*-*-*-*-*This is a super-portable random number generator*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:6696
Double_t * fSIMPy
Definition: TMinuit.h:126
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
virtual TObject * Contour(Int_t npoints=10, Int_t pa1=0, Int_t pa2=1)
Creates a TGraph object describing the n-sigma contour of a TMinuit fit.
Definition: TMinuit.cxx:654
Double_t Log10(Double_t x)
Definition: TMath.h:529
virtual ~TMinuit()
*-*-*-*-*-*-*-*-*-*-*Minuit default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:493
static const double x4[22]
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
Definition: vector.h:450
Int_t fMaxpar5
Definition: TMinuit.h:51
virtual void DeleteArrays()
*-*-*-*-*-*-*-*-*-*-*-*Delete internal Minuit arrays*-*-*-*-*-*-*-*-* *-* ===========================...
Definition: TMinuit.cxx:710
std::vector< std::vector< double > > Data
virtual void mncuve()
*-*-*-*-*-*-*-*Makes sure that the current point is a local minimum*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:2158
Double_t fAmin
Definition: TMinuit.h:56
Double_t * fGrd
Definition: TMinuit.h:88
Int_t fNfcnfr
Definition: TMinuit.h:155
Double_t * fAlim
Definition: TMinuit.h:76
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
XFontStruct * id
Definition: TGX11.cxx:108
virtual void BuildArrays(Int_t maxpar=15)
*-*-*-*-*-*-*Create internal Minuit arrays for the maxpar parameters*-*-*-* *-* =====================...
Definition: TMinuit.cxx:509
Method or function calling interface.
Definition: TMethodCall.h:41
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Double_t * fPARSplist
Definition: TMinuit.h:131
Double_t fYdircr
Definition: TMinuit.h:73
TObject * fObjectFit
Definition: TMinuit.h:182
Double_t * fGsteps
Definition: TMinuit.h:95
Int_t * fNvarl
Definition: TMinuit.h:133
virtual void mnmnot(Int_t ilax, Int_t ilax2, Double_t &val2pl, Double_t &val2mi)
*-*-*-*-*-*Performs a MINOS error analysis on one parameter*-*-*-*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:5536
Int_t fNstkrd
Definition: TMinuit.h:145
Int_t fMaxpar1
Definition: TMinuit.h:54
Double_t * fPbar
Definition: TMinuit.h:101
Double_t fYmidcr
Definition: TMinuit.h:71
Double_t * fSEEKxmid
Definition: TMinuit.h:124
TString fCfrom
Definition: TMinuit.h:173
Int_t fNewpag
Definition: TMinuit.h:143
virtual Int_t DefineParameter(Int_t parNo, const char *name, Double_t initVal, Double_t initErr, Double_t lowerLimit, Double_t upperLimit)
Define a parameter.
Definition: TMinuit.cxx:696
double gamma(double x)
virtual void mncont(Int_t ke1, Int_t ke2, Int_t nptu, Double_t *xptu, Double_t *yptu, Int_t &ierrf)
*-*-*-*-*-*-*Find points along a contour where FCN is minimum*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:1421
float ymax
Definition: THbookFile.cxx:93
Int_t fNfcnmx
Definition: TMinuit.h:153
Double_t * fVERTpp
Definition: TMinuit.h:129
TString fCundef
Definition: TMinuit.h:177
TPaveText * pt
Int_t fNpfix
Definition: TMinuit.h:44
ROOT::R::TRInterface & r
Definition: Object.C:4
TString * fCpnam
Character to be plotted at the X,Y contour positions.
Definition: TMinuit.h:172
Double_t * fG2
Definition: TMinuit.h:89
Double_t fEpsi
Definition: TMinuit.h:60
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
Double_t * fSEEKxbest
Definition: TMinuit.h:125
Int_t fMaxpar2
Definition: TMinuit.h:53
virtual void mncler()
*-*-*-*-*-*-*-*-*-*-*Resets the parameter list to UNDEFINED*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:1129
virtual void mnparm(Int_t k, TString cnamj, Double_t uk, Double_t wk, Double_t a, Double_t b, Int_t &ierflg)
*-*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:5736
virtual Int_t GetParameter(Int_t parNo, Double_t &currentValue, Double_t &currentError) const
return parameter value and error
Definition: TMinuit.cxx:843
virtual void mnfixp(Int_t iint, Int_t &ierr)
*-*-*-*-*-*-*Removes parameter IINT from the internal parameter list*-*-* *-* =======================...
Definition: TMinuit.cxx:3203
Double_t fXmidcr
Definition: TMinuit.h:70
Int_t fStatus
Definition: TMinuit.h:161
virtual void mncalf(Double_t *pvec, Double_t &ycalf)
*-*-*-*-*-*-*-*-*-*Transform FCN to find further minima*-*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:1095
Double_t * fWerr
Definition: TMinuit.h:80
Double_t * fMIGRgs
Definition: TMinuit.h:117
char * fChpt
Definition: TMinuit.h:171
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
Bool_t fLnolim
Definition: TMinuit.h:167
Double_t * fDirins
Definition: TMinuit.h:87
TMarker * m
Definition: textangle.C:8
Double_t * fIMPRdsav
Definition: TMinuit.h:112
char * Form(const char *fmt,...)
Double_t * fPstst
Definition: TMinuit.h:100
virtual Int_t SetErrorDef(Double_t up)
To get the n-sigma contour the error def parameter "up" has to set to n^2.
Definition: TMinuit.cxx:910
Bool_t fLrepor
Definition: TMinuit.h:165
Double_t * fIMPRy
Definition: TMinuit.h:113
Double_t fApsi
Definition: TMinuit.h:61
TLine * l
Definition: textangle.C:4
const std::string sname
Definition: testIO.cxx:45
Double_t * fXt
Definition: TMinuit.h:83
TMethodCall * GetMethodCall() const
Definition: TMinuit.h:200
float xmax
Definition: THbookFile.cxx:93
TMethodCall * fMethodCall
Definition: TMinuit.h:184
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TMinuit.cxx:594
int ncall
Definition: stressTF1.cxx:20
Double_t fUpdflt
Definition: TMinuit.h:69
Double_t * fVERTs
Definition: TMinuit.h:128
virtual void mnerrs(Int_t number, Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &gcc)
*-*-*-*-*-*-*-*-*-*Utility routine to get MINOS errors*-*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:2607
virtual void mnhess()
*-*-*-*-*-*Calculates the full second-derivative matrix of FCN*-*-*-*-*-*-*-* *-* ===================...
Definition: TMinuit.cxx:4056
Double_t fFval3
Definition: TMinuit.h:59
Double_t * fGstep
Definition: TMinuit.h:90
Int_t fIsyssa
Definition: TMinuit.h:140
Double_t * fMIGRflnu
Definition: TMinuit.h:115
TGraphErrors * gr
Definition: legend1.C:25
Bool_t fGraphicsMode
Definition: TMinuit.h:170
#define Printf
Definition: TGeoToOCC.h:18
Bool_t fLwarn
Definition: TMinuit.h:164
Double_t * fErp
Definition: TMinuit.h:78
Double_t Cos(Double_t)
Definition: TMath.h:424
Int_t * fNiofex
Definition: TMinuit.h:134
void InitWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Initialize the method invocation environment.
virtual Int_t GetNumFixedPars() const
returns the number of currently fixed parameters
Definition: TMinuit.cxx:857
virtual void mnpsdf()
*-*-*-*-*-*Calculates the eigenvalues of v to see if positive-def*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:6572
virtual void mndxdi(Double_t pint, Int_t ipar, Double_t &dxdi)
*-*-*-*Calculates the transformation factor between ext/internal values*-* *-* ======================...
Definition: TMinuit.cxx:2323
long Long_t
Definition: RtypesCore.h:50
Int_t fNpagln
Definition: TMinuit.h:142
Double_t * fMIGRxxs
Definition: TMinuit.h:119
Double_t fEDM
Definition: TMinuit.h:58
Double_t * fCONTgcc
Definition: TMinuit.h:107
Double_t * fFIXPyy
Definition: TMinuit.h:109
virtual void mnamin()
*-*-*-*-*-*-*-*-*-*-*-*-*Initialize AMIN*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* =============== *-*C Ca...
Definition: TMinuit.cxx:995
Int_t fNfcn
Definition: TMinuit.h:152
static const double x1[5]
double f(double x)
Double_t * fMNOTgcc
Definition: TMinuit.h:122
Double_t * fCONTw
Definition: TMinuit.h:108
virtual void mnscan()
*-*-*-*-*Scans the values of FCN as a function of one parameter*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:6774
TString fWarmes[kMAXWARN]
Definition: TMinuit.h:181
double Double_t
Definition: RtypesCore.h:55
virtual void mnhelp(TString comd)
*-*-*-*-*-*-*-*HELP routine for MINUIT interactive commands*-*-*-*-*-*-*-*-* *-* ====================...
Definition: TMinuit.cxx:3476
void InteractiveFCNm(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
*-*-*-*-*-*-*Static function called when SetFCN is called in interactive mode *-* ===================...
Definition: TMinuit.cxx:933
virtual Int_t Release(Int_t parNo)
release a parameter
Definition: TMinuit.cxx:896
Int_t fNfcwar[20]
Definition: TMinuit.h:159
Double_t * fG2s
Definition: TMinuit.h:94
Double_t y[n]
Definition: legend1.C:17
Bool_t fLimset
Definition: TMinuit.h:166
virtual void mnpfit(Double_t *parx2p, Double_t *pary2p, Int_t npar2p, Double_t *coef2p, Double_t &sdev2p)
*-*-*-*-*-*-*-*-*-*To fit a parabola to npar2p points*-*-*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:6029
Double_t * fU
Definition: TMinuit.h:75
virtual void mnlims()
*-*-*-*Interprets the SET LIM command, to reset the parameter limits*-*-*-* *-* =====================...
Definition: TMinuit.cxx:4683
virtual void mnexcm(const char *comand, Double_t *plist, Int_t llist, Int_t &ierflg)
*-*-*-*-*-*Interprets a command and takes appropriate action*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:2696
virtual void mncntr(Int_t ke1, Int_t ke2, Int_t &ierrf)
*-*-*-*-*Print function contours in two variables, on line printer*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:1160
Int_t fMaxcpt
Definition: TMinuit.h:52
virtual void SetMaxIterations(Int_t maxiter=500)
Definition: TMinuit.h:272
virtual void mncomd(const char *crdbin, Int_t &icondn)
*-*-*-*-*-*-*-*-*-*-*Reads a command string and executes*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:1338
#define name(a, b)
Definition: linkTestLib0.cpp:5
Double_t * fGin
Definition: TMinuit.h:91
virtual Int_t Command(const char *command)
execute a Minuit command Equivalent to MNEXCM except that the command is given as a character string...
Definition: TMinuit.cxx:627
virtual void mninit(Int_t i1, Int_t i2, Int_t i3)
*-*-*-*-*-*Main initialization member function for MINUIT*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:4592
Mother of all ROOT objects.
Definition: TObject.h:58
Double_t * fMIGRstep
Definition: TMinuit.h:116
virtual Int_t Migrad()
invokes the MIGRAD minimizer
Definition: TMinuit.cxx:882
Int_t fIcomnd
Definition: TMinuit.h:151
virtual void mnpars(TString &crdbuf, Int_t &icondn)
*-*-*-*-*-*-*-*Implements one parameter definition*-*-*-*-*-*-*-*-*-*-*-*-* *-* =========== =========...
Definition: TMinuit.cxx:5939
Double_t * fVthmat
Definition: TMinuit.h:97
virtual void mnplot(Double_t *xpt, Double_t *ypt, char *chpt, Int_t nxypt, Int_t npagwd, Int_t npagln)
*-*-*-*Plots points in array xypt onto one page with labelled axes*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:6143
virtual void mnpint(Double_t &pexti, Int_t i, Double_t &pinti)
*-*-*-*-*-*-*Calculates the internal parameter value PINTI*-*-*-*-*-*-*-* *-* =======================...
Definition: TMinuit.cxx:6091
virtual void mnsave()
*-*-*-*Writes current parameter values and step sizes onto file ISYSSA*-*-* *-* =====================...
Definition: TMinuit.cxx:6760
virtual void mninex(Double_t *pint)
*-*-*-*-*Transforms from internal coordinates (PINT) to external (U)*-*-*-* *-* =====================...
Definition: TMinuit.cxx:4571
Double_t * fPSDFs
Definition: TMinuit.h:123
const char charal[29]
Definition: TMinuit.cxx:333
double f2(const double *x)
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:68
Double_t * fMIGRvg
Definition: TMinuit.h:118
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Double_t fVlimlo
Definition: TMinuit.h:65
Double_t Sin(Double_t)
Definition: TMath.h:421
TF1 * f1
Definition: legend1.C:11
Double_t fEpsma2
Definition: TMinuit.h:64
TMinuit * gMinuit
Definition: TMinuit.cxx:331
virtual void mnmatu(Int_t kode)
*-*-*-*-*-*-*-*Prints the covariance matrix v when KODE=1*-*-*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:5039
virtual void mnset()
*-*-*-*-*Interprets the commands that start with SET and SHOW*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:6981
Double_t ASin(Double_t)
Definition: TMath.h:439
Double_t fUp
Definition: TMinuit.h:57
Int_t fEmpty
Definition: TMinuit.h:45
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:167
Double_t fXdircr
Definition: TMinuit.h:72
int * iq
Definition: THbookFile.cxx:86
Bool_t mnunpt(TString &cfname)
*-*-*-*-*-*Returns .TRUE.
Definition: TMinuit.cxx:7741
Int_t fMaxpar
Definition: TMinuit.h:46
virtual void mnrazz(Double_t ynew, Double_t *pnew, Double_t *y, Int_t &jh, Int_t &jl)
*-*-*-*-*Called only by MNSIMP (and MNIMPR) to add a new point*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:6647
virtual const char * Getp2f2funcname(void *) const
Definition: TInterpreter.h:213
double result[121]
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:504
const Bool_t kTRUE
Definition: Rtypes.h:91
Double_t * fDgrd
Definition: TMinuit.h:92
Bool_t fLphead
Definition: TMinuit.h:169
TString fCvrsn
Definition: TMinuit.h:178
Int_t fIsysrd
Definition: TMinuit.h:138
Int_t fNu
Definition: TMinuit.h:137
Double_t * fHESSyy
Definition: TMinuit.h:111
const Int_t n
Definition: legend1.C:16
Int_t fNwrmes[2]
Definition: TMinuit.h:158
Double_t fVlimhi
Definition: TMinuit.h:66
virtual void mnpout(Int_t iuext, TString &chnam, Double_t &val, Double_t &err, Double_t &xlolim, Double_t &xuplim, Int_t &iuint) const
*-*-*-*Provides the user with information concerning the current status*-*-* *-* ====================...
Definition: TMinuit.cxx:6325
TString fCovmes[4]
Definition: TMinuit.h:179
Definition: drr.cxx:518
virtual void mnimpr()
*-*-*-*-*-*-*Attempts to improve on a good local minimum*-*-*-*-*-*-*-*-*-* *-* =====================...
Definition: TMinuit.cxx:4359
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1058
Int_t fISW[7]
Definition: TMinuit.h:148
static const double x3[11]
Double_t ATan(Double_t)
Definition: TMath.h:451
virtual void mnwerr()
*-*-*-*-*-*-*-*Calculates the WERR, external parameter errors*-*-*-*-*-*-* *-* ======================...
Definition: TMinuit.cxx:7935
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904