Logo ROOT  
Reference Guide
MnMinos.cxx
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
10#include "Minuit2/MnMinos.h"
12#include "Minuit2/FCNBase.h"
14#include "Minuit2/MnCross.h"
15#include "Minuit2/MinosError.h"
16
17//#define DEBUG
18
19#if defined(DEBUG) || defined(WARNINGMSG)
20#include "Minuit2/MnPrint.h"
21#endif
22
23
24namespace ROOT {
25
26 namespace Minuit2 {
27
28
29MnMinos::MnMinos(const FCNBase& fcn, const FunctionMinimum& min, unsigned int stra ) :
30 fFCN(fcn),
31 fMinimum(min),
32 fStrategy(MnStrategy(stra))
33{
34 // construct from FCN + Minimum
35 // check if Error definition has been changed, in case re-update errors
36 if (fcn.Up() != min.Up() ) {
37#ifdef WARNINGMSG
38 MN_INFO_MSG("MnMinos UP value has changed, need to update FunctionMinimum class");
39#endif
40 }
41}
42
43MnMinos::MnMinos(const FCNBase& fcn, const FunctionMinimum& min, const MnStrategy& stra) :
44 fFCN(fcn),
45 fMinimum(min),
46 fStrategy(stra)
47{
48 // construct from FCN + Minimum
49 // check if Error definition has been changed, in case re-update errors
50 if (fcn.Up() != min.Up() ) {
51#ifdef WARNINGMSG
52 MN_INFO_MSG("MnMinos UP value has changed, need to update FunctionMinimum class");
53#endif
54 }
55}
56
57
58std::pair<double,double> MnMinos::operator()(unsigned int par, unsigned int maxcalls, double toler) const {
59 // do Minos analysis given the parameter index returning a pair for (lower,upper) errors
60 MinosError mnerr = Minos(par, maxcalls,toler);
61 return mnerr();
62}
63
64double MnMinos::Lower(unsigned int par, unsigned int maxcalls, double toler) const {
65 // get lower error for parameter par
66
67 MnCross aopt = Loval(par, maxcalls,toler);
68
69 MinosError mnerr(par, fMinimum.UserState().Value(par), aopt, MnCross());
70
71 return mnerr.Lower();
72}
73
74double MnMinos::Upper(unsigned int par, unsigned int maxcalls, double toler) const {
75 // upper error for parameter par
76
77 MnCross aopt = Upval(par, maxcalls,toler);
78
79 MinosError mnerr(par, fMinimum.UserState().Value(par), MnCross(), aopt);
80
81 return mnerr.Upper();
82}
83
84MinosError MnMinos::Minos(unsigned int par, unsigned int maxcalls, double toler) const {
85 // do full minos error anlysis (lower + upper) for parameter par
86
87 MnCross up = Upval(par, maxcalls,toler);
88#ifdef DEBUG
89 std::cout << "Function calls to find upper error " << up.NFcn() << std::endl;
90#endif
91
92 MnCross lo = Loval(par, maxcalls,toler);
93
94#ifdef DEBUG
95 std::cout << "Function calls to find lower error " << lo.NFcn() << std::endl;
96#endif
97
98 std::cout << "return Minos error " << lo.Value() << " , " << up.Value() << std::endl;
99
100 return MinosError(par, fMinimum.UserState().Value(par), lo, up);
101}
102
103
104MnCross MnMinos::FindCrossValue(int direction, unsigned int par, unsigned int maxcalls, double toler) const {
105 // get crossing value in the parameter direction :
106 // direction = + 1 upper value
107 // direction = -1 lower value
108 // pass now tolerance used for Migrad minimizations
109
110 assert(direction == 1 || direction == -1);
111
112 int printLevel = MnPrint::Level();
113 if (printLevel > 2) {
114 if (direction == 1)
115 std::cout << "--------- MnMinos -------\nDetermination of upper Minos error for parameter "
116 << par << std::endl;
117 else
118 std::cout << "--------- MnMinos -------\nDetermination of lower Minos error for parameter "
119 << par << std::endl;
120 }
121
122 assert(fMinimum.IsValid());
123 assert(!fMinimum.UserState().Parameter(par).IsFixed());
124 assert(!fMinimum.UserState().Parameter(par).IsConst());
125
126 if(maxcalls == 0) {
127 unsigned int nvar = fMinimum.UserState().VariableParameters();
128 maxcalls = 2*(nvar+1)*(200 + 100*nvar + 5*nvar*nvar);
129 }
130
131 std::vector<unsigned int> para(1, par);
132
134 double err = direction * upar.Error(par);
135 double val = upar.Value(par) + err;
136 // check if we do not cross limits
137 if (direction == 1 && upar.Parameter(par).HasUpperLimit()) {
138 val = std::min(val, upar.Parameter(par).UpperLimit());
139 }
140 if (direction == -1 && upar.Parameter(par).HasLowerLimit()) {
141 val = std::max(val, upar.Parameter(par).LowerLimit());
142 }
143 // recompute err in case it was truncated for the limit
144 err = val-upar.Value(par);
145 std::vector<double> xmid(1, val);
146 std::vector<double> xdir(1, err);
147
148 double up = fFCN.Up();
149 unsigned int ind = upar.IntOfExt(par);
150 // get error matrix (methods return a copy)
152 // get internal parameters
153 const MnAlgebraicVector & xt = fMinimum.Parameters().Vec();
154 //LM: change to use err**2 (m(i,i) instead of err as in F77 version
155 double xunit = sqrt(up/m(ind,ind));
156 // LM (29/04/08) bug: change should be done in internal variables
157 // set the initial value for the other parmaeters that we are going to fit in MnCross
158 for(unsigned int i = 0; i < m.Nrow(); i++) {
159 if(i == ind) continue;
160 double xdev = xunit*m(ind,i);
161 double xnew = xt(i) + direction * xdev;
162
163 // transform to external values
164 unsigned int ext = upar.ExtOfInt(i);
165
166 double unew = upar.Int2ext(i, xnew);
167
168 // take into account limits
169 if (upar.Parameter(ext).HasUpperLimit()) {
170 unew = std::min(unew, upar.Parameter(ext).UpperLimit());
171 }
172 if (upar.Parameter(ext).HasLowerLimit()) {
173 unew = std::max(unew, upar.Parameter(ext).LowerLimit());
174 }
175
176#ifdef DEBUG
177 std::cout << "Parameter " << ext << " is set from " << upar.Value(ext) << " to " << unew << std::endl;
178#endif
179 upar.SetValue(ext, unew);
180 }
181
182 upar.Fix(par);
183 upar.SetValue(par, val);
184
185#ifdef DEBUG
186 std::cout << "Parameter " << par << " is fixed and set from " << fMinimum.UserState().Value(par) << " to " << val
187 << " delta = " << err << std::endl;
188#endif
189
190
191 MnFunctionCross cross(fFCN, upar, fMinimum.Fval(), fStrategy);
192 MnCross aopt = cross(para, xmid, xdir, toler, maxcalls);
193
194
195#ifdef DEBUG
196 std::cout<<"----- MnMinos: aopt value found from MnFunctionCross = "<<aopt.Value()<<std::endl << std::endl;
197#endif
198
199#ifdef WARNINGMSG
200 const char * par_name = upar.Name(par);
201 if(aopt.AtMaxFcn())
202 MN_INFO_VAL2("MnMinos maximum number of function calls exceeded for Parameter ",par_name);
203 if(aopt.NewMinimum())
204 MN_INFO_VAL2("MnMinos new Minimum found while looking for Parameter ",par_name);
205 if (direction ==1) {
206 if(aopt.AtLimit())
207 MN_INFO_VAL2("MnMinos: parameter is at Upper limit.",par_name);
208 if(!aopt.IsValid())
209 MN_INFO_VAL2("MnMinos: could not find Upper Value for Parameter ",par_name);
210 }
211 else {
212 if(aopt.AtLimit())
213 MN_INFO_VAL2("MnMinos: parameter is at Lower limit.",par_name);
214 if(!aopt.IsValid())
215 MN_INFO_VAL2("MnMinos: could not find Lower Value for Parameter ",par_name);
216 }
217#endif
218
219 if (printLevel > 2) {
220 std::string scanType = (direction == 1) ? "up" : "low";
221 std::cout << " ------ end Minos scan for " << scanType << " interval for parameter " << upar.Name(par) << std::endl;
222 }
223
224 return aopt;
225}
226
227MnCross MnMinos::Upval(unsigned int par, unsigned int maxcalls, double toler) const {
228 // return crossing in the lower parameter direction
229 return FindCrossValue(1,par,maxcalls,toler);
230}
231
232MnCross MnMinos::Loval(unsigned int par, unsigned int maxcalls, double toler) const {
233 // return crossing in the lower parameter direction
234 return FindCrossValue(-1,par,maxcalls,toler);
235}
236
237
238 } // namespace Minuit2
239
240} // namespace ROOT
#define MN_INFO_VAL2(loc, x)
Definition: MnPrint.h:130
#define MN_INFO_MSG(str)
Definition: MnPrint.h:110
double sqrt(double)
Interface (abstract class) defining the function to be minimized, which has to be implemented by the ...
Definition: FCNBase.h:47
virtual double Up() const =0
Error definition of the function.
class holding the full result of the minimization; both internal and external (MnUserParameterState) ...
const MinimumParameters & Parameters() const
const MinimumError & Error() const
const MnUserParameterState & UserState() const
Class describing a symmetric matrix of size n.
Definition: LASymMatrix.h:51
MnAlgebraicSymMatrix Matrix() const
Definition: MinimumError.h:58
const MnAlgebraicVector & Vec() const
Class holding the result of Minos (lower and upper values) for a specific parameter.
Definition: MinosError.h:25
double Upper() const
Definition: MinosError.h:58
double Lower() const
Definition: MinosError.h:50
bool AtLimit() const
Definition: MnCross.h:64
unsigned int NFcn() const
Definition: MnCross.h:67
bool AtMaxFcn() const
Definition: MnCross.h:65
bool IsValid() const
Definition: MnCross.h:63
bool NewMinimum() const
Definition: MnCross.h:66
double Value() const
Definition: MnCross.h:61
const FunctionMinimum & fMinimum
Definition: MnMinos.h:71
const FCNBase & fFCN
Definition: MnMinos.h:70
MnStrategy fStrategy
Definition: MnMinos.h:72
MinosError Minos(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
ask for MinosError (Lower + Upper) can be printed via std::cout
Definition: MnMinos.cxx:84
double Upper(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition: MnMinos.cxx:74
std::pair< double, double > operator()(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
returns the negative (pair.first) and the positive (pair.second) Minos Error of the Parameter
Definition: MnMinos.cxx:58
MnCross Loval(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition: MnMinos.cxx:232
MnCross FindCrossValue(int dir, unsigned int, unsigned int maxcalls, double toler) const
internal method to get crossing value via MnFunctionCross
Definition: MnMinos.cxx:104
MnMinos(const FCNBase &fcn, const FunctionMinimum &min, unsigned int stra=1)
construct from FCN + Minimum + strategy
Definition: MnMinos.cxx:29
double Lower(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
calculate one side (negative or positive Error) of the Parameter give as input (optionally) maxcalls ...
Definition: MnMinos.cxx:64
MnCross Upval(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition: MnMinos.cxx:227
static int Level()
Definition: MnPrint.cxx:47
API class for defining three levels of strategies: low (0), medium (1), high (>=2); acts on: Migrad (...
Definition: MnStrategy.h:27
class which holds the external user and/or internal Minuit representation of the parameters and error...
double Int2ext(unsigned int, double) const
const MinuitParameter & Parameter(unsigned int i) const
unsigned int ExtOfInt(unsigned int) const
const char * Name(unsigned int) const
unsigned int IntOfExt(unsigned int) const
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21
auto * m
Definition: textangle.C:8