Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
MnUserTransformation.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
12#include "Minuit2/MnMatrix.h"
13
14#include <algorithm>
15#include <cstdio>
16#include <string>
17#include <sstream>
18
19namespace ROOT {
20
21namespace Minuit2 {
22
23class MnParStr {
24
25public:
26 MnParStr(const std::string &name) : fName(name) {}
27
29
30 bool operator()(const MinuitParameter &par) const
31 {
32 // return (strcmp(par.Name(), fName) == 0);
33 return par.GetName() == fName;
34 }
35
36private:
37 const std::string &fName;
38};
39
40MnUserTransformation::MnUserTransformation(std::span<const double> par, std::span<const double> err)
41{
42 // constructor from a vector of parameter values and a vector of errors (step sizes)
43 // class has as data member the transformation objects (all of the types),
44 // the std::vector of MinuitParameter objects and the vector with the index conversions from
45 // internal to external (fExtOfInt)
46
47 fParameters.reserve(par.size());
48 fExtOfInt.reserve(par.size());
49 fCache.reserve(par.size());
50
51 std::string parName;
52 for (unsigned int i = 0; i < par.size(); i++) {
53 std::ostringstream buf;
54 buf << "p" << i;
55 parName = buf.str();
56 Add(parName, par[i], err[i]);
57 }
58}
59
60//#ifdef MINUIT2_THREAD_SAFE
61// this if a thread-safe implementation needed if want to share transformation object between the threads
62std::vector<double> MnUserTransformation::operator()(const MnAlgebraicVector &pstates) const
63{
64 // transform an internal Minuit vector of internal values in a std::vector of external values
65 // fixed parameters will have their fixed values
66 unsigned int n = pstates.size();
67 // need to initialize to the stored (initial values) parameter values for the fixed ones
68 std::vector<double> pcache(fCache);
69 for (unsigned int i = 0; i < n; i++) {
70 if (fParameters[fExtOfInt[i]].HasLimits()) {
71 pcache[fExtOfInt[i]] = Int2ext(i, pstates(i));
72 } else {
73 pcache[fExtOfInt[i]] = pstates(i);
74 }
75 }
76 return pcache;
77}
78
79// #else
80// const std::vector<double> & MnUserTransformation::operator()(const MnAlgebraicVector& pstates) const {
81// // transform an internal Minuit vector of internal values in a std::vector of external values
82// // std::vector<double> Cache(pstates.size() );
83// for(unsigned int i = 0; i < pstates.size(); i++) {
84// if(fParameters[fExtOfInt[i]].HasLimits()) {
85// fCache[fExtOfInt[i]] = Int2ext(i, pstates(i));
86// } else {
87// fCache[fExtOfInt[i]] = pstates(i);
88// }
89// }
90
91// return fCache;
92// }
93// #endif
94
95double MnUserTransformation::Int2ext(unsigned int i, double val) const
96{
97 // return external value from internal value for parameter i
98 if (fParameters[fExtOfInt[i]].HasLimits()) {
99 if (fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit())
100 return fDoubleLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].UpperLimit(),
101 fParameters[fExtOfInt[i]].LowerLimit());
102 else if (fParameters[fExtOfInt[i]].HasUpperLimit() && !fParameters[fExtOfInt[i]].HasLowerLimit())
103 return fUpperLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].UpperLimit());
104 else
105 return fLowerLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].LowerLimit());
106 }
107
108 return val;
109}
110
111double MnUserTransformation::Int2extError(unsigned int i, double val, double err) const
112{
113 // return external error from internal error for parameter i
114
115 // err = sigma Value == std::sqrt(cov(i,i))
116 double dx = err;
117
118 if (fParameters[fExtOfInt[i]].HasLimits()) {
119 double ui = Int2ext(i, val);
120 double du1 = Int2ext(i, val + dx) - ui;
121 double du2 = Int2ext(i, val - dx) - ui;
122 if (fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit()) {
123 // double al = fParameters[fExtOfInt[i]].Lower();
124 // double ba = fParameters[fExtOfInt[i]].Upper() - al;
125 // double du1 = al + 0.5*(sin(val + dx) + 1.)*ba - ui;
126 // double du2 = al + 0.5*(sin(val - dx) + 1.)*ba - ui;
127 // if(dx > 1.) du1 = ba;
128 if (dx > 1.)
129 du1 = fParameters[fExtOfInt[i]].UpperLimit() - fParameters[fExtOfInt[i]].LowerLimit();
130 dx = 0.5 * (std::fabs(du1) + std::fabs(du2));
131 } else {
132 dx = 0.5 * (std::fabs(du1) + std::fabs(du2));
133 }
134 }
135
136 return dx;
137}
138
141{
142 // return the external covariance matrix from the internal error matrix and the internal parameter value
143 // the vector of internal parameter is needed for the derivatives (Jacobian of the transformation)
144 // Vext(i,j) = Vint(i,j) * dPext(i)/dPint(i) * dPext(j)/dPint(j)
145
147 for (unsigned int i = 0; i < vec.size(); i++) {
148 double dxdi = 1.;
149 if (fParameters[fExtOfInt[i]].HasLimits()) {
150 // dxdi = 0.5*std::fabs((fParameters[fExtOfInt[i]].Upper() -
151 // fParameters[fExtOfInt[i]].Lower())*cos(vec(i)));
152 dxdi = DInt2Ext(i, vec(i));
153 }
154 for (unsigned int j = i; j < vec.size(); j++) {
155 double dxdj = 1.;
156 if (fParameters[fExtOfInt[j]].HasLimits()) {
157 // dxdj = 0.5*std::fabs((fParameters[fExtOfInt[j]].Upper() -
158 // fParameters[fExtOfInt[j]].Lower())*cos(vec(j)));
159 dxdj = DInt2Ext(j, vec(j));
160 }
161 result(i, j) = dxdi * cov(i, j) * dxdj;
162 }
163 // double diag = Int2extError(i, vec(i), std::sqrt(cov(i,i)));
164 // result(i,i) = diag*diag;
165 }
166
167 return result;
168}
169
170double MnUserTransformation::Ext2int(unsigned int i, double val) const
171{
172 // return the internal value for parameter i with external value val
173
174 if (fParameters[i].HasLimits()) {
175 if (fParameters[i].HasUpperLimit() && fParameters[i].HasLowerLimit())
176 return fDoubleLimTrafo.Ext2int(val, fParameters[i].UpperLimit(), fParameters[i].LowerLimit(), Precision());
177 else if (fParameters[i].HasUpperLimit() && !fParameters[i].HasLowerLimit())
178 return fUpperLimTrafo.Ext2int(val, fParameters[i].UpperLimit(), Precision());
179 else
180 return fLowerLimTrafo.Ext2int(val, fParameters[i].LowerLimit(), Precision());
181 }
182
183 return val;
184}
185
186double MnUserTransformation::DInt2Ext(unsigned int i, double val) const
187{
188 // return the derivative of the int->ext transformation: dPext(i) / dPint(i)
189 // for the parameter i with value val
190
191 double dd = 1.;
192 if (fParameters[fExtOfInt[i]].HasLimits()) {
193 if (fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit())
194 // dd = 0.5*std::fabs((fParameters[fExtOfInt[i]].Upper() -
195 // fParameters[fExtOfInt[i]].Lower())*cos(vec(i)));
196 dd = fDoubleLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].UpperLimit(),
197 fParameters[fExtOfInt[i]].LowerLimit());
198 else if (fParameters[fExtOfInt[i]].HasUpperLimit() && !fParameters[fExtOfInt[i]].HasLowerLimit())
199 dd = fUpperLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].UpperLimit());
200 else
201 dd = fLowerLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].LowerLimit());
202 }
203
204 return dd;
205}
206
207/*
208 double MnUserTransformation::dExt2Int(unsigned int, double) const {
209 double dd = 1.;
210
211 if(fParameters[fExtOfInt[i]].HasLimits()) {
212 if(fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit())
213 // dd = 0.5*std::fabs((fParameters[fExtOfInt[i]].Upper() -
214 fParameters[fExtOfInt[i]].Lower())*cos(vec(i))); dd = fDoubleLimTrafo.dExt2Int(val,
215 fParameters[fExtOfInt[i]].UpperLimit(), fParameters[fExtOfInt[i]].LowerLimit()); else
216 if(fParameters[fExtOfInt[i]].HasUpperLimit() && !fParameters[fExtOfInt[i]].HasLowerLimit()) dd =
217 fUpperLimTrafo.dExt2Int(val, fParameters[fExtOfInt[i]].UpperLimit()); else dd = fLowerLimTrafo.dExtInt(val,
218 fParameters[fExtOfInt[i]].LowerLimit());
219 }
220
221 return dd;
222 }
223 */
224
225unsigned int MnUserTransformation::IntOfExt(unsigned int ext) const
226{
227 // return internal index given external one ext
228 assert(ext < fParameters.size());
229 assert(!fParameters[ext].IsFixed());
230 assert(!fParameters[ext].IsConst());
231 auto iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), ext);
232 assert(iind != fExtOfInt.end());
233
234 return (iind - fExtOfInt.begin());
235}
236
237std::vector<double> MnUserTransformation::Params() const
238{
239 // return std::vector of double with parameter values
240 unsigned int n = fParameters.size();
241 std::vector<double> result(n);
242 for (unsigned int i = 0; i < n; ++i)
243 result[i] = fParameters[i].Value();
244
245 return result;
246}
247
248std::vector<double> MnUserTransformation::Errors() const
249{
250 // return std::vector of double with parameter errors
251 std::vector<double> result;
252 result.reserve(fParameters.size());
253 for (auto const &ipar : Parameters()) {
254 result.push_back(ipar.Error());
255 }
256
257 return result;
258}
259
261{
262 // return the MinuitParameter object for index n (external)
263 assert(n < fParameters.size());
264 return fParameters[n];
265}
266
267// bool MnUserTransformation::Remove(const std::string & name) {
268// // remove parameter with name
269// // useful if want to re-define a parameter
270// // return false if parameter does not exist
271// auto itr = std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)
272// ); if (itr == fParameters.end() ) return false; int n = itr - fParameters.begin(); if (n < 0 || n >=
273// fParameters.size() ) return false; fParameters.erase(itr); fCache.erase( fExtOfInt.begin() + n);
274// auto iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), n);
275// if (iind != fExtOfInt.end()) fExtOfInt.erase(iind);
276// }
277
278bool MnUserTransformation::Add(const std::string &name, double val, double err)
279{
280 // add a new unlimited parameter giving name, value and err (step size)
281 // return false if parameter already exists
282 if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end())
283 return false;
284 fExtOfInt.push_back(fParameters.size());
285 fCache.push_back(val);
286 fParameters.push_back(MinuitParameter(fParameters.size(), name, val, err));
287 return true;
288}
289
290bool MnUserTransformation::Add(const std::string &name, double val, double err, double low, double up)
291{
292 // add a new limited parameter giving name, value, err (step size) and lower/upper limits
293 // return false if parameter already exists
294 if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end())
295 return false;
296 fExtOfInt.push_back(fParameters.size());
297 fCache.push_back(val);
298 fParameters.push_back(MinuitParameter(fParameters.size(), name, val, err, low, up));
299 return true;
300}
301
302bool MnUserTransformation::Add(const std::string &name, double val)
303{
304 // add a new constant parameter giving name and value
305 // return false if parameter already exists
306 if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end())
307 return false;
308 fCache.push_back(val);
309 // constant parameter - do not add in list of internals (fExtOfInt)
310 fParameters.push_back(MinuitParameter(fParameters.size(), name, val));
311 return true;
312}
313
314void MnUserTransformation::Fix(unsigned int n)
315{
316 // fix parameter n (external index)
317 assert(n < fParameters.size());
318 auto iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), n);
319 if (iind != fExtOfInt.end())
320 fExtOfInt.erase(iind, iind + 1);
321 fParameters[n].Fix();
322}
323
325{
326 // release parameter n (external index)
327 assert(n < fParameters.size());
328 auto iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), n);
329 if (iind == fExtOfInt.end()) {
330 fExtOfInt.push_back(n);
331 std::sort(fExtOfInt.begin(), fExtOfInt.end());
332 }
333 fParameters[n].Release();
334}
335
336void MnUserTransformation::SetValue(unsigned int n, double val)
337{
338 // set value for parameter n (external index)
339 assert(n < fParameters.size());
340 fParameters[n].SetValue(val);
341 fCache[n] = val;
342}
343
344void MnUserTransformation::SetError(unsigned int n, double err)
345{
346 // set error for parameter n (external index)
347 assert(n < fParameters.size());
348 fParameters[n].SetError(err);
349}
350
351void MnUserTransformation::SetLimits(unsigned int n, double low, double up)
352{
353 // set limits (lower/upper) for parameter n (external index)
354 assert(n < fParameters.size());
355 assert(low != up);
356 fParameters[n].SetLimits(low, up);
357}
358
359void MnUserTransformation::SetUpperLimit(unsigned int n, double up)
360{
361 // set upper limit for parameter n (external index)
362 assert(n < fParameters.size());
363 fParameters[n].SetUpperLimit(up);
364}
365
366void MnUserTransformation::SetLowerLimit(unsigned int n, double lo)
367{
368 // set lower limit for parameter n (external index)
369 assert(n < fParameters.size());
370 fParameters[n].SetLowerLimit(lo);
371}
372
374{
375 // remove limits for parameter n (external index)
376 assert(n < fParameters.size());
377 fParameters[n].RemoveLimits();
378}
379
380void MnUserTransformation::SetName(unsigned int n, const std::string &name)
381{
382 // set name for parameter n (external index)
383 assert(n < fParameters.size());
384 fParameters[n].SetName(name);
385}
386
387double MnUserTransformation::Value(unsigned int n) const
388{
389 // get value for parameter n (external index)
390 assert(n < fParameters.size());
391 return fParameters[n].Value();
392}
393
394double MnUserTransformation::Error(unsigned int n) const
395{
396 // get error for parameter n (external index)
397 assert(n < fParameters.size());
398 return fParameters[n].Error();
399}
400
401// interface by parameter name
402
403void MnUserTransformation::Fix(const std::string &name)
404{
405 // fix parameter
406 Fix(Index(name));
407}
408
409void MnUserTransformation::Release(const std::string &name)
410{
411 // release parameter
413}
414
415void MnUserTransformation::SetValue(const std::string &name, double val)
416{
417 // set value for parameter
418 SetValue(Index(name), val);
419}
420
421void MnUserTransformation::SetError(const std::string &name, double err)
422{
423 // set error
424 SetError(Index(name), err);
425}
426
427void MnUserTransformation::SetLimits(const std::string &name, double low, double up)
428{
429 // set lower/upper limits
430 SetLimits(Index(name), low, up);
431}
432
433void MnUserTransformation::SetUpperLimit(const std::string &name, double up)
434{
435 // set upper limit
437}
438
439void MnUserTransformation::SetLowerLimit(const std::string &name, double lo)
440{
441 // set lower limit
443}
444
446{
447 // remove limits
449}
450
451double MnUserTransformation::Value(const std::string &name) const
452{
453 // get parameter value
454 return Value(Index(name));
455}
456
457double MnUserTransformation::Error(const std::string &name) const
458{
459 // get parameter error
460 return Error(Index(name));
461}
462
463unsigned int MnUserTransformation::Index(const std::string &name) const
464{
465 // get index (external) corresponding to name
466 auto ipar = std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name));
467 assert(ipar != fParameters.end());
468 // return (ipar - fParameters.begin());
469 return (*ipar).Number();
470}
471
472int MnUserTransformation::FindIndex(const std::string &name) const
473{
474 // find index (external) corresponding to name - return -1 if not found
475 auto ipar = std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name));
476 if (ipar == fParameters.end())
477 return -1;
478 return (*ipar).Number();
479}
480
481const std::string &MnUserTransformation::GetName(unsigned int n) const
482{
483 // get name corresponding to index (external)
484 assert(n < fParameters.size());
485 return fParameters[n].GetName();
486}
487
488const char *MnUserTransformation::Name(unsigned int n) const
489{
490 // get name corresponding to index (external)
491 return GetName(n).c_str();
492}
493
494} // namespace Minuit2
495
496} // namespace ROOT
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
char name[80]
Definition TGX11.cxx:110
Class describing a symmetric matrix of size n.
Definition LASymMatrix.h:45
unsigned int Nrow() const
unsigned int size() const
Definition LAVector.h:231
class for the individual Minuit Parameter with Name and number; contains the input numbers for the mi...
const std::string & GetName() const
MnParStr(const std::string &name)
bool operator()(const MinuitParameter &par) const
Class containing the covariance matrix data represented as a vector of size n*(n+1)/2 Used to hide in...
double Ext2int(unsigned int, double) const
MnUserCovariance Int2extCovariance(const MnAlgebraicVector &, const MnAlgebraicSymMatrix &) const
bool Add(const std::string &, double, double)
double DInt2Ext(unsigned int, double) const
void SetName(unsigned int, const std::string &)
std::vector< MinuitParameter > fParameters
std::vector< double > operator()(const MnAlgebraicVector &) const
const std::vector< MinuitParameter > & Parameters() const
unsigned int IntOfExt(unsigned int) const
const char * Name(unsigned int) const
std::vector< unsigned int > fExtOfInt
std::vector< double > Params() const
access to parameters and errors in column-wise representation
SqrtLowParameterTransformation fLowerLimTrafo
int FindIndex(const std::string &) const
double Int2ext(unsigned int, double) const
unsigned int Index(const std::string &) const
SinParameterTransformation fDoubleLimTrafo
const std::string & GetName(unsigned int) const
void SetLimits(unsigned int, double, double)
double Int2extError(unsigned int, double, double) const
const MnMachinePrecision & Precision() const
forwarded interface
SqrtUpParameterTransformation fUpperLimTrafo
const MinuitParameter & Parameter(unsigned int) const
long double DInt2Ext(long double Value, long double Upper, long double Lower) const
long double Int2ext(long double Value, long double Upper, long double Lower) const
long double Ext2int(long double Value, long double Upper, long double Lower, const MnMachinePrecision &) const
long double Ext2int(long double Value, long double Lower, const MnMachinePrecision &) const
long double DInt2Ext(long double Value, long double Lower) const
long double Int2ext(long double Value, long double Lower) const
long double Int2ext(long double Value, long double Upper) const
long double DInt2Ext(long double Value, long double Upper) const
long double Ext2int(long double Value, long double Upper, const MnMachinePrecision &) const
const Int_t n
Definition legend1.C:16
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...