00001 // @(#)root/minuit2:$Id: TChi2ExtendedFCN.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 "TChi2ExtendedFCN.h" 00011 #include "TChi2ExtendedFitData.h" 00012 00013 #include "TF1.h" 00014 #include "TVirtualFitter.h" 00015 #include <cassert> 00016 00017 //#include <iostream> 00018 00019 00020 00021 TChi2ExtendedFCN::TChi2ExtendedFCN( const TVirtualFitter & fitter) : 00022 fUp(1.) 00023 { 00024 // constructor : create FitData class and keep a pointer to model function 00025 fFunc = dynamic_cast<TF1 *> ( fitter.GetUserFunc() ); 00026 assert(fFunc != 0); 00027 // default skip empty bins 00028 fData = new TChi2ExtendedFitData(fitter); 00029 00030 // need to set the size so ROOT can calculate ndf. 00031 fFunc->SetNumberFitPoints(fData->Size()); 00032 } 00033 00034 00035 00036 TChi2ExtendedFCN::~TChi2ExtendedFCN() { 00037 // this class manages the fit data class. Delete it at the end 00038 if (fData) { 00039 delete fData; 00040 } 00041 } 00042 00043 00044 00045 double TChi2ExtendedFCN::operator()(const std::vector<double>& par) const { 00046 // implement chi2 extended function: use also error on x coordinates (can be also asymmetric) 00047 00048 assert(fData != 0); 00049 assert(fFunc != 0); 00050 00051 00052 // std::cout << "number of params " << par.size() << " in TF1 " << fFunc->GetNpar() << " " << fFunc->GetNumberFreeParameters() << std::endl; 00053 00054 unsigned int n = fData->Size(); 00055 double chi2 = 0; 00056 for (unsigned int i = 0; i < n; ++ i) { 00057 const std::vector<double> & x = fData->Coords(i); 00058 fFunc->InitArgs( &x.front(), &par.front() ); 00059 double y = fData->Value(i); 00060 //std::cout << x[0] << " " << y << " " << 1./invError << " params " << par[0] << std::endl; 00061 double functionValue = fFunc->EvalPar( &x.front(), &par.front() ); 00062 00063 double ey = fData->ErrorY(i); 00064 double exl = fData->ErrorXLow(i); 00065 double exh = fData->ErrorXUp(i); 00066 double eux = 0; 00067 if (exh <=0 && exl <= 0) 00068 eux = 0; 00069 else 00070 // works only for 1D func 00071 eux = 0.5 * (exl + exh) * fFunc->Derivative( x[0], const_cast<double *> ( &par.front() ) ); 00072 double error2 = (ey*ey + eux*eux); 00073 if (error2 == 0) error2 = 1; 00074 00075 double tmp = ( y -functionValue ); 00076 00077 chi2 += tmp*tmp/error2; 00078 } 00079 00080 return chi2; 00081 } 00082