00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "TH1.h"
00027 #include "TH1F.h"
00028 #include "TF1.h"
00029
00030 #if ROOT_VERSION_CODE >= 364802
00031 #ifndef ROOT_TMathBase
00032 #include "TMathBase.h"
00033 #endif
00034 #else
00035 #ifndef ROOT_TMath
00036 #include "TMath.h"
00037 #endif
00038 #endif
00039
00040 #include "TMVA/KDEKernel.h"
00041 #include "TMVA/MsgLogger.h"
00042
00043 ClassImp(TMVA::KDEKernel)
00044
00045
00046 TMVA::KDEKernel::KDEKernel( EKernelIter kiter, const TH1 *hist, Float_t lower_edge, Float_t upper_edge,
00047 EKernelBorder kborder, Float_t FineFactor )
00048 : fSigma( 1. ),
00049 fIter ( kiter ),
00050 fLowerEdge (lower_edge ),
00051 fUpperEdge (upper_edge),
00052 fFineFactor ( FineFactor ),
00053 fKernel_integ ( 0 ),
00054 fKDEborder ( kborder ),
00055 fLogger( new MsgLogger("KDEKernel") )
00056 {
00057
00058
00059 if (hist == NULL) {
00060 Log() << kFATAL << "Called without valid histogram pointer (hist)!" << Endl;
00061 }
00062
00063 fHist = (TH1F*)hist->Clone();
00064 fFirstIterHist = (TH1F*)hist->Clone();
00065 fFirstIterHist->Reset();
00066 fSigmaHist = (TH1F*)hist->Clone();
00067 fSigmaHist->Reset();
00068
00069 fHiddenIteration=false;
00070 }
00071
00072
00073 TMVA::KDEKernel::~KDEKernel()
00074 {
00075
00076 if (fHist != NULL) delete fHist;
00077 if (fFirstIterHist != NULL) delete fFirstIterHist;
00078 if (fSigmaHist != NULL) delete fSigmaHist;
00079 if (fKernel_integ != NULL) delete fKernel_integ;
00080 delete fLogger;
00081 }
00082
00083
00084 Double_t GaussIntegral(Double_t *x, Double_t *par)
00085 {
00086
00087 if ( (par[1]<=0) || (x[0]>x[1])) return -1.;
00088
00089 Float_t xs1=(x[0]-par[0])/par[1];
00090 Float_t xs2=(x[1]-par[0])/par[1];
00091
00092 if (xs1==0) {
00093 if (xs2==0) return 0.;
00094 if (xs2>0 ) return 0.5*TMath::Erf(xs2);
00095 }
00096 if (xs2==0) return 0.5*TMath::Erf(TMath::Abs(xs1));
00097 if (xs1>0) return 0.5*(TMath::Erf(xs2)-TMath::Erf(xs1));
00098 if (xs1<0) {
00099 if (xs2>0 ) return 0.5*(TMath::Erf(xs2)+TMath::Erf(TMath::Abs(xs1)));
00100 else return 0.5*(TMath::Erf(TMath::Abs(xs1))-TMath::Erf(TMath::Abs(xs2)));
00101 }
00102 return -1.;
00103 }
00104
00105
00106 void TMVA::KDEKernel::SetKernelType( EKernelType ktype )
00107 {
00108
00109
00110
00111 if (ktype == kGauss) {
00112
00113
00114
00115
00116
00117
00118 fKernel_integ = new TF1("GaussIntegral",GaussIntegral,fLowerEdge,fUpperEdge,4);
00119 fSigma = ( TMath::Sqrt(2.0)
00120 *TMath::Power(4./3., 0.2)
00121 *fHist->GetRMS()
00122 *TMath::Power(fHist->Integral(), -0.2) );
00123
00124
00125
00126 if (fSigma <= 0 ) {
00127 Log() << kFATAL << "<SetKernelType> KDE sigma has invalid value ( <=0 ) !" << Endl;
00128 }
00129 }
00130
00131 if (fIter == kAdaptiveKDE) {
00132
00133
00134
00135
00136
00137 fHiddenIteration=true;
00138
00139 Float_t histoLowEdge=fHist->GetBinLowEdge(1);
00140 Float_t histoUpperEdge=fHist->GetBinLowEdge(fHist->GetNbinsX()+1);
00141
00142 for (Int_t i=1;i<fHist->GetNbinsX();i++) {
00143
00144 for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
00145
00146 fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
00147 this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
00148 fFirstIterHist->GetBinLowEdge(j+1),
00149 fHist->GetBinCenter(i),
00150 i)
00151 );
00152 }
00153 if (fKDEborder == 3) {
00154
00155
00156
00157 if (i < fHist->GetNbinsX()/5 ) {
00158 for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
00159
00160 fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
00161 this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
00162 fFirstIterHist->GetBinLowEdge(j+1),
00163 2*histoLowEdge-fHist->GetBinCenter(i),
00164 i)
00165 );
00166 }
00167 }
00168 if (i > 4*fHist->GetNbinsX()/5) {
00169 for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
00170
00171 fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
00172 this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
00173 fFirstIterHist->GetBinLowEdge(j+1),
00174 2*histoUpperEdge-fHist->GetBinCenter(i),
00175 i)
00176 );
00177 }
00178 }
00179 }
00180 }
00181
00182 fFirstIterHist->SetEntries(fHist->GetEntries());
00183
00184
00185 Float_t integ=0;
00186 for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++)
00187 integ+=fFirstIterHist->GetBinContent(j)*fFirstIterHist->GetBinWidth(j);
00188 fFirstIterHist->Scale(1./integ);
00189
00190 fHiddenIteration=false;
00191
00192
00193
00194
00195
00196 for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
00197
00198 if (fSigma*TMath::Sqrt(1.0/fFirstIterHist->GetBinContent(j)) <= 0 ) {
00199 Log() << kFATAL << "<SetKernelType> KDE sigma has invalid value ( <=0 ) !" << Endl;
00200 }
00201
00202 fSigmaHist->SetBinContent(j,fFineFactor*fSigma/TMath::Sqrt(fFirstIterHist->GetBinContent(j)));
00203 }
00204 }
00205
00206 if (fKernel_integ ==0 ) {
00207 Log() << kFATAL << "KDE kernel not correctly initialized!" << Endl;
00208 }
00209 }
00210
00211
00212 Float_t TMVA::KDEKernel::GetBinKernelIntegral( Float_t lowr, Float_t highr, Float_t mean, Int_t binnum )
00213 {
00214
00215 if ((fIter == kNonadaptiveKDE) || fHiddenIteration )
00216 fKernel_integ->SetParameters(mean,fSigma);
00217 else if ((fIter == kAdaptiveKDE) && !fHiddenIteration )
00218 fKernel_integ->SetParameters(mean,fSigmaHist->GetBinContent(binnum));
00219
00220 if ( fKDEborder == 2 ) {
00221 Float_t renormFactor=1.0/fKernel_integ->Eval(fLowerEdge,fUpperEdge);
00222 return (renormFactor*fKernel_integ->Eval(lowr,highr));
00223 }
00224
00225
00226
00227 return (fKernel_integ->Eval(lowr,highr));
00228 }
00229