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), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
24 fParameters(MnUserParameters(par, err)),
25 fIntParameters(par.begin(), par.end())
26{
27}
28
30 : fValid(true), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0),
31 fParameters(par)
32{
33 // construct from user parameters (before minimization)
34
35 for (auto const &ipar : MinuitParameters()) {
36 if (ipar.IsConst() || ipar.IsFixed())
37 continue;
38 if (ipar.HasLimits())
39 fIntParameters.push_back(Ext2int(ipar.Number(), ipar.Value()));
40 else
41 fIntParameters.push_back(ipar.Value());
42 }
43}
44
45//
46// construct from user parameters + errors (before minimization)
47//
48MnUserParameterState::MnUserParameterState(std::span<const double> par, std::span<const double> cov, unsigned int nrow)
49 : fValid(true),
50 fGCCValid(false),
51 fCovStatus(-1),
52 fFVal(0.),
53 fEDM(0.),
54 fNFcn(0),
55 fIntParameters(par.begin(), par.end())
56{
57 // construct from user parameters + errors (before minimization) using std::vector for parameter error and // an
58 // std::vector of size n*(n+1)/2 for the covariance matrix and n (rank of cov matrix)
59
60 std::vector<double> err;
61 err.reserve(par.size());
62 for (unsigned int i = 0; i < par.size(); i++) {
63 assert(fCovariance(i, i) > 0.);
64 err.push_back(std::sqrt(fCovariance(i, i)));
65 }
66 fParameters = MnUserParameters(par, err);
68}
69
70MnUserParameterState::MnUserParameterState(std::span<const double> par, const MnUserCovariance &cov)
71 : fValid(true),
72 fGCCValid(false),
73 fCovStatus(-1),
74 fFVal(0.),
75 fEDM(0.),
76 fNFcn(0),
77 fIntParameters(par.begin(), par.end())
78{
79 // construct from user parameters + errors (before minimization) using std::vector (params) and MnUserCovariance
80 // class
81
82 std::vector<double> err;
83 err.reserve(par.size());
84 for (unsigned int i = 0; i < par.size(); i++) {
85 assert(fCovariance(i, i) > 0.);
86 err.push_back(std::sqrt(fCovariance(i, i)));
87 }
88 fParameters = MnUserParameters(par, err);
90}
91
93 : fValid(true), fGCCValid(false), fCovStatus(-1), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(par)
94{
95 // construct from user parameters + errors (before minimization) using
96 // MnUserParameters and MnUserCovariance objects
97
98 for (auto const &ipar : MinuitParameters()) {
99 if (ipar.IsConst() || ipar.IsFixed())
100 continue;
101 if (ipar.HasLimits())
102 fIntParameters.push_back(Ext2int(ipar.Number(), ipar.Value()));
103 else
104 fIntParameters.push_back(ipar.Value());
105 }
106
108}
109
110//
111//
113 : fValid(st.IsValid()), fCovarianceValid(false), fGCCValid(false), fCovStatus(-1), fFVal(st.Fval()), fEDM(st.Edm()),
114 fNFcn(st.NFcn())
115{
116 //
117 // construct from internal parameters (after minimization)
118 //
119 // std::cout << "build a MnUserParameterState after minimization.." << std::endl;
120
121 for (auto const &ipar : trafo.Parameters()) {
122 if (ipar.IsConst()) {
123 Add(ipar.GetName(), ipar.Value());
124 } else if (ipar.IsFixed()) {
125 Add(ipar.GetName(), ipar.Value(), ipar.Error());
126 if (ipar.HasLimits()) {
127 if (ipar.HasLowerLimit() && ipar.HasUpperLimit())
128 SetLimits(ipar.GetName(), ipar.LowerLimit(), ipar.UpperLimit());
129 else if (ipar.HasLowerLimit() && !ipar.HasUpperLimit())
130 SetLowerLimit(ipar.GetName(), ipar.LowerLimit());
131 else
132 SetUpperLimit(ipar.GetName(), ipar.UpperLimit());
133 }
134 Fix(ipar.GetName());
135 } else if (ipar.HasLimits()) {
136 unsigned int i = trafo.IntOfExt(ipar.Number());
137 double err =
138 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
139 Add(ipar.GetName(), trafo.Int2ext(i, st.Vec()(i)), trafo.Int2extError(i, st.Vec()(i), err));
140 if (ipar.HasLowerLimit() && ipar.HasUpperLimit())
141 SetLimits(ipar.GetName(), ipar.LowerLimit(), ipar.UpperLimit());
142 else if (ipar.HasLowerLimit() && !ipar.HasUpperLimit())
143 SetLowerLimit(ipar.GetName(), ipar.LowerLimit());
144 else
145 SetUpperLimit(ipar.GetName(), ipar.UpperLimit());
146 } else {
147 unsigned int i = trafo.IntOfExt(ipar.Number());
148 double err =
149 st.Error().IsValid() ? std::sqrt(2. * up * st.Error().InvHessian()(i, i)) : st.Parameters().Dirin()(i);
150 Add(ipar.GetName(), st.Vec()(i), err);
151 }
152 }
153
154 // need to be set afterwards because becore the ::Add method set fCovarianceValid to false
156
157 fCovStatus = -1; // when not available
158 // if (st.Error().HesseFailed() || st.Error().InvertFailed() ) fCovStatus = -1;
159 // when available
160 if (st.Error().IsAvailable())
161 fCovStatus = 0;
162
163 if (fCovarianceValid) {
164 fCovariance = trafo.Int2extCovariance(st.Vec(), st.Error().InvHessian());
166 MnUserCovariance({st.Error().InvHessian().Data(), st.Error().InvHessian().size()}, st.Error().InvHessian().Nrow());
167 fCovariance.Scale(2. * up);
170
171 assert(fCovariance.Nrow() == VariableParameters());
172
173 if (!st.Error().IsNotPosDef())
174 fCovStatus = 1; // when is valid and not NotPosDef
175 }
176 if (st.Error().IsMadePosDef())
177 fCovStatus = 2;
178 if (st.Error().IsAccurate())
179 fCovStatus = 3;
180
181}
182
184{
185 // invert covariance matrix and return Hessian
186 // need to copy in a MnSymMatrix
187 MnPrint print("MnUserParameterState::Hessian");
188
190 std::copy(fCovariance.Data().begin(), fCovariance.Data().end(), mat.Data());
191 int ifail = Invert(mat);
192 if (ifail != 0) {
193 print.Warn("Inversion failed; return diagonal matrix");
194
196 for (unsigned int i = 0; i < fCovariance.Nrow(); i++) {
197 tmp(i, i) = 1. / fCovariance(i, i);
198 }
199 return tmp;
200 }
201
202 MnUserCovariance hessian(mat.Data(), fCovariance.Nrow());
203 return hessian;
204}
205
206// facade: forward interface of MnUserParameters and MnUserTransformation
207// via MnUserParameterState
208
209const std::vector<MinuitParameter> &MnUserParameterState::MinuitParameters() const
210{
211 // access to parameters (row-wise)
212 return fParameters.Parameters();
213}
214
215std::vector<double> MnUserParameterState::Params() const
216{
217 // access to parameters in column-wise representation
218 return fParameters.Params();
219}
220std::vector<double> MnUserParameterState::Errors() const
221{
222 // access to errors in column-wise representation
223 return fParameters.Errors();
224}
225
227{
228 // access to single Parameter i
229 return fParameters.Parameter(i);
230}
231
232void MnUserParameterState::Add(const std::string &name, double val, double err)
233{
234 MnPrint print("MnUserParameterState::Add");
235
236 // add free Parameter
237 if (fParameters.Add(name, val, err)) {
238 fIntParameters.push_back(val);
239 fCovarianceValid = false;
240 fGCCValid = false;
241 fValid = true;
242 } else {
243 // redefine an existing parameter
244 int i = Index(name);
245 SetValue(i, val);
246 if (Parameter(i).IsConst()) {
247 print.Warn("Cannot modify status of constant parameter", name);
248 return;
249 }
250 SetError(i, err);
251 // release if it was fixed
252 if (Parameter(i).IsFixed())
253 Release(i);
254 }
255}
256
257void MnUserParameterState::Add(const std::string &name, double val, double err, double low, double up)
258{
259 MnPrint print("MnUserParameterState::Add");
260
261 // add limited Parameter
262 if (fParameters.Add(name, val, err, low, up)) {
263 fCovarianceValid = false;
264 fIntParameters.push_back(Ext2int(Index(name), val));
265 fGCCValid = false;
266 fValid = true;
267 } else { // Parameter already exist - just set values
268 int i = Index(name);
269 SetValue(i, val);
270 if (Parameter(i).IsConst()) {
271 print.Warn("Cannot modify status of constant parameter", name);
272 return;
273 }
274 SetError(i, err);
275 SetLimits(i, low, up);
276 // release if it was fixed
277 if (Parameter(i).IsFixed())
278 Release(i);
279 }
280}
281
282void MnUserParameterState::Add(const std::string &name, double val)
283{
284 // add const Parameter
285 if (fParameters.Add(name, val))
286 fValid = true;
287 else
288 SetValue(name, val);
289}
290
292{
293
294 unsigned int nrow = VariableParameters();
295 assert(cov.Nrow() >= nrow);
296
297 // add external covariance matrix
298 fCovariance = cov;
299
300 // compute and add internal covariance matrix
301 MnUserCovariance covsqueezed;
302 if (cov.Nrow() > nrow)
303 covsqueezed = MnCovarianceSqueeze()(cov, nrow);
304 else if (cov.Nrow() == nrow)
305 covsqueezed = cov;
306
307 MnAlgebraicVector params(nrow);
308 for (unsigned int i = 0; i < nrow; i++)
309 params(i) = fParameters.Params()[i];
310
311 MnAlgebraicSymMatrix covmat(nrow);
312 for (unsigned int i = 0; i < nrow; i++)
313 for (unsigned int j = i; j < nrow; j++)
314 covmat(i, j) = covsqueezed(i, j);
315
317 fIntCovariance.Scale(0.5); //?
318 fCovarianceValid = true;
319 fCovStatus = 0; //?
320}
321
322// interaction via external number of Parameter
323
324void MnUserParameterState::Fix(unsigned int e)
325{
326 // fix parameter e (external index)
327 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
328 unsigned int i = IntOfExt(e);
329 if (fCovarianceValid) {
330 // when covariance is valid remove fixed parameter row/column in covariance matrix
331 // use squeeze to remove first from Hessian and obtain then new covariance
334 }
335 fIntParameters.erase(fIntParameters.begin() + i, fIntParameters.begin() + i + 1);
336 }
338 fGCCValid = false;
339}
340
342{
343 // release parameter e (external index)
344 // no-op if parameter is const or if it is not fixed
345 if (Parameter(e).IsConst() || !Parameter(e).IsFixed())
346 return;
348 fCovarianceValid = false;
349 fGCCValid = false;
350 unsigned int i = IntOfExt(e);
351 if (Parameter(e).HasLimits())
352 fIntParameters.insert(fIntParameters.begin() + i, Ext2int(e, Parameter(e).Value()));
353 else
354 fIntParameters.insert(fIntParameters.begin() + i, Parameter(e).Value());
355}
356
357void MnUserParameterState::SetValue(unsigned int e, double val)
358{
359 // set value for parameter e ( external index )
360 fParameters.SetValue(e, val);
361 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
362 unsigned int i = IntOfExt(e);
363 if (Parameter(e).HasLimits())
364 fIntParameters[i] = Ext2int(e, val);
365 else
366 fIntParameters[i] = val;
367 }
368}
369
370void MnUserParameterState::SetError(unsigned int e, double val)
371{
372 // set error for parameter e (external index)
373 fParameters.SetError(e, val);
374}
375
376void MnUserParameterState::SetLimits(unsigned int e, double low, double up)
377{
378 // set limits for parameter e (external index)
379 fParameters.SetLimits(e, low, up);
380 fCovarianceValid = false;
381 fGCCValid = false;
382 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
383 unsigned int i = IntOfExt(e);
384 if (low < fIntParameters[i] && fIntParameters[i] < up)
386 else if (low >= fIntParameters[i])
387 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
388 else
389 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
390 }
391}
392
393void MnUserParameterState::SetUpperLimit(unsigned int e, double up)
394{
395 // set upper limit for parameter e (external index)
397 fCovarianceValid = false;
398 fGCCValid = false;
399 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
400 unsigned int i = IntOfExt(e);
401 if (fIntParameters[i] < up)
403 else
404 fIntParameters[i] = Ext2int(e, up - 0.1 * Parameter(e).Error());
405 }
406}
407
408void MnUserParameterState::SetLowerLimit(unsigned int e, double low)
409{
410 // set lower limit for parameter e (external index)
412 fCovarianceValid = false;
413 fGCCValid = false;
414 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
415 unsigned int i = IntOfExt(e);
416 if (low < fIntParameters[i])
418 else
419 fIntParameters[i] = Ext2int(e, low + 0.1 * Parameter(e).Error());
420 }
421}
422
424{
425 // remove limit for parameter e (external index)
427 fCovarianceValid = false;
428 fGCCValid = false;
429 if (!Parameter(e).IsFixed() && !Parameter(e).IsConst())
431}
432
433double MnUserParameterState::Value(unsigned int i) const
434{
435 // get value for parameter e (external index)
436 return fParameters.Value(i);
437}
438double MnUserParameterState::Error(unsigned int i) const
439{
440 // get error for parameter e (external index)
441 return fParameters.Error(i);
442}
443
444// interaction via name of Parameter
445
446void MnUserParameterState::Fix(const std::string &name)
447{
448 Fix(Index(name));
449}
450
451void MnUserParameterState::Release(const std::string &name)
452{
454}
455
456void MnUserParameterState::SetValue(const std::string &name, double val)
457{
458 SetValue(Index(name), val);
459}
460
461void MnUserParameterState::SetError(const std::string &name, double val)
462{
463 SetError(Index(name), val);
464}
465
466void MnUserParameterState::SetLimits(const std::string &name, double low, double up)
467{
468 SetLimits(Index(name), low, up);
469}
470
471void MnUserParameterState::SetUpperLimit(const std::string &name, double up)
472{
474}
475
476void MnUserParameterState::SetLowerLimit(const std::string &name, double low)
477{
478 SetLowerLimit(Index(name), low);
479}
480
482{
484}
485
486double MnUserParameterState::Value(const std::string &name) const
487{
488 return Value(Index(name));
489}
490
491double MnUserParameterState::Error(const std::string &name) const
492{
493 return Error(Index(name));
494}
495
496unsigned int MnUserParameterState::Index(const std::string &name) const
497{
498 // convert name into external number of Parameter
499 return fParameters.Index(name);
500}
501
502const char *MnUserParameterState::Name(unsigned int i) const
503{
504 // convert external number into name of Parameter (API returning a const char *)
505 return fParameters.Name(i);
506}
507const std::string &MnUserParameterState::GetName(unsigned int i) const
508{
509 // convert external number into name of Parameter (new interface returning a string)
510 return fParameters.GetName(i);
511}
512
513// transformation internal <-> external (forward to transformation class)
514
515double MnUserParameterState::Int2ext(unsigned int i, double val) const
516{
517 // internal to external value
518 return fParameters.Trafo().Int2ext(i, val);
519}
520double MnUserParameterState::Ext2int(unsigned int e, double val) const
521{
522 // external to internal value
523 return fParameters.Trafo().Ext2int(e, val);
524}
525unsigned int MnUserParameterState::IntOfExt(unsigned int ext) const
526{
527 // return internal index for external index ext
528 return fParameters.Trafo().IntOfExt(ext);
529}
530unsigned int MnUserParameterState::ExtOfInt(unsigned int internal) const
531{
532 // return external index for internal index internal
533 return fParameters.Trafo().ExtOfInt(internal);
534}
536{
537 // return number of variable parameters
539}
541{
542 // return global parameter precision
543 return fParameters.Precision();
544}
545
547{
548 // set global parameter precision
550}
551
552} // namespace Minuit2
553
554} // 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 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
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
CPyCppyy::Parameter Parameter
int Invert(LASymMatrix &)
Definition LaInverse.cxx:21
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...