#ifndef ROOT_TKDE
#define ROOT_TKDE
#ifndef ROOT_Math_WrappedFunction
#include "Math/WrappedFunction.h"
#endif
#ifndef ROOT_TNamed
#include "TNamed.h"
#endif
#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif
class TGraphErrors;
class TF1;
class TKDE : public TNamed {
public:
enum EKernelType {
kGaussian,
kEpanechnikov,
kBiweight,
kCosineArch,
kUserDefined,
kTotalKernels
};
enum EIteration {
kAdaptive,
kFixed
};
enum EMirror {
kNoMirror,
kMirrorLeft,
kMirrorRight,
kMirrorBoth,
kMirrorAsymLeft,
kMirrorAsymLeftRight,
kMirrorAsymRight,
kMirrorLeftAsymRight,
kMirrorAsymBoth
};
enum EBinning{
kUnbinned,
kRelaxedBinning,
kForcedBinning
};
explicit TKDE(UInt_t events = 0, const Double_t* data = 0, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option =
"KernelType:Gaussian;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
Instantiate( nullptr, events, data, nullptr, xMin, xMax, option, rho);
}
TKDE(UInt_t events, const Double_t* data, const Double_t* dataWeight, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option =
"KernelType:Gaussian;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
Instantiate( nullptr, events, data, dataWeight, xMin, xMax, option, rho);
}
template<class KernelFunction>
TKDE(const Char_t* , const KernelFunction& kernfunc, UInt_t events, const Double_t* data, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option = "KernelType:UserDefined;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
Instantiate(new ROOT::Math::WrappedFunction<const KernelFunction&>(kernfunc), events, data, nullptr, xMin, xMax, option, rho);
}
template<class KernelFunction>
TKDE(const Char_t* , const KernelFunction& kernfunc, UInt_t events, const Double_t* data, const Double_t * dataWeight, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option = "KernelType:UserDefined;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
Instantiate(new ROOT::Math::WrappedFunction<const KernelFunction&>(kernfunc), events, data, dataWeight, xMin, xMax, option, rho);
}
virtual ~TKDE();
void Fill(Double_t data);
void Fill(Double_t data, Double_t weight);
void SetKernelType(EKernelType kern);
void SetIteration(EIteration iter);
void SetMirror(EMirror mir);
void SetBinning(EBinning);
void SetNBins(UInt_t nbins);
void SetUseBinsNEvents(UInt_t nEvents);
void SetTuneFactor(Double_t rho);
void SetRange(Double_t xMin, Double_t xMax);
virtual void Draw(const Option_t* option = "");
Double_t operator()(Double_t x) const;
Double_t operator()(const Double_t* x, const Double_t* p=0) const;
Double_t GetValue(Double_t x) const { return (*this)(x); }
Double_t GetError(Double_t x) const;
Double_t GetBias(Double_t x) const;
Double_t GetMean() const;
Double_t GetSigma() const;
Double_t GetRAMISE() const;
Double_t GetFixedWeight() const;
TF1* GetFunction(UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetUpperFunction(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetLowerFunction(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetApproximateBias(UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TGraphErrors * GetGraphWithErrors(UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1 * GetDrawnFunction() { return fPDF;}
TF1 * GetDrawnUpperFunction() { return fUpperPDF;}
TF1 * GetDrawnLowerFunction() { return fLowerPDF;}
TGraphErrors * GetDrawnGraph() { return fGraph;}
const Double_t * GetAdaptiveWeights() const;
private:
TKDE(TKDE& kde);
TKDE operator=(TKDE& kde);
typedef ROOT::Math::IBaseFunctionOneDim* KernelFunction_Ptr;
KernelFunction_Ptr fKernelFunction;
class TKernel;
friend class TKernel;
TKernel* fKernel;
std::vector<Double_t> fData;
std::vector<Double_t> fEvents;
std::vector<Double_t> fEventWeights;
TF1* fPDF;
TF1* fUpperPDF;
TF1* fLowerPDF;
TF1* fApproximateBias;
TGraphErrors* fGraph;
EKernelType fKernelType;
EIteration fIteration;
EMirror fMirror;
EBinning fBinning;
Bool_t fUseMirroring, fMirrorLeft, fMirrorRight, fAsymLeft, fAsymRight;
Bool_t fUseBins;
Bool_t fNewData;
Bool_t fUseMinMaxFromData;
UInt_t fNBins;
UInt_t fNEvents;
Double_t fSumOfCounts;
UInt_t fUseBinsNEvents;
Double_t fMean;
Double_t fSigma;
Double_t fSigmaRob;
Double_t fXMin;
Double_t fXMax;
Double_t fRho;
Double_t fAdaptiveBandwidthFactor;
Double_t fWeightSize;
std::vector<Double_t> fCanonicalBandwidths;
std::vector<Double_t> fKernelSigmas2;
std::vector<Double_t> fBinCount;
std::vector<Bool_t> fSettedOptions;
struct KernelIntegrand;
friend struct KernelIntegrand;
void Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_t* data, const Double_t* weight,
Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho);
inline Double_t GaussianKernel(Double_t x) const {
Double_t k2_PI_ROOT_INV = 0.398942280401432703;
return (x > -9. && x < 9.) ? k2_PI_ROOT_INV * std::exp(-.5 * x * x) : 0.0;
}
inline Double_t EpanechnikovKernel(Double_t x) const {
return (x > -1. && x < 1.) ? 3. / 4. * (1. - x * x) : 0.0;
}
inline Double_t BiweightKernel(Double_t x) const {
return (x > -1. && x < 1.) ? 15. / 16. * (1. - x * x) * (1. - x * x) : 0.0;
}
inline Double_t CosineArchKernel(Double_t x) const {
return (x > -1. && x < 1.) ? M_PI_4 * std::cos(M_PI_2 * x) : 0.0;
}
Double_t UpperConfidenceInterval(const Double_t* x, const Double_t* p) const;
Double_t LowerConfidenceInterval(const Double_t* x, const Double_t* p) const;
Double_t ApproximateBias(const Double_t* x, const Double_t* ) const { return GetBias(*x); }
Double_t ComputeKernelL2Norm() const;
Double_t ComputeKernelSigma2() const;
Double_t ComputeKernelMu() const;
Double_t ComputeKernelIntegral() const;
Double_t ComputeMidspread() ;
void ComputeDataStats() ;
UInt_t Index(Double_t x) const;
void SetBinCentreData(Double_t xmin, Double_t xmax);
void SetBinCountData();
void CheckKernelValidity();
void SetUserCanonicalBandwidth();
void SetUserKernelSigma2();
void SetCanonicalBandwidths();
void SetKernelSigmas2();
void SetHistogram();
void SetUseBins();
void SetMirror();
void SetMean();
void SetSigma(Double_t R);
void SetKernel();
void SetKernelFunction(KernelFunction_Ptr kernfunc = 0);
void SetOptions(const Option_t* option, Double_t rho);
void CheckOptions(Bool_t isUserDefinedKernel = kFALSE);
void GetOptions(std::string optionType, std::string option);
void AssureOptions();
void SetData(const Double_t* data, const Double_t * weights);
void InitFromNewData();
void SetMirroredEvents();
void SetDrawOptions(const Option_t* option, TString& plotOpt, TString& drawOpt);
void DrawErrors(TString& drawOpt);
void DrawConfidenceInterval(TString& drawOpt, double cl=0.95);
TF1* GetKDEFunction(UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetKDEApproximateBias(UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetPDFUpperConfidenceInterval(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
TF1* GetPDFLowerConfidenceInterval(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
ClassDef(TKDE, 2)
};
#endif