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 (before minimization)
21//
22MnUserParameterState::MnUserParameterState(std::span<const double> par, std::span<const double> err)
23 : fValid(true), fCovStatus(-1), fParameters(MnUserParameters(par, err)), fIntParameters(par.begin(), par.end())
24{
25}
26
27MnUserParameterState::MnUserParameterState(const MnUserParameters &par) : fValid(true), fCovStatus(-1), fParameters(par)
28{
29 // construct from user parameters (before minimization)
30
31 for (auto const &ipar : MinuitParameters()) {
32 if (ipar.IsConst() || ipar.IsFixed())
33 continue;
34 if (ipar.HasLimits())
35 fIntParameters.push_back(Ext2int(ipar.Number(), ipar.Value()));
36 else
37 fIntParameters.push_back(ipar.Value());
38 }
39}
40
41//
42// construct from user parameters + errors (before minimization)
43//
44MnUserParameterState::MnUserParameterState(std::span<const double> par, std::span<const double> cov, unsigned int nrow)
45 : fValid(true), fCovStatus(-1), fIntParameters(par.begin(), par.end())
46{
47 // construct from user parameters + errors (before minimization) using std::vector for parameter error and // an
48 // std::vector of size n*(n+1)/2 for the covariance matrix and n (rank of cov matrix)
49
50 std::vector<double> err;
51 err.reserve(par.size());
52 for (unsigned int i = 0; i < par.size(); i++) {
53 assert(fCovariance(i, i) > 0.);
54 err.push_back(std::sqrt(fCovariance(i, i)));
55 }
56 fParameters = MnUserParameters(par, err);
58}
59
61 : fValid(true), fCovStatus(-1), fIntParameters(par.begin(), par.end())
62{
63 // construct from user parameters + errors (before minimization) using std::vector (params) and MnUserCovariance
64 // class
65
66 std::vector<double> err;
67 err.reserve(par.size());
68 for (unsigned int i = 0; i < par.size(); i++) {
69 assert(fCovariance(i, i) > 0.);
70 err.push_back(std::sqrt(fCovariance(i, i)));
71 }
72 fParameters = MnUserParameters(par, err);
74}
75
77 : fValid(true), fCovStatus(-1), fParameters(par)
78{
79 // construct from user parameters + errors (before minimization) using
80 // MnUserParameters and MnUserCovariance objects
81
82 for (auto const &ipar : MinuitParameters()) {
83 if (ipar.IsConst() || ipar.IsFixed())
84 continue;
85 if (ipar.HasLimits())
86 fIntParameters.push_back(Ext2int(ipar.Number(), ipar.Value()));
87 else
88 fIntParameters.push_back(ipar.Value());
89 }
90
92}
93
94//
95//
97 : fValid(st.IsValid()), fCovStatus(-1), fFVal(st.Fval()), fEDM(st.Edm()), fNFcn(st.NFcn())
98{
99 //
100 // construct from internal parameters (after minimization)
101 //
102 // std::cout << "build a MnUserParameterState after minimization.." << std::endl;
103
104 for (auto const &ipar : trafo.Parameters()) {
105 if (ipar.IsConst()) {
106 Add(ipar.GetName(), ipar.Value());
107 } else if (ipar.IsFixed()) {
108 Add(ipar.GetName(), ipar.Value(), ipar.Error());
109 if (ipar.HasLimits()) {
110 if (ipar.HasLowerLimit() && ipar.HasUpperLimit())
111 SetLimits(ipar.GetName(), ipar.LowerLimit(), ipar.UpperLimit());
112 else if (ipar.HasLowerLimit() && !ipar.HasUpperLimit())
113 SetLowerLimit(ipar.GetName(), ipar.LowerLimit());
114 else
115 SetUpperLimit(ipar.GetName(), ipar.UpperLimit());
116 }
117 Fix(ipar.GetName());
118 } else if (ipar.HasLimits()) {
119 unsigned int i = trafo.IntOfExt(ipar.Number());
120 double err =
121 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
122 Add(ipar.GetName(), trafo.Int2ext(i, st.Vec()(i)), trafo.Int2extError(i, st.Vec()(i), err));
123 if (ipar.HasLowerLimit() && ipar.HasUpperLimit())
124 SetLimits(ipar.GetName(), ipar.LowerLimit(), ipar.UpperLimit());
125 else if (ipar.HasLowerLimit() && !ipar.HasUpperLimit())
126 SetLowerLimit(ipar.GetName(), ipar.LowerLimit());
127 else
128 SetUpperLimit(ipar.GetName(), ipar.UpperLimit());
129 } else {
130 unsigned int i = trafo.IntOfExt(ipar.Number());
131 double err =
132 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
133 Add(ipar.GetName(), st.Vec()(i), err);
134 }
135 }
136
137 // need to be set afterwards because becore the ::Add method set fCovarianceValid to false
138 fCovarianceValid = st.Error().IsValid();
139
140 fCovStatus = -1; // when not available
141 // if (st.Error().HesseFailed() || st.Error().InvertFailed() ) fCovStatus = -1;
142 // when available
143 if (st.Error().IsAvailable())
144 fCovStatus = 0;
145
146 if (fCovarianceValid) {
147 fCovariance = trafo.Int2extCovariance(st.Vec(), st.Error().InvHessian());
149 MnUserCovariance({st.Error().InvHessian().Data(), st.Error().InvHessian().size()}, st.Error().InvHessian().Nrow());
150 fCovariance.Scale(2. * up);
151
153
154 if (!st.Error().IsNotPosDef())
155 fCovStatus = 1; // when is valid and not NotPosDef
156 }
157 if (st.Error().IsMadePosDef())
158 fCovStatus = 2;
159 if (st.Error().IsAccurate())
160 fCovStatus = 3;
161
162}
163
165{
166 // invert covariance matrix and return Hessian
167 // need to copy in a MnSymMatrix
168 MnPrint print("MnUserParameterState::Hessian");
169
171 std::copy(fCovariance.Data().begin(), fCovariance.Data().end(), mat.Data());
172 int ifail = Invert(mat);
173 if (ifail != 0) {
174 print.Warn("Inversion failed; return diagonal matrix");
175
177 for (unsigned int i = 0; i < fCovariance.Nrow(); i++) {
178 tmp(i, i) = 1. / fCovariance(i, i);
179 }
180 return tmp;
181 }
182
184 return hessian;
185}
186
187// facade: forward interface of MnUserParameters and MnUserTransformation
188// via MnUserParameterState
189
190const std::vector<MinuitParameter> &MnUserParameterState::MinuitParameters() const
191{
192 // access to parameters (row-wise)
193 return fParameters.Parameters();
194}
195
196std::vector<double> MnUserParameterState::Params() const
197{
198 // access to parameters in column-wise representation
199 return fParameters.Params();
200}
201std::vector<double> MnUserParameterState::Errors() const
202{
203 // access to errors in column-wise representation
204 return fParameters.Errors();
205}
206
208{
209 // access to single Parameter i
210 return fParameters.Parameter(i);
211}
212
213void MnUserParameterState::Add(const std::string &name, double val, double err)
214{
215 MnPrint print("MnUserParameterState::Add");
216
217 // add free Parameter
218 if (fParameters.Add(name, val, err)) {
219 fIntParameters.push_back(val);
220 fCovarianceValid = false;
221 fValid = true;
222 } else {
223 // redefine an existing parameter
224 int i = Index(name);
225 SetValue(i, val);
226 if (Parameter(i).IsConst()) {
227 print.Warn("Cannot modify status of constant parameter", name);
228 return;
229 }
230 SetError(i, err);
231 // release if it was fixed
232 if (Parameter(i).IsFixed())
233 Release(i);
234 }
235}
236
237void MnUserParameterState::Add(const std::string &name, double val, double err, double low, double up)
238{
239 MnPrint print("MnUserParameterState::Add");
240
241 // add limited Parameter
242 if (fParameters.Add(name, val, err, low, up)) {
243 fCovarianceValid = false;
244 fIntParameters.push_back(Ext2int(Index(name), val));
245 fValid = true;
246 } else { // Parameter already exist - just set values
247 int i = Index(name);
248 SetValue(i, val);
249 if (Parameter(i).IsConst()) {
250 print.Warn("Cannot modify status of constant parameter", name);
251 return;
252 }
253 SetError(i, err);
254 SetLimits(i, low, up);
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)
262{
263 // add const Parameter
264 if (fParameters.Add(name, val))
265 fValid = true;
266 else
267 SetValue(name, val);
268}
269
271{
272
273 unsigned int nrow = VariableParameters();
274 assert(cov.Nrow() >= nrow);
275
276 // add external covariance matrix
278
279 // compute and add internal covariance matrix
281 if (cov.Nrow() > nrow)
283 else if (cov.Nrow() == nrow)
285
286 MnAlgebraicVector params(nrow);
287 for (unsigned int i = 0; i < nrow; i++)
288 params(i) = fParameters.Params()[i];
289
291 for (unsigned int i = 0; i < nrow; i++)
292 for (unsigned int j = i; j < nrow; j++)
293 covmat(i, j) = covsqueezed(i, j);
294
295 fIntCovariance = fParameters.Trafo().Ext2intCovariance(params, covmat);
296 fIntCovariance.Scale(0.5); //?
297 fCovarianceValid = true;
298 fCovStatus = 0; //?
299}
300
301// interaction via external number of Parameter
302
303void MnUserParameterState::Fix(unsigned int e)
304{
305 // fix parameter e (external index)
306 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
307 unsigned int i = IntOfExt(e);
308 if (fCovarianceValid) {
309 // when covariance is valid remove fixed parameter row/column in covariance matrix
310 // use squeeze to remove first from Hessian and obtain then new covariance
313 }
314 fIntParameters.erase(fIntParameters.begin() + i, fIntParameters.begin() + i + 1);
315 }
317}
318
320{
321 // release parameter e (external index)
322 // no-op if parameter is const or if it is not fixed
323 if (Parameter(e).IsConst() || !Parameter(e).IsFixed())
324 return;
326 fCovarianceValid = false;
327 unsigned int i = IntOfExt(e);
328 if (Parameter(e).HasLimits())
329 fIntParameters.insert(fIntParameters.begin() + i, Ext2int(e, Parameter(e).Value()));
330 else
331 fIntParameters.insert(fIntParameters.begin() + i, Parameter(e).Value());
332}
333
334void MnUserParameterState::SetValue(unsigned int e, double val)
335{
336 // set value for parameter e ( external index )
337 fParameters.SetValue(e, val);
338 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
339 unsigned int i = IntOfExt(e);
340 if (Parameter(e).HasLimits())
341 fIntParameters[i] = Ext2int(e, val);
342 else
343 fIntParameters[i] = val;
344 }
345}
346
347void MnUserParameterState::SetError(unsigned int e, double val)
348{
349 // set error for parameter e (external index)
350 fParameters.SetError(e, val);
351}
352
353void MnUserParameterState::SetLimits(unsigned int e, double low, double up)
354{
355 // set limits for parameter e (external index)
356 fParameters.SetLimits(e, low, up);
357 fCovarianceValid = false;
358 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
359 unsigned int i = IntOfExt(e);
360 if (low < fIntParameters[i] && fIntParameters[i] < up)
362 else if (low >= fIntParameters[i])
363 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
364 else
365 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
366 }
367}
368
369void MnUserParameterState::SetUpperLimit(unsigned int e, double up)
370{
371 // set upper limit for parameter e (external index)
373 fCovarianceValid = false;
374 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
375 unsigned int i = IntOfExt(e);
376 if (fIntParameters[i] < up)
378 else
379 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
380 }
381}
382
383void MnUserParameterState::SetLowerLimit(unsigned int e, double low)
384{
385 // set lower limit for parameter e (external index)
387 fCovarianceValid = false;
388 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
389 unsigned int i = IntOfExt(e);
390 if (low < fIntParameters[i])
392 else
393 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
394 }
395}
396
398{
399 // remove limit for parameter e (external index)
401 fCovarianceValid = 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 returning 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
511 return fParameters.Trafo().VariableParameters();
512}
514{
515 // return global parameter precision
516 return fParameters.Precision();
517}
518
520{
521 // set global parameter precision
523}
524
526{
527 if (!fCovarianceValid) {
528 return MnGlobalCorrelationCoeff{}; // invalidate
529 }
530 int n = fIntCovariance.Nrow();
531 MnAlgebraicSymMatrix invHessian{static_cast<unsigned int>(n)};
532 for (int i = 0; i < n; ++i) {
533 for (int j = 0; j <= i; ++j) {
534 invHessian(i, j) = fIntCovariance(i, j);
535 }
536 }
538}
539
540} // namespace Minuit2
541
542} // namespace ROOT
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:110
Class describing a symmetric matrix of size n.
Definition MnMatrix.h:438
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
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:123
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
MnGlobalCorrelationCoeff GlobalCC() 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
void AddCovariance(const MnUserCovariance &)
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...
const_iterator begin() const
const_iterator end() const
CPyCppyy::Parameter Parameter
const Int_t n
Definition legend1.C:16
int Invert(LASymMatrix &)
Definition MnMatrix.cxx:296