File indexing completed on 2025-01-18 10:10:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_Math_KDTree
0015 #define ROOT_Math_KDTree
0016
0017
0018 #include <cassert>
0019 #include <vector>
0020 #include <cmath>
0021 #include <utility>
0022
0023
0024 #include "RtypesCore.h"
0025
0026 namespace ROOT
0027 {
0028 namespace Math
0029 {
0030
0031
0032
0033
0034 template<class _DataPoint>
0035 class KDTree
0036 {
0037 public:
0038
0039 typedef _DataPoint point_type;
0040 typedef typename _DataPoint::value_type value_type;
0041 static UInt_t Dimension() {return _DataPoint::Dimension();}
0042 enum eSplitOption {
0043 kEffective = 0,
0044 kBinContent
0045 };
0046
0047 private:
0048
0049 class ComparePoints
0050 {
0051 public:
0052 Bool_t operator()(const point_type* pFirst,const point_type* pSecond) const;
0053
0054 UInt_t GetAxis() const {return fAxis;}
0055 void SetAxis(UInt_t iAxis) {fAxis = iAxis;}
0056
0057 private:
0058 UInt_t fAxis;
0059 };
0060
0061 class Cut
0062 {
0063 public:
0064 Cut():fAxis(0),fCutValue(0) {}
0065 Cut(UInt_t iAxis,Double_t fNewCutValue):fAxis(iAxis),fCutValue(fNewCutValue) {}
0066 ~Cut() {}
0067
0068 UInt_t GetAxis() const {return fAxis;}
0069 value_type GetCutValue() const {return fCutValue;}
0070 void SetAxis(UInt_t iAxis) {fAxis = iAxis;}
0071 void SetCutValue(Double_t fNewCutValue) {fCutValue = fNewCutValue;}
0072
0073 Bool_t operator<(const point_type& rPoint) const;
0074 Bool_t operator>(const point_type& rPoint) const;
0075
0076 private:
0077 UInt_t fAxis;
0078 Double_t fCutValue;
0079 };
0080
0081
0082 class BaseNode;
0083 class HeadNode;
0084 class SplitNode;
0085 class BinNode;
0086 class TerminalNode;
0087
0088 class BaseNode
0089 {
0090 public:
0091
0092 BaseNode(BaseNode* pParent = 0);
0093 virtual ~BaseNode();
0094
0095
0096 virtual BaseNode* Clone() = 0;
0097 virtual const BinNode* FindNode(const point_type& rPoint) const = 0;
0098 virtual void GetClosestPoints(const point_type& rRef,UInt_t nPoints,std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const = 0;
0099 virtual void GetPointsWithinDist(const point_type& rRef,value_type fDist,std::vector<const point_type*>& vFoundPoints) const = 0;
0100 virtual Bool_t Insert(const point_type& rPoint) = 0;
0101 virtual void Print(int iRow = 0) const = 0;
0102
0103
0104 BaseNode*& LeftChild() {return fLeftChild;}
0105 const BaseNode* LeftChild() const {return fLeftChild;}
0106 BaseNode*& Parent() {return fParent;}
0107 const BaseNode* Parent() const {return fParent;}
0108 BaseNode*& RightChild() {return fRightChild;}
0109 const BaseNode* RightChild() const {return fRightChild;}
0110
0111
0112 BaseNode*& GetParentPointer();
0113 virtual Bool_t IsHeadNode() const {return false;}
0114 Bool_t IsLeftChild() const;
0115
0116 private:
0117
0118 BaseNode(const BaseNode& ) {}
0119 BaseNode& operator=(const BaseNode& ) {return *this;}
0120
0121
0122 BaseNode* fParent;
0123 BaseNode* fLeftChild;
0124 BaseNode* fRightChild;
0125 };
0126
0127 class HeadNode : public BaseNode
0128 {
0129 public:
0130
0131 HeadNode(BaseNode& rNode):BaseNode(&rNode) {}
0132 virtual ~HeadNode() {delete Parent();}
0133
0134
0135 virtual const BinNode* FindNode(const point_type& rPoint) const {return Parent()->FindNode(rPoint);}
0136 virtual void GetClosestPoints(const point_type& rRef,UInt_t nPoints,std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const;
0137 virtual void GetPointsWithinDist(const point_type& rRef,value_type fDist,std::vector<const _DataPoint*>& vFoundPoints) const;
0138 virtual Bool_t Insert(const point_type& rPoint) {return Parent()->Insert(rPoint);}
0139 virtual void Print(Int_t) const {Parent()->Print();}
0140
0141 private:
0142
0143 HeadNode(const HeadNode& ) {}
0144 HeadNode& operator=(const HeadNode& ) {return *this;}
0145
0146 virtual HeadNode* Clone();
0147 virtual bool IsHeadNode() const {return true;}
0148
0149
0150 using BaseNode::Parent;
0151 using BaseNode::LeftChild;
0152 using BaseNode::RightChild;
0153
0154 using BaseNode::GetParentPointer;
0155 using BaseNode::IsLeftChild;
0156 };
0157
0158 class SplitNode : public BaseNode
0159 {
0160 public:
0161
0162 SplitNode(UInt_t iAxis,Double_t fCutValue,BaseNode& rLeft,BaseNode& rRight,BaseNode* pParent = 0);
0163 virtual ~SplitNode();
0164
0165
0166 const Cut* GetCut() const {return fCut;}
0167 virtual void Print(Int_t iRow = 0) const;
0168
0169 private:
0170
0171 SplitNode(const SplitNode& ) {}
0172 SplitNode& operator=(const SplitNode& ) {return *this;}
0173
0174 virtual SplitNode* Clone();
0175 virtual const BinNode* FindNode(const point_type& rPoint) const;
0176 virtual void GetClosestPoints(const point_type& rRef,UInt_t nPoints,std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const;
0177 virtual void GetPointsWithinDist(const point_type& rRef,value_type fDist,std::vector<const _DataPoint*>& vFoundPoints) const;
0178 virtual Bool_t Insert(const point_type& rPoint);
0179
0180 const Cut* fCut;
0181 };
0182
0183 class BinNode : public BaseNode
0184 {
0185 protected:
0186
0187 typedef std::pair<value_type,value_type> tBoundary;
0188 public:
0189
0190 BinNode(BaseNode* pParent = 0);
0191 BinNode(const BinNode& copy);
0192 virtual ~BinNode() {}
0193
0194
0195 virtual void EmptyBin();
0196 virtual const BinNode* FindNode(const point_type& rPoint) const;
0197 point_type GetBinCenter() const;
0198 Double_t GetBinContent() const {return GetSumw();}
0199 #ifndef _AIX
0200 virtual const std::vector<tBoundary>& GetBoundaries() const {return fBoundaries;}
0201 #else
0202 virtual void GetBoundaries() const { }
0203 #endif
0204 Double_t GetDensity() const {return GetBinContent()/GetVolume();}
0205 Double_t GetEffectiveEntries() const {return (GetSumw2()) ? std::pow(GetSumw(),2)/GetSumw2() : 0;}
0206 UInt_t GetEntries() const {return fEntries;}
0207 Double_t GetVolume() const;
0208 Double_t GetSumw() const {return fSumw;}
0209 Double_t GetSumw2() const {return fSumw2;}
0210 virtual Bool_t Insert(const point_type& rPoint);
0211 Bool_t IsInBin(const point_type& rPoint) const;
0212 virtual void Print(int iRow = 0) const;
0213
0214 protected:
0215 virtual BinNode* Clone();
0216
0217
0218 std::vector<tBoundary> fBoundaries;
0219 Double_t fSumw;
0220 Double_t fSumw2;
0221 UInt_t fEntries;
0222
0223 private:
0224 BinNode& operator=(const BinNode& rhs);
0225
0226
0227 virtual void GetClosestPoints(const point_type&,UInt_t,std::vector<std::pair<const _DataPoint*,Double_t> >&) const {}
0228 virtual void GetPointsWithinDist(const point_type&,value_type,std::vector<const point_type*>&) const {}
0229
0230
0231 using BaseNode::LeftChild;
0232 using BaseNode::RightChild;
0233 };
0234
0235 class TerminalNode : public BinNode
0236 {
0237 friend class KDTree<_DataPoint>;
0238
0239 typedef std::pair<value_type,value_type> tBoundary;
0240
0241 public:
0242
0243 TerminalNode(Double_t iBucketSize,BaseNode* pParent = 0);
0244 virtual ~TerminalNode();
0245
0246 virtual void EmptyBin();
0247 #ifndef _AIX
0248 virtual const std::vector<tBoundary>& GetBoundaries() const;
0249 #else
0250 virtual void GetBoundaries() const;
0251 #endif
0252 virtual void GetClosestPoints(const point_type& rRef,UInt_t nPoints,std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const;
0253 const std::vector<const point_type*>& GetPoints() const {return fDataPoints;}
0254 virtual void GetPointsWithinDist(const point_type& rRef,value_type fDist,std::vector<const _DataPoint*>& vFoundPoints) const;
0255 virtual void Print(int iRow = 0) const;
0256
0257 private:
0258
0259 TerminalNode(const TerminalNode& ) {}
0260 TerminalNode& operator=(const TerminalNode& ) {return *this;}
0261
0262
0263 typedef typename std::vector<const point_type* >::iterator data_it;
0264 typedef typename std::vector<const point_type* >::const_iterator const_data_it;
0265
0266
0267 TerminalNode(Double_t iBucketSize,UInt_t iSplitAxis,data_it first,data_it end);
0268
0269
0270 virtual BinNode* Clone() {return ConvertToBinNode();}
0271 BinNode* ConvertToBinNode();
0272 virtual const BinNode* FindNode(const point_type&) const {return this;}
0273 virtual Bool_t Insert(const point_type& rPoint);
0274 void Split();
0275 void SetOwner(Bool_t bIsOwner = true) {fOwnData = bIsOwner;}
0276 void SetSplitOption(eSplitOption opt) {fSplitOption = opt;}
0277 data_it SplitEffectiveEntries();
0278 data_it SplitBinContent();
0279 void UpdateBoundaries();
0280
0281 Bool_t fOwnData;
0282 eSplitOption fSplitOption;
0283 Double_t fBucketSize;
0284 UInt_t fSplitAxis;
0285 std::vector<const _DataPoint*> fDataPoints;
0286 };
0287
0288 public:
0289
0290
0291
0292
0293
0294 typedef BinNode Bin;
0295 class iterator
0296 {
0297 friend class KDTree<_DataPoint>;
0298 public:
0299 iterator(): fBin(0) {}
0300 iterator(const iterator& copy): fBin(copy.fBin) {}
0301 ~iterator() {}
0302
0303 iterator& operator++();
0304 const iterator& operator++() const;
0305 iterator operator++(int);
0306 const iterator operator++(int) const;
0307 iterator& operator--();
0308 const iterator& operator--() const;
0309 iterator operator--(int);
0310 const iterator operator--(int) const;
0311 bool operator==(const iterator& rIterator) const {return (fBin == rIterator.fBin);}
0312 bool operator!=(const iterator& rIterator) const {return !(*this == rIterator);}
0313 iterator& operator=(const iterator& rhs);
0314 Bin& operator*() {return *fBin;}
0315 const Bin& operator*() const {return *fBin;}
0316 Bin* operator->() {return fBin;}
0317 const Bin* operator->() const {return fBin;}
0318
0319 TerminalNode* TN() {assert(dynamic_cast<TerminalNode*>(fBin)); return (TerminalNode*)fBin;}
0320
0321 private:
0322 iterator(BinNode* pNode): fBin(pNode) {}
0323
0324 Bin* Next() const;
0325 Bin* Previous() const;
0326
0327 mutable Bin* fBin;
0328 };
0329
0330
0331 KDTree(UInt_t iBucketSize);
0332 ~KDTree();
0333
0334
0335 void EmptyBins();
0336 iterator End();
0337 const iterator End() const;
0338 const Bin* FindBin(const point_type& rPoint) const {return fHead->FindNode(rPoint);}
0339 iterator First();
0340 const iterator First() const;
0341 void Freeze();
0342 Double_t GetBucketSize() const {return fBucketSize;}
0343 void GetClosestPoints(const point_type& rRef,UInt_t nPoints,std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const;
0344 Double_t GetEffectiveEntries() const;
0345 KDTree<_DataPoint>* GetFrozenCopy();
0346 UInt_t GetNBins() const;
0347 UInt_t GetEntries() const;
0348 void GetPointsWithinDist(const point_type& rRef,value_type fDist,std::vector<const point_type*>& vFoundPoints) const;
0349 Double_t GetTotalSumw() const;
0350 Double_t GetTotalSumw2() const;
0351 Bool_t Insert(const point_type& rData) {return fHead->Parent()->Insert(rData);}
0352 Bool_t IsFrozen() const {return fIsFrozen;}
0353 iterator Last();
0354 const iterator Last() const;
0355 void Print() {fHead->Parent()->Print();}
0356 void Reset();
0357 void SetOwner(Bool_t bIsOwner = true);
0358 void SetSplitOption(eSplitOption opt);
0359
0360 private:
0361 KDTree();
0362 KDTree(const KDTree<point_type>& ) {}
0363 KDTree<point_type>& operator=(const KDTree<point_type>& ) {return *this;}
0364
0365 BaseNode* fHead;
0366 Double_t fBucketSize;
0367 Bool_t fIsFrozen;
0368 };
0369
0370
0371 }
0372 }
0373
0374 #include "Math/KDTree.icc"
0375
0376 #endif