00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef ROOT_Fit_Chi2FCN
00014 #define ROOT_Fit_Chi2FCN
00015
00016 #ifndef ROOT_Math_FitMethodFunction
00017 #include "Math/FitMethodFunction.h"
00018 #endif
00019
00020 #ifndef ROOT_Math_IParamFunction
00021 #include "Math/IParamFunction.h"
00022 #endif
00023
00024
00025 #ifndef ROOT_Fit_BinData
00026 #include "Fit/BinData.h"
00027 #endif
00028
00029
00030 #ifndef ROOT_Fit_FitUtil
00031 #include "Fit/FitUtil.h"
00032 #endif
00033
00034
00035
00036 #ifdef ROOT_FIT_PARALLEL
00037 #ifndef ROOT_Fit_FitUtilParallel
00038 #include "Fit/FitUtilParallel.h"
00039 #endif
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 namespace ROOT {
00051
00052
00053 namespace Fit {
00054
00055
00056 template<class FunType>
00057 struct ModelFunctionTrait {
00058 typedef ::ROOT::Math::IParamMultiFunction ModelFunc;
00059 };
00060 template<>
00061 struct ModelFunctionTrait<ROOT::Math::IMultiGradFunction> {
00062 typedef ::ROOT::Math::IParamMultiGradFunction ModelFunc;
00063 };
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 template<class FunType>
00074 class Chi2FCN : public ::ROOT::Math::BasicFitMethodFunction<FunType> {
00075
00076 public:
00077
00078
00079
00080 typedef ::ROOT::Math::BasicFitMethodFunction<FunType> BaseObjFunction;
00081 typedef typename BaseObjFunction::BaseFunction BaseFunction;
00082
00083 typedef typename ModelFunctionTrait<FunType>::ModelFunc IModelFunction;
00084 typedef typename BaseObjFunction::Type_t Type_t;
00085
00086
00087
00088
00089 Chi2FCN (const BinData & data, const IModelFunction & func) :
00090 BaseObjFunction(func.NPar(), data.Size() ),
00091 fData(data),
00092 fFunc(func),
00093 fNEffPoints(0),
00094 fGrad ( std::vector<double> ( func.NPar() ) )
00095 { }
00096
00097
00098
00099
00100 virtual ~Chi2FCN () {}
00101
00102 #ifdef LATER
00103 private:
00104
00105
00106
00107
00108
00109
00110 Chi2FCN(const Chi2FCN &);
00111
00112
00113
00114
00115 Chi2FCN & operator = (const Chi2FCN & rhs);
00116
00117 #endif
00118 public:
00119
00120 virtual BaseFunction * Clone() const {
00121
00122 Chi2FCN * fcn = new Chi2FCN(fData,fFunc);
00123 return fcn;
00124 }
00125
00126
00127
00128 using BaseObjFunction::operator();
00129
00130
00131
00132 virtual unsigned int NFitPoints() const { return fNEffPoints; }
00133
00134
00135
00136 virtual double DataElement(const double * x, unsigned int i, double * g) const {
00137 if (i==0) this->UpdateNCalls();
00138 return FitUtil::EvaluateChi2Residual(fFunc, fData, x, i, g);
00139 }
00140
00141
00142 virtual void Gradient(const double *x, double *g) const {
00143
00144 FitUtil::EvaluateChi2Gradient(fFunc, fData, x, g, fNEffPoints);
00145 }
00146
00147
00148 virtual typename BaseObjFunction::Type_t Type() const { return BaseObjFunction::kLeastSquare; }
00149
00150
00151 virtual const BinData & Data() const { return fData; }
00152
00153
00154 virtual const IModelFunction & ModelFunction() const { return fFunc; }
00155
00156
00157
00158 protected:
00159
00160
00161
00162 virtual void SetNFitPoints(unsigned int n) const { fNEffPoints = n; }
00163
00164 private:
00165
00166
00167
00168
00169 virtual double DoEval (const double * x) const {
00170 this->UpdateNCalls();
00171 #ifdef ROOT_FIT_PARALLEL
00172 return FitUtilParallel::EvaluateChi2(fFunc, fData, x, fNEffPoints);
00173 #else
00174 if (!fData.HaveCoordErrors() )
00175 return FitUtil::EvaluateChi2(fFunc, fData, x, fNEffPoints);
00176 else
00177 return FitUtil::EvaluateChi2Effective(fFunc, fData, x, fNEffPoints);
00178 #endif
00179 }
00180
00181
00182 virtual double DoDerivative(const double * x, unsigned int icoord ) const {
00183 Gradient(x, &fGrad[0]);
00184 return fGrad[icoord];
00185 }
00186
00187 const BinData & fData;
00188 const IModelFunction & fFunc;
00189
00190 mutable unsigned int fNEffPoints;
00191
00192 mutable std::vector<double> fGrad;
00193
00194
00195 };
00196
00197
00198 typedef Chi2FCN<ROOT::Math::IMultiGenFunction> Chi2Function;
00199 typedef Chi2FCN<ROOT::Math::IMultiGradFunction> Chi2GradFunction;
00200
00201
00202 }
00203
00204 }
00205
00206
00207 #endif