Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
MnUserParameterState.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
13#include "Minuit2/MnPrint.h"
14
15namespace ROOT {
16
17namespace Minuit2 {
18
19//
20// construct from user parameters (befor minimization)
21//
22MnUserParameterState::MnUserParameterState(const std::vector<double> &par, const std::vector<double> &err)
23 : fValid(true), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
24 fParameters(MnUserParameters(par, err)), fCovariance(MnUserCovariance()), fGlobalCC(MnGlobalCorrelationCoeff()),
25 fIntParameters(par), fIntCovariance(MnUserCovariance())
26{
27}
28
30 : fValid(true), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
31 fParameters(par), fCovariance(MnUserCovariance()), fGlobalCC(MnGlobalCorrelationCoeff()),
32 fIntParameters(std::vector<double>()), fIntCovariance(MnUserCovariance())
33{
34 // construct from user parameters (befor minimization)
35
36 for (std::vector<MinuitParameter>::const_iterator ipar = MinuitParameters().begin();
37 ipar != MinuitParameters().end(); ++ipar) {
38 if ((*ipar).IsConst() || (*ipar).IsFixed())
39 continue;
40 if ((*ipar).HasLimits())
41 fIntParameters.push_back(Ext2int((*ipar).Number(), (*ipar).Value()));
42 else
43 fIntParameters.push_back((*ipar).Value());
44 }
45}
46
47//
48// construct from user parameters + errors (befor minimization)
49//
50MnUserParameterState::MnUserParameterState(const std::vector<double> &par, const std::vector<double> &cov,
51 unsigned int nrow)
52 : fValid(true), fCovarianceValid(true), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
53 fParameters(MnUserParameters()), fCovariance(MnUserCovariance(cov, nrow)), fGlobalCC(MnGlobalCorrelationCoeff()),
54 fIntParameters(par), fIntCovariance(MnUserCovariance(cov, nrow))
55{
56 // construct from user parameters + errors (before minimization) using std::vector for parameter error and // an
57 // std::vector of size n*(n+1)/2 for the covariance matrix and n (rank of cov matrix)
58
59 std::vector<double> err;
60 err.reserve(par.size());
61 for (unsigned int i = 0; i < par.size(); i++) {
62 assert(fCovariance(i, i) > 0.);
63 err.push_back(std::sqrt(fCovariance(i, i)));
64 }
65 fParameters = MnUserParameters(par, err);
66 assert(fCovariance.Nrow() == VariableParameters());
67}
68
69MnUserParameterState::MnUserParameterState(const std::vector<double> &par, const MnUserCovariance &cov)
70 : fValid(true), fCovarianceValid(true), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
71 fParameters(MnUserParameters()), fCovariance(cov), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(par),
72 fIntCovariance(cov)
73{
74 // construct from user parameters + errors (before minimization) using std::vector (params) and MnUserCovariance
75 // class
76
77 std::vector<double> err;
78 err.reserve(par.size());
79 for (unsigned int i = 0; i < par.size(); i++) {
80 assert(fCovariance(i, i) > 0.);
81 err.push_back(std::sqrt(fCovariance(i, i)));
82 }
83 fParameters = MnUserParameters(par, err);
84 assert(fCovariance.Nrow() == VariableParameters());
85}
86
88 : fValid(true), fCovarianceValid(true), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
89 fParameters(par), fCovariance(cov), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(std::vector<double>()),
90 fIntCovariance(cov)
91{
92 // construct from user parameters + errors (befor minimization) using
93 // MnUserParameters and MnUserCovariance objects
94
96 for (std::vector<MinuitParameter>::const_iterator ipar = MinuitParameters().begin();
97 ipar != MinuitParameters().end(); ++ipar) {
98 if ((*ipar).IsConst() || (*ipar).IsFixed())
99 continue;
100 if ((*ipar).HasLimits())
101 fIntParameters.push_back(Ext2int((*ipar).Number(), (*ipar).Value()));
102 else
103 fIntParameters.push_back((*ipar).Value());
104 }
105 assert(fCovariance.Nrow() == VariableParameters());
106 //
107 // need to Fix that in case of limited parameters
108 // fIntCovariance = MnUserCovariance();
109 //
110}
111
112//
113//
115 : fValid(st.IsValid()), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(st.Fval()), fEDM(st.Edm()),
116 fNFcn(st.NFcn()), fParameters(MnUserParameters()), fCovariance(MnUserCovariance()),
117 fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(std::vector<double>()), fIntCovariance(MnUserCovariance())
118{
119 //
120 // construct from internal parameters (after minimization)
121 //
122 // std::cout << "build a MnUSerParameterState after minimization.." << std::endl;
123
124 for (std::vector<MinuitParameter>::const_iterator ipar = trafo.Parameters().begin();
125 ipar != trafo.Parameters().end(); ++ipar) {
126 if ((*ipar).IsConst()) {
127 Add((*ipar).GetName(), (*ipar).Value());
128 } else if ((*ipar).IsFixed()) {
129 Add((*ipar).GetName(), (*ipar).Value(), (*ipar).Error());
130 if ((*ipar).HasLimits()) {
131 if ((*ipar).HasLowerLimit() && (*ipar).HasUpperLimit())
132 SetLimits((*ipar).GetName(), (*ipar).LowerLimit(), (*ipar).UpperLimit());
133 else if ((*ipar).HasLowerLimit() && !(*ipar).HasUpperLimit())
134 SetLowerLimit((*ipar).GetName(), (*ipar).LowerLimit());
135 else
136 SetUpperLimit((*ipar).GetName(), (*ipar).UpperLimit());
137 }
138 Fix((*ipar).GetName());
139 } else if ((*ipar).HasLimits()) {
140 unsigned int i = trafo.IntOfExt((*ipar).Number());
141 double err =
142 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
143 Add((*ipar).GetName(), trafo.Int2ext(i, st.Vec()(i)), trafo.Int2extError(i, st.Vec()(i), err));
144 if ((*ipar).HasLowerLimit() && (*ipar).HasUpperLimit())
145 SetLimits((*ipar).GetName(), (*ipar).LowerLimit(), (*ipar).UpperLimit());
146 else if ((*ipar).HasLowerLimit() && !(*ipar).HasUpperLimit())
147 SetLowerLimit((*ipar).GetName(), (*ipar).LowerLimit());
148 else
149 SetUpperLimit((*ipar).GetName(), (*ipar).UpperLimit());
150 } else {
151 unsigned int i = trafo.IntOfExt((*ipar).Number());
152 double err =
153 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
154 Add((*ipar).GetName(), st.Vec()(i), err);
155 }
156 }
157
158 // need to be set afterwards because becore the ::Add method set fCovarianceValid to false
160
161 fCovStatus = -1; // when not available
162 // if (st.Error().HesseFailed() || st.Error().InvertFailed() ) fCovStatus = -1;
163 // when available
164 if (st.Error().IsAvailable())
165 fCovStatus = 0;
166
167 if (fCovarianceValid) {
168 fCovariance = trafo.Int2extCovariance(st.Vec(), st.Error().InvHessian());
170 MnUserCovariance(std::vector<double>(st.Error().InvHessian().Data(),
171 st.Error().InvHessian().Data() + st.Error().InvHessian().size()),
172 st.Error().InvHessian().Nrow());
173 fCovariance.Scale(2. * up);
176
177 assert(fCovariance.Nrow() == VariableParameters());
178
179 fCovStatus = 1; // when is valid
180 }
181 if (st.Error().IsMadePosDef())
182 fCovStatus = 2;
183 if (st.Error().IsAccurate())
184 fCovStatus = 3;
185}
186
188{
189 // invert covariance matrix and return Hessian
190 // need to copy in a MnSymMatrix
191 MnPrint print("MnUserParameterState::Hessian");
192
194 std::copy(fCovariance.Data().begin(), fCovariance.Data().end(), mat.Data());
195 int ifail = Invert(mat);
196 if (ifail != 0) {
197 print.Warn("Inversion failed; return diagonal matrix");
198
200 for (unsigned int i = 0; i < fCovariance.Nrow(); i++) {
201 tmp(i, i) = 1. / fCovariance(i, i);
202 }
203 return tmp;
204 }
205
206 MnUserCovariance hessian(mat.Data(), fCovariance.Nrow());
207 return hessian;
208}
209
210// facade: forward interface of MnUserParameters and MnUserTransformation
211// via MnUserParameterState
212
213const std::vector<MinuitParameter> &MnUserParameterState::MinuitParameters() const
214{
215 // access to parameters (row-wise)
216 return fParameters.Parameters();
217}
218
219std::vector<double> MnUserParameterState::Params() const
220{
221 // access to parameters in column-wise representation
222 return fParameters.Params();
223}
224std::vector<double> MnUserParameterState::Errors() const
225{
226 // access to errors in column-wise representation
227 return fParameters.Errors();
228}
229
231{
232 // access to single Parameter i
233 return fParameters.Parameter(i);
234}
235
236void MnUserParameterState::Add(const std::string &name, double val, double err)
237{
238 MnPrint print("MnUserParameterState::Add");
239
240 // add free Parameter
241 if (fParameters.Add(name, val, err)) {
242 fIntParameters.push_back(val);
243 fCovarianceValid = false;
244 fGCCValid = false;
245 fValid = true;
246 } else {
247 // redefine an existing parameter
248 int i = Index(name);
249 SetValue(i, val);
250 if (Parameter(i).IsConst()) {
251 print.Warn("Cannot modify status of constant parameter", name);
252 return;
253 }
254 SetError(i, err);
255 // release if it was fixed
256 if (Parameter(i).IsFixed())
257 Release(i);
258 }
259}
260
261void MnUserParameterState::Add(const std::string &name, double val, double err, double low, double up)
262{
263 MnPrint print("MnUserParameterState::Add");
264
265 // add limited Parameter
266 if (fParameters.Add(name, val, err, low, up)) {
267 fCovarianceValid = false;
268 fIntParameters.push_back(Ext2int(Index(name), val));
269 fGCCValid = false;
270 fValid = true;
271 } else { // Parameter already exist - just set values
272 int i = Index(name);
273 SetValue(i, val);
274 if (Parameter(i).IsConst()) {
275 print.Warn("Cannot modify status of constant parameter", name);
276 return;
277 }
278 SetError(i, err);
279 SetLimits(i, low, up);
280 // release if it was fixed
281 if (Parameter(i).IsFixed())
282 Release(i);
283 }
284}
285
286void MnUserParameterState::Add(const std::string &name, double val)
287{
288 // add const Parameter
289 if (fParameters.Add(name, val))
290 fValid = true;
291 else
292 SetValue(name, val);
293}
294
295// interaction via external number of Parameter
296
297void MnUserParameterState::Fix(unsigned int e)
298{
299 // fix parameter e (external index)
300 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
301 unsigned int i = IntOfExt(e);
302 if (fCovarianceValid) {
303 // when covariance is valid remove fixed parameter row/column in covariance matrix
304 // use squeeze to remove first from Hessian and obtain then new covariance
307 }
308 fIntParameters.erase(fIntParameters.begin() + i, fIntParameters.begin() + i + 1);
309 }
311 fGCCValid = false;
312}
313
315{
316 // release parameter e (external index)
317 // no-op if parameter is const or if it is not fixed
318 if (Parameter(e).IsConst() || !Parameter(e).IsFixed())
319 return;
321 fCovarianceValid = false;
322 fGCCValid = false;
323 unsigned int i = IntOfExt(e);
324 if (Parameter(e).HasLimits())
325 fIntParameters.insert(fIntParameters.begin() + i, Ext2int(e, Parameter(e).Value()));
326 else
327 fIntParameters.insert(fIntParameters.begin() + i, Parameter(e).Value());
328}
329
330void MnUserParameterState::SetValue(unsigned int e, double val)
331{
332 // set value for parameter e ( external index )
333 fParameters.SetValue(e, val);
334 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
335 unsigned int i = IntOfExt(e);
336 if (Parameter(e).HasLimits())
337 fIntParameters[i] = Ext2int(e, val);
338 else
339 fIntParameters[i] = val;
340 }
341}
342
343void MnUserParameterState::SetError(unsigned int e, double val)
344{
345 // set error for parameter e (external index)
346 fParameters.SetError(e, val);
347}
348
349void MnUserParameterState::SetLimits(unsigned int e, double low, double up)
350{
351 // set limits for parameter e (external index)
352 fParameters.SetLimits(e, low, up);
353 fCovarianceValid = false;
354 fGCCValid = false;
355 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
356 unsigned int i = IntOfExt(e);
357 if (low < fIntParameters[i] && fIntParameters[i] < up)
359 else if (low >= fIntParameters[i])
360 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
361 else
362 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
363 }
364}
365
366void MnUserParameterState::SetUpperLimit(unsigned int e, double up)
367{
368 // set upper limit for parameter e (external index)
370 fCovarianceValid = false;
371 fGCCValid = false;
372 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
373 unsigned int i = IntOfExt(e);
374 if (fIntParameters[i] < up)
376 else
377 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
378 }
379}
380
381void MnUserParameterState::SetLowerLimit(unsigned int e, double low)
382{
383 // set lower limit for parameter e (external index)
385 fCovarianceValid = false;
386 fGCCValid = false;
387 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
388 unsigned int i = IntOfExt(e);
389 if (low < fIntParameters[i])
391 else
392 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
393 }
394}
395
397{
398 // remove limit for parameter e (external index)
400 fCovarianceValid = false;
401 fGCCValid = false;
402 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst())
404}
405
406double MnUserParameterState::Value(unsigned int i) const
407{
408 // get value for parameter e (external index)
409 return fParameters.Value(i);
410}
411double MnUserParameterState::Error(unsigned int i) const
412{
413 // get error for parameter e (external index)
414 return fParameters.Error(i);
415}
416
417// interaction via name of Parameter
418
419void MnUserParameterState::Fix(const std::string &name)
420{
421 Fix(Index(name));
422}
423
424void MnUserParameterState::Release(const std::string &name)
425{
427}
428
429void MnUserParameterState::SetValue(const std::string &name, double val)
430{
431 SetValue(Index(name), val);
432}
433
434void MnUserParameterState::SetError(const std::string &name, double val)
435{
436 SetError(Index(name), val);
437}
438
439void MnUserParameterState::SetLimits(const std::string &name, double low, double up)
440{
441 SetLimits(Index(name), low, up);
442}
443
444void MnUserParameterState::SetUpperLimit(const std::string &name, double up)
445{
447}
448
449void MnUserParameterState::SetLowerLimit(const std::string &name, double low)
450{
451 SetLowerLimit(Index(name), low);
452}
453
455{
457}
458
459double MnUserParameterState::Value(const std::string &name) const
460{
461 return Value(Index(name));
462}
463
464double MnUserParameterState::Error(const std::string &name) const
465{
466 return Error(Index(name));
467}
468
469unsigned int MnUserParameterState::Index(const std::string &name) const
470{
471 // convert name into external number of Parameter
472 return fParameters.Index(name);
473}
474
475const char *MnUserParameterState::Name(unsigned int i) const
476{
477 // convert external number into name of Parameter (API returing a const char *)
478 return fParameters.Name(i);
479}
480const std::string &MnUserParameterState::GetName(unsigned int i) const
481{
482 // convert external number into name of Parameter (new interface returning a string)
483 return fParameters.GetName(i);
484}
485
486// transformation internal <-> external (forward to transformation class)
487
488double MnUserParameterState::Int2ext(unsigned int i, double val) const
489{
490 // internal to external value
491 return fParameters.Trafo().Int2ext(i, val);
492}
493double MnUserParameterState::Ext2int(unsigned int e, double val) const
494{
495 // external to internal value
496 return fParameters.Trafo().Ext2int(e, val);
497}
498unsigned int MnUserParameterState::IntOfExt(unsigned int ext) const
499{
500 // return internal index for external index ext
501 return fParameters.Trafo().IntOfExt(ext);
502}
503unsigned int MnUserParameterState::ExtOfInt(unsigned int internal) const
504{
505 // return external index for internal index internal
506 return fParameters.Trafo().ExtOfInt(internal);
507}
509{
510 // return number of variable parameters
512}
514{
515 // return global parameter precision
516 return fParameters.Precision();
517}
518
520{
521 // set global parameter precision
523}
524
525} // namespace Minuit2
526
527} // namespace ROOT
#define e(i)
Definition RSha256.hxx:103
char name[80]
Definition TGX11.cxx:110
Class describing a symmetric matrix of size n.
Definition LASymMatrix.h:45
const double * Data() const
unsigned int Nrow() const
unsigned int size() const
const MnAlgebraicSymMatrix & InvHessian() const
const MnAlgebraicVector & Dirin() const
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
const MinimumError & Error() const
const MnAlgebraicVector & Vec() const
const MinimumParameters & Parameters() const
class for the individual Minuit Parameter with Name and number; contains the input numbers for the mi...
class to reduce the covariance matrix when a parameter is fixed by removing the corresponding row and...
class for global correlation coefficient
Sets the relative floating point (double) arithmetic precision.
void Warn(const Ts &... args)
Definition MnPrint.h:135
Class containing the covariance matrix data represented as a vector of size n*(n+1)/2 Used to hide in...
const std::vector< double > & Data() const
const MnMachinePrecision & Precision() const
void SetLimits(unsigned int, double, double)
unsigned int Index(const std::string &) const
const std::string & GetName(unsigned int) const
double Int2ext(unsigned int, double) const
const MinuitParameter & Parameter(unsigned int i) const
double Ext2int(unsigned int, double) const
void Add(const std::string &name, double val, double err)
unsigned int ExtOfInt(unsigned int) const
const char * Name(unsigned int) const
MnUserParameterState()
default constructor (invalid state)
const std::vector< ROOT::Minuit2::MinuitParameter > & MinuitParameters() const
facade: forward interface of MnUserParameters and MnUserTransformation
unsigned int IntOfExt(unsigned int) const
API class for the user interaction with the parameters; serves as input to the minimizer as well as o...
double Error(unsigned int) const
std::vector< double > Params() const
access to parameters and errors in column-wise representation
const char * Name(unsigned int) const
const MinuitParameter & Parameter(unsigned int) const
access to single Parameter
unsigned int Index(const std::string &) const
double Value(unsigned int) const
const MnMachinePrecision & Precision() const
void Fix(unsigned int)
interaction via external number of Parameter
void SetLowerLimit(unsigned int, double)
void SetError(unsigned int, double)
void SetValue(unsigned int, double)
const std::vector< ROOT::Minuit2::MinuitParameter > & Parameters() const
access to parameters (row-wise)
const MnUserTransformation & Trafo() const
std::vector< double > Errors() const
const std::string & GetName(unsigned int) const
void SetUpperLimit(unsigned int, double)
bool Add(const std::string &, double, double)
Add free Parameter Name, Value, Error.
void SetLimits(unsigned int, double, double)
class dealing with the transformation between user specified parameters (external) and internal param...
double Ext2int(unsigned int, double) const
MnUserCovariance Int2extCovariance(const MnAlgebraicVector &, const MnAlgebraicSymMatrix &) const
unsigned int ExtOfInt(unsigned int internal) const
const std::vector< MinuitParameter > & Parameters() const
unsigned int IntOfExt(unsigned int) const
double Int2ext(unsigned int, double) const
double Int2extError(unsigned int, double, double) const
CPyCppyy::Parameter Parameter
int Invert(LASymMatrix &)
Definition LaInverse.cxx:21
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.