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