Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
FumiliFCNAdapter.h
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Author: L. Moneta 10/2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 ROOT Foundation, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
10#ifndef ROOT_Minuit2_FumiliFCNAdapter
11#define ROOT_Minuit2_FumiliFCNAdapter
12
14
16
17#include "Minuit2/MnPrint.h"
18
19// #ifndef ROOT_Math_Util
20// #include "Math/Util.h"
21// #endif
22
23#include <cmath>
24#include <cassert>
25#include <vector>
26
27namespace ROOT {
28
29namespace Minuit2 {
30
31/**
32
33
34template wrapped class for adapting to FumiliFCNBase signature
35
36@author Lorenzo Moneta
37
38@ingroup Minuit
39
40*/
41
42template <class Function>
44
45public:
46 // typedef ROOT::Math::FitMethodFunction Function;
47 typedef typename Function::Type_t Type_t;
48
49 FumiliFCNAdapter(const Function &f, unsigned int ndim, double up = 1.) : FumiliFCNBase(ndim), fFunc(f), fUp(up) {}
50
51 double operator()(std::vector<double> const &v) const override { return fFunc.operator()(&v[0]); }
52 double operator()(const double *v) const { return fFunc.operator()(v); }
53 double Up() const override { return fUp; }
54
55 void SetErrorDef(double up) override { fUp = up; }
56
57 // virtual std::vector<double> Gradient(std::vector<double> const &) const;
58
59 // forward interface
60 // virtual double operator()(int npar, double* params,int iflag = 4) const;
61
62 /**
63 evaluate gradient hessian and function value needed by fumili
64 */
65 void EvaluateAll(std::vector<double> const &v) override;
66
67private:
69 double fUp;
70};
71
72template <class Function>
73void FumiliFCNAdapter<Function>::EvaluateAll(std::vector<double> const &v)
74{
75 MnPrint print("FumiliFCNAdapter");
76
77 // evaluate all elements
78 unsigned int npar = Dimension();
79 if (npar != v.size())
80 print.Error("npar", npar, "v.size()", v.size());
81 assert(npar == v.size());
82 // must distinguish case of likelihood or LS
83
84 std::vector<double> &grad = Gradient();
85 std::vector<double> &hess = Hessian();
86 // reset
87 assert(grad.size() == npar);
88 grad.assign(npar, 0.0);
89 hess.assign(hess.size(), 0.0);
90
91 unsigned int ndata = fFunc.NPoints();
92
93 std::vector<double> gf(npar);
94 std::vector<double> h(hess.size());
95
96 // loop on the data points
97
98 // if FCN is of type least-square
99 if (fFunc.Type() == Function::kLeastSquare) {
100 print.Debug("Chi2 FCN: Evaluate gradient and Hessian");
101
102 for (unsigned int i = 0; i < ndata; ++i) {
103 // calculate data element and gradient (no need to compute Hessian)
104 double fval = fFunc.DataElement(&v.front(), i, &gf[0]);
105
106 for (unsigned int j = 0; j < npar; ++j) {
107 grad[j] += 2. * fval * gf[j];
108 for (unsigned int k = j; k < npar; ++k) {
109 int idx = j + k * (k + 1) / 2;
110 hess[idx] += 2.0 * gf[j] * gf[k];
111 }
112 }
113 }
114 } else if (fFunc.Type() == Function::kLogLikelihood) {
115 print.Debug("LogLikelihood FCN: Evaluate gradient and Hessian");
116 for (unsigned int i = 0; i < ndata; ++i) {
117
118 // calculate data element and gradient: returns derivative of log(pdf)
119 fFunc.DataElement(&v.front(), i, &gf[0]);
120
121 for (unsigned int j = 0; j < npar; ++j) {
122 double gfj = gf[j];
123 grad[j] -= gfj; // need a minus sign since is a NLL
124 for (unsigned int k = j; k < npar; ++k) {
125 int idx = j + k * (k + 1) / 2;
126 hess[idx] += gfj * gf[k];
127 }
128 }
129 }
130 } else if (fFunc.Type() == Function::kPoissonLikelihood) {
131 print.Debug("Poisson Likelihood FCN: Evaluate gradient and Hessian");
132 // for Poisson need Hessian computed in DataElement since one needs the bin expected value ad bin observed value
133 for (unsigned int i = 0; i < ndata; ++i) {
134 // calculate data element and gradient
135 fFunc.DataElement(&v.front(), i, gf.data(), h.data());
136 for (size_t j = 0; j < npar; ++j) {
137 grad[j] += gf[j];
138 for (unsigned int k = j; k < npar; ++k) {
139 int idx = j + k * (k + 1) / 2;
140 hess[idx] += h[idx];
141 }
142 }
143 }
144 } else {
145 print.Error("Type of fit method is not supported, it must be chi2 or log-likelihood or Poisson Likelihood");
146 }
147}
148
149} // end namespace Minuit2
150
151} // end namespace ROOT
152
153#endif // ROOT_Minuit2_FCNAdapter
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
Double_t(* Function)(Double_t)
Definition Functor.C:4
template wrapped class for adapting to FumiliFCNBase signature
double Up() const override
Error definition of the function.
double operator()(const double *v) const
void SetErrorDef(double up) override
add interface to set dynamically a new error definition Re-implement this function if needed.
void EvaluateAll(std::vector< double > const &v) override
evaluate gradient hessian and function value needed by fumili
FumiliFCNAdapter(const Function &f, unsigned int ndim, double up=1.)
double operator()(std::vector< double > const &v) const override
The meaning of the vector of parameters is of course defined by the user, who uses the values of thos...
Extension of the FCNBase for the Fumili method.
void Debug(const Ts &... args)
Definition MnPrint.h:147
void Error(const Ts &... args)
Definition MnPrint.h:129
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...