19 #if defined(DEBUG) || defined(WARNINGMSG)
29 MnMinos::MnMinos(
const FCNBase& fcn,
const FunctionMinimum& min,
unsigned int stra ) :
32 fStrategy(MnStrategy(stra))
36 if (fcn.Up() != min.Up() ) {
38 MN_INFO_MSG(
"MnMinos UP value has changed, need to update FunctionMinimum class");
43 MnMinos::MnMinos(
const FCNBase& fcn,
const FunctionMinimum& min,
const MnStrategy& stra) :
50 if (fcn.Up() != min.Up() ) {
52 MN_INFO_MSG(
"MnMinos UP value has changed, need to update FunctionMinimum class");
58 std::pair<double,double> MnMinos::operator()(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
60 MinosError mnerr = Minos(par, maxcalls,toler);
64 double MnMinos::Lower(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
66 MnUserParameterState upar = fMinimum.UserState();
67 double err = fMinimum.UserState().Error(par);
69 MnCross aopt = Loval(par, maxcalls,toler);
71 double lower = aopt.IsValid() ? -1.*err*(1.+ aopt.Value()) : (aopt.AtLimit() ? upar.Parameter(par).LowerLimit() : upar.Value(par));
76 double MnMinos::Upper(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
78 MnCross aopt = Upval(par, maxcalls,toler);
80 MnUserParameterState upar = fMinimum.UserState();
81 double err = fMinimum.UserState().Error(par);
83 double upper = aopt.IsValid() ? err*(1.+ aopt.Value()) : (aopt.AtLimit() ? upar.Parameter(par).UpperLimit() : upar.Value(par));
88 MinosError MnMinos::Minos(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
90 assert(fMinimum.IsValid());
91 assert(!fMinimum.UserState().Parameter(par).IsFixed());
92 assert(!fMinimum.UserState().Parameter(par).IsConst());
94 MnCross up = Upval(par, maxcalls,toler);
96 std::cout <<
"Function calls to find upper error " << up.NFcn() << std::endl;
99 MnCross lo = Loval(par, maxcalls,toler);
102 std::cout <<
"Function calls to find lower error " << lo.NFcn() << std::endl;
105 return MinosError(par, fMinimum.UserState().Value(par), lo, up);
109 MnCross MnMinos::FindCrossValue(
int direction,
unsigned int par,
unsigned int maxcalls,
double toler)
const {
115 assert(direction == 1 || direction == -1);
118 std::cout <<
"\n--------- MnMinos --------- \n Determination of positive Minos error for parameter "
121 std::cout <<
"\n--------- MnMinos --------- \n Determination of positive Minos error for parameter "
125 assert(fMinimum.IsValid());
126 assert(!fMinimum.UserState().Parameter(par).IsFixed());
127 assert(!fMinimum.UserState().Parameter(par).IsConst());
129 unsigned int nvar = fMinimum.UserState().VariableParameters();
130 maxcalls = 2*(nvar+1)*(200 + 100*nvar + 5*nvar*nvar);
133 std::vector<unsigned int> para(1, par);
135 MnUserParameterState upar = fMinimum.UserState();
136 double err = direction * upar.Error(par);
137 double val = upar.Value(par) + err;
138 std::vector<double> xmid(1, val);
139 std::vector<double> xdir(1, err);
141 double up = fFCN.Up();
142 unsigned int ind = upar.IntOfExt(par);
144 MnAlgebraicSymMatrix m = fMinimum.Error().Matrix();
146 const MnAlgebraicVector & xt = fMinimum.Parameters().Vec();
148 double xunit = sqrt(up/m(ind,ind));
150 for(
unsigned int i = 0; i < m.Nrow(); i++) {
151 if(i == ind)
continue;
152 double xdev = xunit*m(ind,i);
153 double xnew = xt(i) + direction * xdev;
156 unsigned int ext = upar.ExtOfInt(i);
158 double unew = upar.Int2ext(i, xnew);
161 std::cout <<
"Parameter " << ext <<
" is set from " << upar.Value(ext) <<
" to " << unew << std::endl;
163 upar.SetValue(ext, unew);
167 upar.SetValue(par, val);
170 std::cout <<
"Parameter " << par <<
" is fixed and set from " << fMinimum.UserState().Value(par) <<
" to " << val << std::endl;
174 MnFunctionCross cross(fFCN, upar, fMinimum.Fval(), fStrategy);
175 MnCross aopt = cross(para, xmid, xdir, toler, maxcalls);
179 std::cout<<
"----- MnMinos: aopt found from MnFunctionCross = "<<aopt.Value()<<std::endl << std::endl;
183 const char * par_name = upar.Name(par);
185 MN_INFO_VAL2(
"MnMinos maximum number of function calls exceeded for Parameter ",par_name);
186 if(aopt.NewMinimum())
187 MN_INFO_VAL2(
"MnMinos new Minimum found while looking for Parameter ",par_name);
190 MN_INFO_VAL2(
"MnMinos Parameter is at Upper limit.",par_name);
192 MN_INFO_VAL2(
"MnMinos could not find Upper Value for Parameter ",par_name);
196 MN_INFO_VAL2(
"MnMinos Parameter is at Lower limit.",par_name);
198 MN_INFO_VAL2(
"MnMinos could not find Lower Value for Parameter ",par_name);
205 MnCross MnMinos::Upval(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
207 return FindCrossValue(1,par,maxcalls,toler);
210 MnCross MnMinos::Loval(
unsigned int par,
unsigned int maxcalls,
double toler)
const {
212 return FindCrossValue(-1,par,maxcalls,toler);