00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef ROOT_Minuit2_FumiliFCNAdapter
00011 #define ROOT_Minuit2_FumiliFCNAdapter
00012
00013 #ifndef ROOT_Minuit2_FumiliFCNBase
00014 #include "Minuit2/FumiliFCNBase.h"
00015 #endif
00016
00017 #ifndef ROOT_Math_FitMethodFunction
00018 #include "Math/FitMethodFunction.h"
00019 #endif
00020
00021 #ifndef ROOT_Minuit2_MnPrint
00022 #include "Minuit2/MnPrint.h"
00023 #endif
00024
00025 #ifndef ROOT_Math_Util
00026 #include "Math/Util.h"
00027 #endif
00028
00029 #include <cmath>
00030
00031 namespace ROOT {
00032
00033 namespace Minuit2 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 template< class Function>
00047 class FumiliFCNAdapter : public FumiliFCNBase {
00048
00049 public:
00050
00051
00052 typedef typename Function::Type_t Type_t;
00053
00054 FumiliFCNAdapter(const Function & f, unsigned int ndim, double up = 1.) :
00055 FumiliFCNBase( ndim ),
00056 fFunc(f) ,
00057 fUp (up)
00058 {}
00059
00060 ~FumiliFCNAdapter() {}
00061
00062
00063 double operator()(const std::vector<double>& v) const {
00064 return fFunc.operator()(&v[0]);
00065 }
00066 double operator()(const double * v) const {
00067 return fFunc.operator()(v);
00068 }
00069 double Up() const {return fUp;}
00070
00071 void SetErrorDef(double up) { fUp = up; }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void EvaluateAll( const std::vector<double> & v);
00083
00084 private:
00085
00086
00087
00088
00089 const Function & fFunc;
00090 double fUp;
00091 };
00092
00093
00094 template<class Function>
00095 void FumiliFCNAdapter<Function>::EvaluateAll( const std::vector<double> & v) {
00096
00097
00098
00099
00100 unsigned int npar = Dimension();
00101 if (npar != v.size() ) std::cout << "npar = " << npar << " " << v.size() << std::endl;
00102 assert(npar == v.size());
00103
00104
00105 std::vector<double> & grad = Gradient();
00106 std::vector<double> & hess = Hessian();
00107
00108 assert(grad.size() == npar);
00109 grad.assign( npar, 0.0);
00110 hess.assign( hess.size(), 0.0);
00111
00112 double sum = 0;
00113 unsigned int ndata = fFunc.NPoints();
00114
00115 std::vector<double> gf(npar);
00116
00117
00118
00119
00120
00121 if (fFunc.Type() == Function::kLeastSquare) {
00122
00123 for (unsigned int i = 0; i < ndata; ++i) {
00124
00125 double fval = fFunc.DataElement(&v.front(), i, &gf[0]);
00126
00127
00128 sum += fval*fval;
00129
00130 for (unsigned int j = 0; j < npar; ++j) {
00131 grad[j] += 2. * fval * gf[j];
00132 for (unsigned int k = j; k < npar; ++ k) {
00133 int idx = j + k*(k+1)/2;
00134 hess[idx] += 2.0 * gf[j] * gf[k];
00135 }
00136 }
00137 }
00138 }
00139 else if (fFunc.Type() == Function::kLogLikelihood) {
00140
00141
00142 for (unsigned int i = 0; i < ndata; ++i) {
00143
00144
00145
00146 double fval = fFunc.DataElement(&v.front(), i, &gf[0]);
00147
00148 sum -= fval;
00149
00150 for (unsigned int j = 0; j < npar; ++j) {
00151 double gfj = gf[j] ;
00152 grad[j] -= gfj;
00153 for (unsigned int k = j; k < npar; ++ k) {
00154 int idx = j + k*(k+1)/2;
00155 hess[idx] += gfj * gf[k] ;
00156 }
00157 }
00158 }
00159 }
00160 else {
00161 MN_ERROR_MSG("FumiliFCNAdapter: type of fit method is not supported, it must be chi2 or log-likelihood");
00162 }
00163 }
00164
00165
00166 }
00167
00168 }
00169
00170
00171
00172
00173 #endif //ROOT_Minuit2_FCNAdapter