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
60MnUserParameterState::MnUserParameterState(std::span<const double> par, const MnUserCovariance &cov)
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
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
152 assert(fCovariance.Nrow() == VariableParameters());
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
183 MnUserCovariance hessian(mat.Data(), fCovariance.Nrow());
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
277 fCovariance = cov;
278
279 // compute and add internal covariance matrix
280 MnUserCovariance covsqueezed;
281 if (cov.Nrow() > nrow)
282 covsqueezed = MnCovarianceSqueeze()(cov, nrow);
283 else if (cov.Nrow() == nrow)
284 covsqueezed = cov;
285
286 MnAlgebraicVector params(nrow);
287 for (unsigned int i = 0; i < nrow; i++)
288 params(i) = fParameters.Params()[i];
289
290 MnAlgebraicSymMatrix covmat(nrow);
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
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
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 }
537 return MnGlobalCorrelationCoeff{invHessian};
538}
539
540} // namespace Minuit2
541
542} // namespace ROOT
#define e(i)
Definition RSha256.hxx:103
char name[80]
Definition TGX11.cxx:142
Class describing a symmetric matrix of size n.
Definition MnMatrix.h:438
const double * Data() const
Definition MnMatrix.h:677
unsigned int size() const
Definition MnMatrix.h:681
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: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...
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
MnUserCovariance Ext2intCovariance(const MnAlgebraicVector &, const MnAlgebraicSymMatrix &) const
double Int2ext(unsigned int, double) const
double Int2extError(unsigned int, double, double) const
cppjit::cpyrt::Parameter Parameter
const Int_t n
Definition legend1.C:16
int Invert(LASymMatrix &)
Definition MnMatrix.cxx:296