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