CMS 3D CMS Logo

RootMinuit.h
Go to the documentation of this file.
1 #ifndef PhisycsTools_Utilities_RootMinuit_h
2 #define PhisycsTools_Utilities_RootMinuit_h
3 
11 #include "TMinuit.h"
12 #include "Math/SMatrix.h"
13 
14 #include <vector>
15 #include <string>
16 #include <memory>
17 
18 namespace fit {
19 
20  template <class Function>
21  class RootMinuit {
22  public:
24  f_ = f;
25  }
26  void addParameter(const std::string &name, std::shared_ptr<double> val, double err, double min, double max) {
27  if (initialized_)
29  << "RootMinuit: can't add parameter " << name << " after minuit initialization\n";
30  pars_.push_back(val);
31  parameter_t par;
32  par.val = *val;
33  par.err = err;
34  par.min = min;
35  par.max = max;
36  par.fixed = false;
37  parMap_.push_back(std::make_pair(name, par));
38  size_t s = parIndices_.size();
39  parIndices_[name] = s;
40  }
41  void addParameter(const funct::Parameter &par, double err, double min, double max) {
42  return addParameter(par.name(), par, err, min, max);
43  }
44  double getParameter(const std::string &name, double &err) {
45  double val;
46  init();
47  minuit_->GetParameter(parameterIndex(name), val, err);
48  return val;
49  }
50  double getParameter(const std::string &name) {
51  double val, err;
52  init();
53  minuit_->GetParameter(parameterIndex(name), val, err);
54  return val;
55  }
56  double getParameterError(const std::string &name, double &val) {
57  double err;
58  init();
59  minuit_->GetParameter(parameterIndex(name), val, err);
60  return err;
61  }
63  double val, err;
64  init();
65  minuit_->GetParameter(parameterIndex(name), val, err);
66  return err;
67  }
68  template <unsigned int N>
69  void getErrorMatrix(ROOT::Math::SMatrix<double, N, N, ROOT::Math::MatRepSym<double, N> > &err) {
70  init();
71  if (N != numberOfParameters())
73  << "RootMinuit: can't call getErrorMatrix passing an SMatrix of dimension " << N
74  << " while the number of parameters is " << numberOfParameters() << "\n";
75  double *e = new double[N * N];
76  minuit_->mnemat(e, numberOfParameters());
77  for (size_t i = 0; i < N; ++i) {
78  for (size_t j = 0; j <= i; ++j) {
79  err(i, j) = e[i + N * j];
80  }
81  }
82  delete[] e;
83  setParameters();
84  }
85  void fixParameter(const std::string &name) {
86  size_t i = parameterIndex(name);
87  parMap_[i].second.fixed = true;
88  if (initialized_) {
89  minuit_->FixParameter(i);
90  }
91  }
93  size_t i = parameterIndex(name);
94  parMap_[i].second.fixed = false;
95  if (initialized_) {
96  minuit_->Release(i);
97  }
98  }
99  void setParameter(const std::string &name, double val) {
100  size_t i = parameterIndex(name);
101  parameter_t &par = parMap_[i].second;
102  par.val = val;
103  if (initialized_) {
104  int ierflg = 0;
105  minuit_->mnparm(i, name, par.val, par.err, par.min, par.max, ierflg);
106  if (ierflg != 0)
108  << "RootMinuit: error in setting parameter " << i << " value = " << par.val << " error = " << par.err
109  << " range = [" << par.min << ", " << par.max << "]\n";
110  }
111  }
112  void setParameters() {
113  std::map<std::string, size_t>::const_iterator i = parIndices_.begin(), end = parIndices_.end();
114  double val, err;
115  for (; i != end; ++i) {
116  size_t index = i->second;
117  minuit_->GetParameter(index, val, err);
118  *pars_[index] = val;
119  }
120  }
122  init();
123  return minuit_->GetNumPars();
124  }
126  init();
127  return minuit_->GetNumFreePars();
128  }
129  double minimize() {
130  init();
131  double arglist[10];
132  arglist[0] = 5000;
133  arglist[1] = 0.1;
134  int ierflag;
135  minuit_->mnexcm("MINIMIZE", arglist, 2, ierflag);
136  if (ierflag != 0)
137  std::cerr << "ERROR in minimize!!" << std::endl;
138  if (verbose_)
139  minuit_->mnmatu(1); //Prints the covariance matrix
140  double m = minValue();
141  if (verbose_)
142  minuit_->mnprin(3, m);
143  setParameters();
144  return m;
145  }
146  double migrad() {
147  init();
148  double arglist[10];
149  arglist[0] = 5000;
150  arglist[1] = 0.1;
151  int ierflag;
152  minuit_->mnexcm("MIGRAD", arglist, 2, ierflag);
153  if (ierflag != 0)
154  std::cerr << "ERROR in migrad!!" << std::endl;
155  if (verbose_)
156  minuit_->mnmatu(1); //Prints the covariance matrix
157  double m = minValue();
158  if (verbose_)
159  minuit_->mnprin(3, m);
160  setParameters();
161  return m;
162  }
163  double minValue() {
164  init();
165  int ierflag;
166  double edm, errdef;
167  int nvpar, nparx;
168  minuit_->mnstat(minValue_, edm, errdef, nvpar, nparx, ierflag);
169  return minValue_;
170  }
171  void printParameters(std::ostream &cout = std::cout) {
172  std::map<std::string, size_t>::const_iterator i = parIndices_.begin(), end = parIndices_.end();
173  for (; i != end; ++i) {
174  cout << i->first << " = " << *pars_[i->second] << " +/- " << getParameterError(i->first) << std::endl;
175  }
176  }
177  void printFitResults(std::ostream &cout = std::cout) {
180  }
181 
182  private:
184  std::map<std::string, size_t> parIndices_;
186  double minValue_;
187  std::unique_ptr<TMinuit> minuit_;
188  std::vector<std::shared_ptr<double> > pars_;
189  static std::vector<std::shared_ptr<double> > *fPars_;
190  bool verbose_;
191  static Function f_;
192  static void fcn_(int &, double *, double &f, double *par, int) {
193  size_t size = fPars_->size();
194  for (size_t i = 0; i < size; ++i)
195  *((*fPars_)[i]) = par[i];
197  }
198  size_t parameterIndex(const std::string &name) const {
199  typename std::map<std::string, size_t>::const_iterator p = parIndices_.find(name);
200  if (p == parIndices_.end())
201  throw edm::Exception(edm::errors::Configuration) << "RootMinuit: can't find parameter " << name << "\n";
202  return p->second;
203  }
204  void init() {
205  if (initialized_)
206  return;
207  minuit_.reset(new TMinuit(parMap_.size()));
208  double arglist[10];
209  int ierflg = 0;
210  if (!verbose_) {
211  arglist[0] = -1;
212  minuit_->mnexcm("SET PRINT", arglist, 1, ierflg);
213  if (ierflg != 0)
214  throw edm::Exception(edm::errors::Configuration) << "RootMinuit: error in calling SET PRINT\n";
215  }
216  arglist[0] = 1;
217  minuit_->mnexcm("SET ERR", arglist, 1, ierflg);
218  if (ierflg != 0)
219  throw edm::Exception(edm::errors::Configuration) << "RootMinuit: error in calling SET ERR\n";
220 
221  size_t i = 0;
222  typename parameterVector_t::const_iterator p = parMap_.begin(), end = parMap_.end();
223  for (; p != end; ++p, ++i) {
224  const std::string &name = p->first;
225  const parameter_t &par = p->second;
226  minuit_->mnparm(i, name, par.val, par.err, par.min, par.max, ierflg);
227  if (ierflg != 0)
229  << "RootMinuit: error in setting parameter " << i << " value = " << par.val << " error = " << par.err
230  << " range = [" << par.min << ", " << par.max << "]\n";
231  }
232  initialized_ = true;
233  for (i = 0, p = parMap_.begin(); p != end; ++p, ++i)
234  if (p->second.fixed)
235  minuit_->FixParameter(i);
236  fPars_ = &pars_;
237  minuit_->SetFCN(fcn_);
238  }
239  };
240 
241  template <class Function>
243 
244  template <class Function>
245  std::vector<std::shared_ptr<double> > *RootMinuit<Function>::fPars_ = nullptr;
246 } // namespace fit
247 
248 #endif
double minValue_
Definition: RootMinuit.h:186
double getParameterError(const std::string &name)
Definition: RootMinuit.h:62
void printParameters(std::ostream &cout=std::cout)
Definition: RootMinuit.h:171
std::vector< std::shared_ptr< double > > pars_
Definition: RootMinuit.h:188
void getErrorMatrix(ROOT::Math::SMatrix< double, N, N, ROOT::Math::MatRepSym< double, N > > &err)
Definition: RootMinuit.h:69
void printFitResults(std::ostream &cout=std::cout)
Definition: RootMinuit.h:177
bool verbose
size_t parameterIndex(const std::string &name) const
Definition: RootMinuit.h:198
void setParameter(const std::string &name, double val)
Definition: RootMinuit.h:99
std::map< std::string, size_t > parIndices_
Definition: RootMinuit.h:184
const std::string & name() const
Definition: Parameter.h:12
void setParameters()
Definition: RootMinuit.h:112
double migrad()
Definition: RootMinuit.h:146
double getParameterError(const std::string &name, double &val)
Definition: RootMinuit.h:56
void fixParameter(const std::string &name)
Definition: RootMinuit.h:85
static void print(double amin, unsigned int numberOfFreeParameters, const Function &f)
RootMinuit(const Function &f, bool verbose=false)
Definition: RootMinuit.h:23
std::vector< std::pair< std::string, parameter_t > > parameterVector_t
Definition: ParameterMap.h:14
double minimize()
Definition: RootMinuit.h:129
int numberOfFreeParameters()
Definition: RootMinuit.h:125
double getParameter(const std::string &name)
Definition: RootMinuit.h:50
double f[11][100]
#define N
Definition: blowfish.cc:9
static Function f_
Definition: RootMinuit.h:191
int numberOfParameters()
Definition: RootMinuit.h:121
std::unique_ptr< TMinuit > minuit_
Definition: RootMinuit.h:187
double getParameter(const std::string &name, double &err)
Definition: RootMinuit.h:44
HLT enums.
void addParameter(const funct::Parameter &par, double err, double min, double max)
Definition: RootMinuit.h:41
static void fcn_(int &, double *, double &f, double *par, int)
Definition: RootMinuit.h:192
parameterVector_t parMap_
Definition: RootMinuit.h:183
static std::vector< std::shared_ptr< double > > * fPars_
Definition: RootMinuit.h:189
static double evaluate(const Function &f)
void releaseParameter(const std::string &name)
Definition: RootMinuit.h:92
double minValue()
Definition: RootMinuit.h:163
void addParameter(const std::string &name, std::shared_ptr< double > val, double err, double min, double max)
Definition: RootMinuit.h:26