#include "TH1.h"
#include "TH1F.h"
#include "TF1.h"
#if ROOT_VERSION_CODE >= 364802
#ifndef ROOT_TMathBase
#include "TMathBase.h"
#endif
#else
#ifndef ROOT_TMath
#include "TMath.h"
#endif
#endif
#include "TMVA/KDEKernel.h"
ClassImp(TMVA::KDEKernel)
TMVA::KDEKernel::KDEKernel( EKernelIter kiter, const TH1 *hist, Float_t lower_edge, Float_t upper_edge,
                            EKernelBorder kborder, Float_t FineFactor )
   : fSigma( 1. ),
     fIter ( kiter ),
     fLowerEdge (lower_edge ),
     fUpperEdge (upper_edge),
     fFineFactor ( FineFactor ),
     fKernel_integ ( 0 ),
     fKDEborder ( kborder ),
     fLogger( "KDEKernel" )
{
   
   
   if (hist == NULL) {
      fLogger << kFATAL << "Called without valid histogram pointer (hist)!" << Endl;
   } 
   fHist          = (TH1F*)hist->Clone();
   fFirstIterHist = (TH1F*)hist->Clone();
   fFirstIterHist->Reset(); 
   fSigmaHist     = (TH1F*)hist->Clone();
   fSigmaHist->Reset(); 
   
   fHiddenIteration=false;
}
TMVA::KDEKernel::~KDEKernel()
{
   
   if (fHist           != NULL) delete fHist;
   if (fFirstIterHist  != NULL) delete fFirstIterHist;
   if (fSigmaHist      != NULL) delete fSigmaHist;
   if (fKernel_integ   != NULL) delete fKernel_integ;
}
Double_t GaussIntegral(Double_t *x, Double_t *par)
{
   
   if ( (par[1]<=0) || (x[0]>x[1])) return -1.;
  
   Float_t xs1=(x[0]-par[0])/par[1];
   Float_t xs2=(x[1]-par[0])/par[1];
  
   if (xs1==0) {
      if (xs2==0) return 0.;
      if (xs2>0 ) return 0.5*TMath::Erf(xs2);
   }
   if (xs2==0) return 0.5*TMath::Erf(TMath::Abs(xs1));
   if (xs1>0) return 0.5*(TMath::Erf(xs2)-TMath::Erf(xs1));
   if (xs1<0) {
      if (xs2>0 ) return 0.5*(TMath::Erf(xs2)+TMath::Erf(TMath::Abs(xs1)));
      else return 0.5*(TMath::Erf(TMath::Abs(xs1))-TMath::Erf(TMath::Abs(xs2)));
   }
   return -1.;
}
void TMVA::KDEKernel::SetKernelType( EKernelType ktype )
{
   
   
 
   if (ktype == kGauss) {
      
      
      
      
      
      fKernel_integ = new TF1("GaussIntegral",GaussIntegral,fLowerEdge,fUpperEdge,4); 
      fSigma = ( TMath::Sqrt(2.0)
                 *TMath::Power(4./3., 0.2)
                 *fHist->GetRMS()
                 *TMath::Power(fHist->Integral(), -0.2) ); 
      
      
      
      if (fSigma <= 0 ) {
         fLogger << kFATAL << "<SetKernelType> KDE sigma has invalid value ( <=0 ) !" << Endl;
      }
   }
   if (fIter == kAdaptiveKDE) {
      
      
      
      
      fHiddenIteration=true;
      
      Float_t histoLowEdge=fHist->GetBinLowEdge(1);
      Float_t histoUpperEdge=fHist->GetBinLowEdge(fHist->GetNbinsX()+1);
      for (Int_t i=1;i<fHist->GetNbinsX();i++) {
         
         for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
            
            fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
                                    this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
                                                               fFirstIterHist->GetBinLowEdge(j+1),
                                                               fHist->GetBinCenter(i),
                                                               i)
                                    );
         }
         if (fKDEborder == 3) { 
         
         
         
            if (i < fHist->GetNbinsX()/5  ) {  
               for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
               
               fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
                                       this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
                                                               fFirstIterHist->GetBinLowEdge(j+1),
                                                               2*histoLowEdge-fHist->GetBinCenter(i), 
                                                               i)
                                      );
               }
            }
            if (i > 4*fHist->GetNbinsX()/5) { 
               for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
               
               fFirstIterHist->AddBinContent(j,fHist->GetBinContent(i)*
                                       this->GetBinKernelIntegral(fFirstIterHist->GetBinLowEdge(j),
                                                               fFirstIterHist->GetBinLowEdge(j+1),
                                                               2*histoUpperEdge-fHist->GetBinCenter(i), 
                                                               i)
                                      );
               }            
            }
         }
      }
      
      fFirstIterHist->SetEntries(fHist->GetEntries()); 
      
      Float_t integ=0;
      for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) 
         integ+=fFirstIterHist->GetBinContent(j)*fFirstIterHist->GetBinWidth(j);
      fFirstIterHist->Scale(1./integ);
      
      fHiddenIteration=false;
      
      
      
      
      for (Int_t j=1;j<fFirstIterHist->GetNbinsX();j++) {
         
         if (fSigma*TMath::Sqrt(1.0/fFirstIterHist->GetBinContent(j)) <= 0 ) {
            fLogger << kFATAL << "<SetKernelType> KDE sigma has invalid value ( <=0 ) !" << Endl;
         }
         
         fSigmaHist->SetBinContent(j,fFineFactor*fSigma/TMath::Sqrt(fFirstIterHist->GetBinContent(j)));
      }
   }
   if (fKernel_integ ==0 ) {
      fLogger << kFATAL << "KDE kernel not correctly initialized!" << Endl;
   }
}
Float_t TMVA::KDEKernel::GetBinKernelIntegral( Float_t lowr, Float_t highr, Float_t mean, Int_t binnum )
{
   
   if ((fIter == kNonadaptiveKDE) || fHiddenIteration  ) 
      fKernel_integ->SetParameters(mean,fSigma); 
   else if ((fIter == kAdaptiveKDE) && !fHiddenIteration ) 
      fKernel_integ->SetParameters(mean,fSigmaHist->GetBinContent(binnum)); 
   if ( fKDEborder == 2 ) {  
      Float_t renormFactor=1.0/fKernel_integ->Eval(fLowerEdge,fUpperEdge);
      return (renormFactor*fKernel_integ->Eval(lowr,highr));
   }
                                   
   
   
   return (fKernel_integ->Eval(lowr,highr));  
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.