00001 // @(#)root/minuit2:$Id: TChi2FCN.cxx 20880 2007-11-19 11:23:41Z rdm $ 00002 // Author: L. Moneta 10/2005 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2005 ROOT Foundation, CERN/PH-SFT * 00007 * * 00008 **********************************************************************/ 00009 00010 #include "TChi2FCN.h" 00011 #include "TChi2FitData.h" 00012 #include "FitterUtil.h" 00013 00014 #include "TF1.h" 00015 #include "TVirtualFitter.h" 00016 00017 #include <cassert> 00018 00019 //#define DEBUG 00020 #ifdef DEBUG 00021 #include <iostream> 00022 #endif 00023 00024 00025 00026 TChi2FCN::TChi2FCN( const TVirtualFitter & fitter) : 00027 fUp(1), fOwner(true) 00028 { 00029 // constructor : create FitData class and keep a pointer to model function 00030 fFunc = dynamic_cast<TF1 *> ( fitter.GetUserFunc() ); 00031 assert(fFunc != 0); 00032 // default skip empty bins 00033 fData = new TChi2FitData(fitter, true); 00034 #ifdef DEBUG 00035 std::cout << "Created FitData with size = " << fData->Size() << std::endl; 00036 #endif 00037 00038 // need to set the size so ROOT can calculate ndf. 00039 fFunc->SetNumberFitPoints(fData->Size()); 00040 } 00041 00042 00043 00044 TChi2FCN::~TChi2FCN() { 00045 // if this class manages the fit data class, delete it at the end 00046 if (fOwner && fData) { 00047 #ifdef DEBUG 00048 std::cout << "deleting the data - size is " << fData->Size() << std::endl; 00049 #endif 00050 delete fData; 00051 } 00052 } 00053 00054 00055 00056 double TChi2FCN::operator()(const std::vector<double>& par) const { 00057 // implement standard chi2 function using the Fit data and model function 00058 00059 assert(fData != 0); 00060 assert(fFunc != 0); 00061 00062 00063 // std::cout << "number of params " << par.size() << " in TF1 " << fFunc->GetNpar() << " " << fFunc->GetNumberFreeParameters() << std::endl; 00064 00065 unsigned int n = fData->Size(); 00066 // std::cout << "Fit data size = " << n << std::endl; 00067 double chi2 = 0; 00068 int nRejected = 0; 00069 for (unsigned int i = 0; i < n; ++ i) { 00070 const std::vector<double> & x = fData->Coords(i); 00071 fFunc->RejectPoint(false); 00072 fFunc->InitArgs( &x.front(), &par.front() ); 00073 double y = fData->Value(i); 00074 double invError = fData->InvError(i); 00075 //std::cout << x[0] << " " << y << " " << 1./invError << " params " << par[0] << std::endl; 00076 double fval = 0; 00077 if (fData->UseIntegral()) { 00078 const std::vector<double> & x2 = fData->Coords(i+1); 00079 fval = FitterUtil::EvalIntegral(fFunc,x,x2,par); 00080 } 00081 else 00082 fval = fFunc->EvalPar( &x.front(), &par.front() ); 00083 00084 if (!fFunc->RejectedPoint() ) { 00085 // calculat chi2 if point is not rejected 00086 double tmp = ( y -fval )* invError; 00087 chi2 += tmp*tmp; 00088 } 00089 else 00090 nRejected++; 00091 00092 } 00093 00094 // reset the number of fitting data points 00095 if (nRejected != 0) fFunc->SetNumberFitPoints(n-nRejected); 00096 00097 return chi2; 00098 } 00099 00100