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