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 KD_TREE_ICC
0015 #define KD_TREE_ICC
0016
0017 #ifndef ROOT_Math_KDTree
0018 #error "Do not use KDTree.icc directly. #include \"KDTree.h\" instead."
0019 #endif
0020
0021
0022 #include <iostream>
0023 #include <functional>
0024 #include <algorithm>
0025 #include <limits>
0026
0027 namespace ROOT
0028 {
0029 namespace Math
0030 {
0031
0032 template<class _DataPoint>
0033 KDTree<_DataPoint>::KDTree(UInt_t iBucketSize):
0034 fBucketSize(iBucketSize),
0035 fIsFrozen(false)
0036 {
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 TerminalNode* pTerminal = new TerminalNode(iBucketSize);
0054 fHead = new HeadNode(*pTerminal);
0055 pTerminal->Parent() = fHead;
0056 }
0057
0058
0059 template<class _DataPoint>
0060 KDTree<_DataPoint>::KDTree():
0061 fHead(0),
0062 fBucketSize(1),
0063 fIsFrozen(false)
0064 {
0065
0066
0067
0068 }
0069
0070
0071 template<class _DataPoint>
0072 KDTree<_DataPoint>::~KDTree()
0073 {
0074
0075
0076
0077
0078
0079
0080 delete fHead;
0081 }
0082
0083
0084 template<class _DataPoint>
0085 inline void KDTree<_DataPoint>::EmptyBins()
0086 {
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 for(iterator it = First(); it != End(); ++it)
0098 it->EmptyBin();
0099 }
0100
0101
0102 template<class _DataPoint>
0103 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::End()
0104 {
0105
0106
0107
0108
0109
0110
0111
0112 return iterator(0);
0113 }
0114
0115
0116 template<class _DataPoint>
0117 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::End() const
0118 {
0119
0120
0121
0122
0123
0124
0125
0126 return iterator(0);
0127 }
0128
0129
0130 template<class _DataPoint>
0131 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::First()
0132 {
0133
0134
0135
0136
0137 BaseNode* pNode = fHead->Parent();
0138 while(pNode->LeftChild())
0139 pNode = pNode->LeftChild();
0140
0141 assert(dynamic_cast<BinNode*>(pNode));
0142 return iterator((BinNode*)pNode);
0143 }
0144
0145
0146 template<class _DataPoint>
0147 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::First() const
0148 {
0149
0150
0151
0152
0153 BaseNode* pNode = fHead->Parent();
0154 while(pNode->LeftChild())
0155 pNode = pNode->LeftChild();
0156
0157 assert(dynamic_cast<BinNode*>(pNode));
0158 return iterator((BinNode*)pNode);
0159 }
0160
0161
0162 template<class _DataPoint>
0163 void KDTree<_DataPoint>::Freeze()
0164 {
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 if(!fIsFrozen)
0179 {
0180 std::vector<TerminalNode*> vBins;
0181
0182 for(iterator it = First(); it != End(); ++it)
0183 vBins.push_back(it.TN());
0184
0185 BinNode* pBin = 0;
0186 for(typename std::vector<TerminalNode*>::iterator bit = vBins.begin(); bit != vBins.end(); ++bit)
0187 {
0188 pBin = (*bit)->ConvertToBinNode();
0189 (*bit)->GetParentPointer() = pBin;
0190 pBin->Parent() = (*bit)->Parent();
0191 delete *bit;
0192 }
0193
0194 fIsFrozen = true;
0195 }
0196 }
0197
0198
0199 template<class _DataPoint>
0200 void KDTree<_DataPoint>::GetClosestPoints(const _DataPoint& rRef,UInt_t nPoints,
0201 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const
0202 {
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 if((nPoints > 0) && (!fIsFrozen))
0219 fHead->GetClosestPoints(rRef,nPoints,vFoundPoints);
0220 }
0221
0222
0223 template<class _DataPoint>
0224 Double_t KDTree<_DataPoint>::GetEffectiveEntries() const
0225 {
0226
0227
0228
0229
0230 Double_t fSumw = 0;
0231 Double_t fSumw2 = 0;
0232 for(iterator it = First(); it != End(); ++it)
0233 {
0234 fSumw += it->GetBinContent();
0235 fSumw2 += it->GetSumw2();
0236 }
0237
0238 return ((fSumw2) ? fSumw * fSumw / fSumw2 : 0);
0239 }
0240
0241
0242 template<class _DataPoint>
0243 UInt_t KDTree<_DataPoint>::GetEntries() const
0244 {
0245
0246
0247 UInt_t iPoints = 0;
0248 for(iterator it = First(); it != End(); ++it)
0249 iPoints += it->GetEntries();
0250
0251 return iPoints;
0252 }
0253
0254
0255 template<class _DataPoint>
0256 KDTree<_DataPoint>* KDTree<_DataPoint>::GetFrozenCopy()
0257 {
0258
0259
0260
0261
0262
0263 KDTree<_DataPoint>* pTree = new KDTree<_DataPoint>();
0264 pTree->fBucketSize = fBucketSize;
0265 pTree->fHead = fHead->Clone();
0266 pTree->fIsFrozen = true;
0267
0268 return pTree;
0269 }
0270
0271
0272 template<class _DataPoint>
0273 UInt_t KDTree<_DataPoint>::GetNBins() const
0274 {
0275
0276
0277 UInt_t iBins = 0;
0278 for(iterator it = First(); it != End(); ++it)
0279 ++iBins;
0280
0281 return iBins;
0282 }
0283
0284
0285 template<class _DataPoint>
0286 void KDTree<_DataPoint>::GetPointsWithinDist(const _DataPoint& rRef,value_type fDist,
0287 std::vector<const _DataPoint*>& vFoundPoints) const
0288 {
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302 if((fDist > 0) && (!fIsFrozen))
0303 fHead->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0304 }
0305
0306
0307 template<class _DataPoint>
0308 Double_t KDTree<_DataPoint>::GetTotalSumw() const
0309 {
0310
0311
0312 Double_t fSumw = 0;
0313 for(iterator it = First(); it != End(); ++it)
0314 fSumw += it->GetSumw();
0315
0316 return fSumw;
0317 }
0318
0319
0320 template<class _DataPoint>
0321 Double_t KDTree<_DataPoint>::GetTotalSumw2() const
0322 {
0323
0324
0325 Double_t fSumw2 = 0;
0326 for(iterator it = First(); it != End(); ++it)
0327 fSumw2 += it->GetSumw2();
0328
0329 return fSumw2;
0330 }
0331
0332
0333 template<class _DataPoint>
0334 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::Last()
0335 {
0336
0337
0338
0339
0340 BaseNode* pNode = fHead->Parent();
0341 while(pNode->RightChild())
0342 pNode = pNode->RightChild();
0343
0344 assert(dynamic_cast<TerminalNode*>(pNode));
0345 return iterator((TerminalNode*)pNode);
0346 }
0347
0348
0349 template<class _DataPoint>
0350 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::Last() const
0351 {
0352
0353
0354
0355
0356 BaseNode* pNode = fHead->Parent();
0357 while(pNode->RightChild())
0358 pNode = pNode->RightChild();
0359
0360 assert(dynamic_cast<BinNode*>(pNode));
0361 return iterator((BinNode*)pNode);
0362 }
0363
0364
0365 template<class _DataPoint>
0366 void KDTree<_DataPoint>::Reset()
0367 {
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 delete fHead->Parent();
0380
0381 TerminalNode* pTerminal = new TerminalNode(fBucketSize);
0382 pTerminal->Parent() = fHead;
0383 fHead->Parent() = pTerminal;
0384
0385
0386 fIsFrozen = false;
0387 }
0388
0389
0390 template<class _DataPoint>
0391 void KDTree<_DataPoint>::SetOwner(Bool_t bIsOwner)
0392 {
0393
0394
0395
0396
0397
0398
0399
0400
0401 if(!fIsFrozen)
0402 {
0403 for(iterator it = First(); it != End(); ++it)
0404 it.TN()->SetOwner(bIsOwner);
0405 }
0406 }
0407
0408
0409 template<class _DataPoint>
0410 void KDTree<_DataPoint>::SetSplitOption(eSplitOption opt)
0411 {
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 if(!fIsFrozen)
0425 {
0426 for(iterator it = First(); it != End(); ++it)
0427 it.TN()->SetSplitOption(opt);
0428 }
0429 }
0430
0431
0432 template<class _DataPoint>
0433 bool KDTree<_DataPoint>::ComparePoints::operator()(const _DataPoint* pFirst,const _DataPoint* pSecond) const
0434 {
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 assert(pFirst && pSecond && (fAxis < KDTree<_DataPoint>::Dimension()));
0450
0451 return (pFirst->GetCoordinate(fAxis) < pSecond->GetCoordinate(fAxis));
0452 }
0453
0454
0455 template<class _DataPoint>
0456 bool KDTree<_DataPoint>::Cut::operator<(const _DataPoint& rPoint) const
0457 {
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 assert(Dimension() > fAxis);
0471 return (fCutValue < rPoint.GetCoordinate(fAxis));
0472 }
0473
0474
0475 template<class _DataPoint>
0476 bool KDTree<_DataPoint>::Cut::operator>(const _DataPoint& rPoint) const
0477 {
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 assert(Dimension() > fAxis);
0491 return (fCutValue > rPoint.GetCoordinate(fAxis));
0492 }
0493
0494
0495 template<class _DataPoint>
0496 KDTree<_DataPoint>::BaseNode::BaseNode(BaseNode* pParent):
0497 fParent(pParent),
0498 fLeftChild(0),
0499 fRightChild(0)
0500 {
0501
0502 }
0503
0504
0505 template<class _DataPoint>
0506 KDTree<_DataPoint>::BaseNode::~BaseNode()
0507 {
0508
0509
0510
0511
0512
0513
0514 delete LeftChild();
0515 delete RightChild();
0516 }
0517
0518
0519 template<class _DataPoint>
0520 typename KDTree<_DataPoint>::BaseNode*& KDTree<_DataPoint>::BaseNode::GetParentPointer()
0521 {
0522
0523
0524
0525
0526 assert(!IsHeadNode());
0527
0528 if(Parent()->Parent() == this)
0529 return Parent()->Parent();
0530 if(Parent()->LeftChild() == this)
0531 return Parent()->LeftChild();
0532 if(Parent()->RightChild() == this)
0533 return Parent()->RightChild();
0534
0535
0536 assert(false);
0537 return Parent();
0538 }
0539
0540
0541 template<class _DataPoint>
0542 bool KDTree<_DataPoint>::BaseNode::IsLeftChild() const
0543 {
0544
0545
0546
0547
0548 if(Parent()->IsHeadNode())
0549 return false;
0550 else
0551 return (Parent()->LeftChild() == this);
0552 }
0553
0554
0555 template<class _DataPoint>
0556 typename KDTree<_DataPoint>::HeadNode* KDTree<_DataPoint>::HeadNode::Clone()
0557 {
0558
0559
0560
0561
0562
0563 BaseNode* pParent = Parent()->Clone();
0564 HeadNode* pHead = new HeadNode(*pParent);
0565 pParent->Parent() = pHead;
0566
0567 return pHead;
0568 }
0569
0570
0571 template<class _DataPoint>
0572 inline void KDTree<_DataPoint>::HeadNode::GetClosestPoints(const _DataPoint& rRef,UInt_t nPoints,
0573 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const
0574 {
0575 Parent()->GetClosestPoints(rRef,nPoints,vFoundPoints);
0576 }
0577
0578
0579 template<class _DataPoint>
0580 inline void KDTree<_DataPoint>::HeadNode::GetPointsWithinDist(const _DataPoint& rRef,value_type fDist,
0581 std::vector<const _DataPoint*>& vFoundPoints) const
0582 {
0583 Parent()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0584 }
0585
0586
0587 template<class _DataPoint>
0588 KDTree<_DataPoint>::SplitNode::SplitNode(UInt_t iAxis,Double_t fCutValue,BaseNode& rLeft,
0589 BaseNode& rRight,BaseNode* pParent):
0590 BaseNode(pParent),
0591 fCut(new Cut(iAxis,fCutValue))
0592 {
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604 this->LeftChild() = &rLeft;
0605 this->RightChild() = &rRight;
0606 }
0607
0608
0609 template<class _DataPoint>
0610 KDTree<_DataPoint>::SplitNode::~SplitNode()
0611 {
0612
0613
0614 delete fCut;
0615 }
0616
0617
0618 template<class _DataPoint>
0619 typename KDTree<_DataPoint>::SplitNode* KDTree<_DataPoint>::SplitNode::Clone()
0620 {
0621
0622
0623
0624
0625 BaseNode* pLeft = this->LeftChild()->Clone();
0626 BaseNode* pRight = this->RightChild()->Clone();
0627
0628 SplitNode* pSplit = new SplitNode(fCut->GetAxis(),fCut->GetCutValue(),*pLeft,*pRight);
0629
0630 pLeft->Parent() = pSplit;
0631 pRight->Parent() = pSplit;
0632
0633 return pSplit;
0634 }
0635
0636
0637 template<class _DataPoint>
0638 const typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::SplitNode::FindNode(const _DataPoint& rPoint) const
0639 {
0640
0641
0642
0643 if(*fCut > rPoint)
0644 return this->LeftChild()->FindNode(rPoint);
0645
0646 else
0647 return this->RightChild()->FindNode(rPoint);
0648 }
0649
0650
0651 template<class _DataPoint>
0652 void KDTree<_DataPoint>::SplitNode::GetClosestPoints(const _DataPoint& rRef,UInt_t nPoints,
0653 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const
0654 {
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 if(*fCut > rRef)
0665 {
0666 this->LeftChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
0667
0668
0669
0670
0671 if((vFoundPoints.size() < nPoints) || (vFoundPoints.back().second > fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue())))
0672 this->RightChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
0673 }
0674
0675 else
0676 {
0677 this->RightChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
0678
0679
0680
0681
0682 if((vFoundPoints.size() < nPoints) || (vFoundPoints.back().second > fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue())))
0683 this->LeftChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
0684 }
0685 }
0686
0687
0688 template<class _DataPoint>
0689 void KDTree<_DataPoint>::SplitNode::GetPointsWithinDist(const _DataPoint& rRef,value_type fDist,
0690 std::vector<const _DataPoint*>& vFoundPoints) const
0691 {
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 if(fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue()) > fDist)
0703 {
0704
0705 if(*fCut > rRef)
0706 this->LeftChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0707
0708 else
0709 this->RightChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0710 }
0711
0712 else
0713 {
0714 this->RightChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0715 this->LeftChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
0716 }
0717 }
0718
0719
0720 template<class _DataPoint>
0721 inline Bool_t KDTree<_DataPoint>::SplitNode::Insert(const _DataPoint& rPoint)
0722 {
0723
0724
0725
0726 if(*fCut > rPoint)
0727 return this->LeftChild()->Insert(rPoint);
0728
0729 else
0730 return this->RightChild()->Insert(rPoint);
0731 }
0732
0733
0734 template<class _DataPoint>
0735 void KDTree<_DataPoint>::SplitNode::Print(int iRow) const
0736 {
0737
0738
0739 std::cout << "SplitNode at " << this << " in row " << iRow << std::endl;
0740 std::cout << "cut on " << fCut->GetCutValue() << " at axis " << fCut->GetAxis() << std::endl;
0741
0742 this->LeftChild()->Print(iRow+1);
0743 this->RightChild()->Print(iRow+1);
0744 }
0745
0746
0747 template<class _DataPoint>
0748 KDTree<_DataPoint>::BinNode::BinNode(BaseNode* pParent):
0749 BaseNode(pParent),
0750 fBoundaries(std::vector<tBoundary>(Dimension(),std::make_pair(0,0))),
0751 fSumw(0),
0752 fSumw2(0),
0753 fEntries(0)
0754 {
0755
0756 }
0757
0758
0759 template<class _DataPoint>
0760 KDTree<_DataPoint>::BinNode::BinNode(const BinNode& copy):
0761 BaseNode(),
0762 fBoundaries(copy.fBoundaries),
0763 fSumw(copy.fSumw),
0764 fSumw2(copy.fSumw2),
0765 fEntries(copy.fEntries)
0766 {
0767
0768
0769
0770
0771
0772 this->Parent() = 0;
0773 this->LeftChild() = 0;
0774 this->RightChild() = 0;
0775 }
0776
0777
0778 template<class _DataPoint>
0779 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::BinNode::Clone()
0780 {
0781
0782
0783 return new BinNode(*this);
0784 }
0785
0786
0787 template<class _DataPoint>
0788 void KDTree<_DataPoint>::BinNode::EmptyBin()
0789 {
0790
0791
0792 fSumw2 = fSumw = 0;
0793 fEntries = 0;
0794 }
0795
0796
0797 template<class _DataPoint>
0798 typename KDTree<_DataPoint>::BinNode& KDTree<_DataPoint>::BinNode::operator=(const BinNode& rhs)
0799 {
0800
0801
0802
0803
0804
0805 fBoundaries = rhs.fBoundaries;
0806 fSumw = rhs.fSumw;
0807 fSumw2 = rhs.fSumw2;
0808 fEntries = rhs.fEntries;
0809 return *this;
0810 }
0811
0812
0813 template<class _DataPoint>
0814 const typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::BinNode::FindNode(const _DataPoint& rPoint) const
0815 {
0816
0817
0818 if(IsInBin(rPoint))
0819 return this;
0820 else
0821 return 0;
0822 }
0823
0824
0825 template<class _DataPoint>
0826 _DataPoint KDTree<_DataPoint>::BinNode::GetBinCenter() const
0827 {
0828
0829
0830
0831
0832
0833 _DataPoint rPoint;
0834
0835 for(UInt_t k = 0; k < Dimension(); ++k)
0836 rPoint.SetCoordinate(k,0.5 * (fBoundaries.at(k).first + fBoundaries.at(k).second));
0837
0838 return rPoint;
0839 }
0840
0841
0842 template<class _DataPoint>
0843 Double_t KDTree<_DataPoint>::BinNode::GetVolume() const
0844 {
0845
0846
0847
0848
0849
0850 Double_t dVol = 1;
0851 for(typename std::vector<tBoundary>::const_iterator it = fBoundaries.begin(); it != fBoundaries.end(); ++it)
0852 dVol *= (it->second - it->first);
0853
0854 return dVol;
0855 }
0856
0857
0858
0859 template<class _DataPoint>
0860 Bool_t KDTree<_DataPoint>::BinNode::Insert(const _DataPoint& rPoint)
0861 {
0862
0863
0864 if(IsInBin(rPoint))
0865 {
0866 ++fEntries;
0867 fSumw += rPoint.GetWeight();
0868 fSumw2 += pow(rPoint.GetWeight(),2);
0869
0870 return true;
0871 }
0872 else
0873 return false;
0874 }
0875
0876
0877 template<class _DataPoint>
0878 Bool_t KDTree<_DataPoint>::BinNode::IsInBin(const _DataPoint& rPoint) const
0879 {
0880
0881
0882 for(UInt_t k = 0; k < Dimension(); ++k)
0883 if((rPoint.GetCoordinate(k) < fBoundaries.at(k).first) || (fBoundaries.at(k).second < rPoint.GetCoordinate(k)))
0884 return false;
0885
0886 return true;
0887 }
0888
0889
0890 template<class _DataPoint>
0891 void KDTree<_DataPoint>::BinNode::Print(int) const
0892 {
0893
0894
0895 std::cout << "BinNode at " << this << std::endl;
0896 std::cout << "containing " << GetEntries() << " entries" << std::endl;
0897 std::cout << "sumw = " << GetBinContent() << " sumw2 = " << GetSumw2() << " => effective entries = " << GetEffectiveEntries() << std::endl;
0898 std::cout << "volume = " << GetVolume() << " and bin center at (";
0899 _DataPoint rBinCenter = GetBinCenter();
0900 for(UInt_t dim = 0; dim < Dimension(); ++dim)
0901 {
0902 std::cout << rBinCenter.GetCoordinate(dim);
0903 if(dim < Dimension() -1)
0904 std::cout << ",";
0905 }
0906 std::cout << ")" << std::endl;
0907 std::cout << "boundaries are ";
0908 for(typename std::vector<tBoundary>::const_iterator it = fBoundaries.begin(); it != fBoundaries.end(); ++it)
0909 std::cout << "(" << it->first << " ... " << it->second << ") ";
0910 std::cout << std::endl;
0911 }
0912
0913
0914 template<class _DataPoint>
0915 KDTree<_DataPoint>::TerminalNode::TerminalNode(Double_t iBucketSize,BaseNode* pParent):
0916 BinNode(pParent),
0917 fOwnData(false),
0918 fSplitOption(kEffective),
0919 fBucketSize(iBucketSize),
0920 fSplitAxis(0)
0921 {
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931 assert(fBucketSize > 0);
0932 }
0933
0934
0935 template<class _DataPoint>
0936 KDTree<_DataPoint>::TerminalNode::TerminalNode(Double_t iBucketSize,UInt_t iSplitAxis,data_it first,data_it end):
0937 BinNode(),
0938 fOwnData(false),
0939 fSplitOption(kEffective),
0940 fBucketSize(iBucketSize),
0941 fSplitAxis(iSplitAxis % Dimension()),
0942 fDataPoints(std::vector<const _DataPoint*>(first,end))
0943 {
0944
0945
0946
0947
0948
0949
0950
0951
0952 for(data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
0953 {
0954 this->fSumw += (*it)->GetWeight();
0955 this->fSumw2 += pow((*it)->GetWeight(),2);
0956 }
0957
0958 this->fEntries = fDataPoints.size();
0959 }
0960
0961
0962 template<class _DataPoint>
0963 KDTree<_DataPoint>::TerminalNode::~TerminalNode()
0964 {
0965
0966
0967
0968
0969 if(fOwnData)
0970 {
0971 for(typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
0972 it != fDataPoints.end(); ++it)
0973 delete *it;
0974 }
0975 }
0976
0977
0978 template<class _DataPoint>
0979 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::TerminalNode::ConvertToBinNode()
0980 {
0981
0982
0983
0984
0985
0986
0987
0988 UpdateBoundaries();
0989 BinNode* pBin = new BinNode(*this);
0990
0991 return pBin;
0992 }
0993
0994
0995 template<class _DataPoint>
0996 void KDTree<_DataPoint>::TerminalNode::EmptyBin()
0997 {
0998
0999
1000
1001
1002
1003 if(fOwnData)
1004 {
1005 for(typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
1006 it != fDataPoints.end(); ++it)
1007 delete *it;
1008 }
1009 fDataPoints.clear();
1010 UpdateBoundaries();
1011 BinNode::EmptyBin();
1012 }
1013
1014 template<class _DataPoint>
1015 #ifdef _AIX
1016 void KDTree<_DataPoint>::TerminalNode::GetBoundaries() const { }
1017 #else
1018 const std::vector<typename KDTree<_DataPoint>::TerminalNode::tBoundary>& KDTree<_DataPoint>::TerminalNode::GetBoundaries() const
1019 {
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 const_cast<TerminalNode*>(this)->UpdateBoundaries();
1034
1035 return BinNode::GetBoundaries();
1036 }
1037 #endif
1038
1039 template<class _DataPoint>
1040 void KDTree<_DataPoint>::TerminalNode::GetClosestPoints(const _DataPoint& rRef,UInt_t nPoints,
1041 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints) const
1042 {
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 value_type fMaxDist = (vFoundPoints.size() < nPoints) ? std::numeric_limits<value_type>::max() : vFoundPoints.back().second;
1053 value_type fDist;
1054 typedef typename std::vector<std::pair<const _DataPoint*,Double_t> >::iterator t_pit;
1055
1056
1057 for(typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1058 {
1059 fDist = (*it)->Distance(rRef);
1060
1061 if(fDist < fMaxDist)
1062 {
1063
1064 t_pit pit = vFoundPoints.begin();
1065 while(pit != vFoundPoints.end())
1066 {
1067 if(pit->second > fDist)
1068 break;
1069 else
1070 ++pit;
1071 }
1072
1073 vFoundPoints.insert(pit,std::make_pair(*it,fDist));
1074
1075 if(vFoundPoints.size() > nPoints)
1076 vFoundPoints.resize(nPoints);
1077
1078 fMaxDist = (vFoundPoints.size() < nPoints) ? vFoundPoints.back().second : std::numeric_limits<value_type>::max();
1079 }
1080 }
1081 }
1082
1083
1084 template<class _DataPoint>
1085 void KDTree<_DataPoint>::TerminalNode::GetPointsWithinDist(const _DataPoint& rRef,value_type fDist,
1086 std::vector<const _DataPoint*>& vFoundPoints) const
1087 {
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 for(typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1098 {
1099 if((*it)->Distance(rRef) <= fDist)
1100 vFoundPoints.push_back(*it);
1101 }
1102 }
1103
1104
1105 template<class _DataPoint>
1106 Bool_t KDTree<_DataPoint>::TerminalNode::Insert(const _DataPoint& rPoint)
1107 {
1108
1109
1110
1111
1112
1113
1114 fDataPoints.push_back(&rPoint);
1115
1116
1117 this->fSumw += rPoint.GetWeight();
1118 this->fSumw2 += pow(rPoint.GetWeight(),2);
1119 ++this->fEntries;
1120
1121
1122 switch(fSplitOption)
1123 {
1124 case kEffective:
1125 if(this->GetEffectiveEntries() > 2 * fBucketSize)
1126 Split();
1127 break;
1128 case kBinContent:
1129 if(this->GetSumw() > 2 * fBucketSize)
1130 Split();
1131 break;
1132 default: assert(false);
1133 }
1134
1135 return true;
1136 }
1137
1138
1139 template<class _DataPoint>
1140 void KDTree<_DataPoint>::TerminalNode::Print(int iRow) const
1141 {
1142
1143
1144 std::cout << "TerminalNode at " << this << " in row " << iRow << std::endl;
1145 const_cast<TerminalNode*>(this)->UpdateBoundaries();
1146 BinNode::Print(iRow);
1147 std::cout << "next split axis: " << fSplitAxis << std::endl << std::endl;
1148 for(const_data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1149 {
1150 std::cout << "(";
1151 for(UInt_t i = 0; i < Dimension(); ++i)
1152 {
1153 std::cout << (*it)->GetCoordinate(i);
1154 if(i != Dimension() - 1)
1155 std::cout << ",";
1156 }
1157 std::cout << "), w = " << (*it)->GetWeight() << std::endl;
1158 }
1159
1160 std::cout << std::endl;
1161 }
1162
1163
1164 template<class _DataPoint>
1165 void KDTree<_DataPoint>::TerminalNode::Split()
1166 {
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 data_it cut;
1189 switch(fSplitOption)
1190 {
1191 case kEffective: cut = SplitEffectiveEntries(); break;
1192 case kBinContent: cut = SplitBinContent(); break;
1193 default: assert(false);
1194 }
1195
1196
1197 value_type fSplitValue = (*cut)->GetCoordinate(fSplitAxis);
1198
1199 TerminalNode* pNew = new TerminalNode(fBucketSize,fSplitAxis+1,cut,fDataPoints.end());
1200
1201 pNew->SetOwner(fOwnData);
1202 pNew->SetSplitOption(fSplitOption);
1203
1204
1205 fDataPoints.erase(cut,fDataPoints.end());
1206
1207 this->fSumw = this->fSumw2 = 0;
1208 for(data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1209 {
1210 this->fSumw += (*it)->GetWeight();
1211 this->fSumw2 += pow((*it)->GetWeight(),2);
1212 }
1213 this->fEntries = fDataPoints.size();
1214
1215
1216 SplitNode* pSplit = new SplitNode(fSplitAxis,fSplitValue,*this,*pNew,this->Parent());
1217
1218
1219 this->GetParentPointer() = pSplit;
1220
1221
1222 this->Parent() = pSplit;
1223 pNew->Parent() = pSplit;
1224
1225
1226 this->UpdateBoundaries();
1227 pNew->UpdateBoundaries();
1228
1229
1230 ++fSplitAxis;
1231 fSplitAxis = fSplitAxis % Dimension();
1232 }
1233
1234
1235 template<class _DataPoint>
1236 typename KDTree<_DataPoint>::TerminalNode::data_it KDTree<_DataPoint>::TerminalNode::SplitEffectiveEntries()
1237 {
1238
1239
1240
1241
1242
1243
1244
1245
1246 typename KDTree<_DataPoint>::ComparePoints cComp;
1247 cComp.SetAxis(fSplitAxis);
1248
1249 data_it first = fDataPoints.begin();
1250 data_it cut = first;
1251 data_it middle;
1252 UInt_t step = fDataPoints.size();
1253 Double_t fSumwTemp = 0;
1254 Double_t fSumw2Temp = 1e-7;
1255 Double_t fEffective = this->GetEffectiveEntries();
1256
1257
1258
1259 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (step > 1))
1260 {
1261 middle = first + (++step /= 2);
1262 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1263
1264 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (cut != middle-1))
1265 {
1266 fSumwTemp += (*cut)->GetWeight();
1267 fSumw2Temp += pow((*cut)->GetWeight(),2);
1268 ++cut;
1269 }
1270 first = middle;
1271 }
1272
1273 return cut;
1274 }
1275
1276
1277 template<class _DataPoint>
1278 typename KDTree<_DataPoint>::TerminalNode::data_it KDTree<_DataPoint>::TerminalNode::SplitBinContent()
1279 {
1280
1281
1282
1283
1284
1285
1286
1287
1288 typename KDTree<_DataPoint>::ComparePoints cComp;
1289 cComp.SetAxis(fSplitAxis);
1290
1291 data_it first = fDataPoints.begin();
1292 data_it cut = first;
1293 data_it middle;
1294 UInt_t step = fDataPoints.size();
1295 Double_t fSumwTemp = 0;
1296 Double_t fBinContent = this->GetSumw();
1297
1298
1299
1300 while((fSumwTemp < fBinContent/2) && (step > 1))
1301 {
1302 middle = first + (++step /= 2);
1303 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1304
1305 while((fSumwTemp < fBinContent/2) && (cut != middle-1))
1306 {
1307 fSumwTemp += (*cut)->GetWeight();
1308 ++cut;
1309 }
1310 first = middle;
1311 }
1312
1313 return cut;
1314 }
1315
1316
1317 template<class _DataPoint>
1318 void KDTree<_DataPoint>::TerminalNode::UpdateBoundaries()
1319 {
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333 const value_type fMAX = 0.4 * std::numeric_limits<value_type>::max();
1334 const value_type fMIN = -1.0 * fMAX;
1335
1336 this->fBoundaries = std::vector<tBoundary>(Dimension(),std::make_pair(fMIN,fMAX));
1337
1338
1339 const BaseNode* pNode = this->Parent();
1340 const SplitNode* pSplit = 0;
1341 const Cut* pCut = 0;
1342 bool bLeft = this->IsLeftChild();
1343 while(!pNode->IsHeadNode())
1344 {
1345 pSplit = dynamic_cast<const SplitNode*>(pNode);
1346 assert(pSplit);
1347 pCut = pSplit->GetCut();
1348
1349 if(bLeft)
1350 this->fBoundaries.at(pCut->GetAxis()).second = std::min(pCut->GetCutValue(),this->fBoundaries.at(pCut->GetAxis()).second);
1351
1352 else
1353 this->fBoundaries.at(pCut->GetAxis()).first = std::max(pCut->GetCutValue(),this->fBoundaries.at(pCut->GetAxis()).first);
1354
1355 bLeft = pNode->IsLeftChild();
1356 pNode = pNode->Parent();
1357 }
1358
1359
1360 if(fDataPoints.size())
1361 {
1362
1363 for(UInt_t dim = 0; dim < this->fBoundaries.size(); ++dim)
1364 {
1365
1366 if(this->fBoundaries.at(dim).first < 0.8*fMIN)
1367 {
1368 this->fBoundaries.at(dim).first = fMAX;
1369
1370 for(typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1371 it != fDataPoints.end(); ++it)
1372 {
1373 if((*it)->GetCoordinate(dim) < this->fBoundaries.at(dim).first)
1374 this->fBoundaries.at(dim).first = (*it)->GetCoordinate(dim);
1375 }
1376 }
1377
1378 if(this->fBoundaries.at(dim).second > 0.8*fMAX)
1379 {
1380 this->fBoundaries.at(dim).second = fMIN;
1381
1382 for(typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1383 it != fDataPoints.end(); ++it)
1384 {
1385 if((*it)->GetCoordinate(dim) > this->fBoundaries.at(dim).second)
1386 this->fBoundaries.at(dim).second = (*it)->GetCoordinate(dim);
1387 }
1388 }
1389 }
1390 }
1391 }
1392
1393
1394 template<class _DataPoint>
1395 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator++()
1396 {
1397
1398
1399 fBin = Next();
1400 return *this;
1401 }
1402
1403
1404 template<class _DataPoint>
1405 inline const typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator++() const
1406 {
1407
1408
1409 fBin = Next();
1410 return *this;
1411 }
1412
1413
1414 template<class _DataPoint>
1415 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator++(int)
1416 {
1417
1418
1419 iterator tmp(*this);
1420 fBin = Next();
1421 return tmp;
1422 }
1423
1424
1425 template<class _DataPoint>
1426 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator++(int) const
1427 {
1428
1429
1430 iterator tmp(*this);
1431 fBin = Next();
1432 return tmp;
1433 }
1434
1435
1436 template<class _DataPoint>
1437 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator--()
1438 {
1439
1440
1441 fBin = Previous();
1442 return *this;
1443 }
1444
1445
1446 template<class _DataPoint>
1447 inline const typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator--() const
1448 {
1449
1450
1451 fBin = Previous();
1452 return *this;
1453 }
1454
1455
1456 template<class _DataPoint>
1457 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator--(int)
1458 {
1459
1460
1461 iterator tmp(*this);
1462 fBin = Previous();
1463 return tmp;
1464 }
1465
1466
1467 template<class _DataPoint>
1468 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator--(int) const
1469 {
1470
1471
1472 iterator tmp(*this);
1473 fBin = Previous();
1474 return tmp;
1475 }
1476
1477
1478 template<class _DataPoint>
1479 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator=(const typename KDTree<_DataPoint>::iterator& rhs)
1480 {
1481
1482
1483 fBin = rhs.fBin;
1484 return *this;
1485 }
1486
1487
1488 template<class _DataPoint>
1489 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::iterator::Next() const
1490 {
1491
1492
1493
1494
1495 BaseNode* pNode = fBin;
1496
1497 while(!pNode->IsHeadNode())
1498 {
1499 if(pNode->IsLeftChild())
1500 {
1501 assert(pNode->Parent()->RightChild());
1502 pNode = pNode->Parent()->RightChild();
1503 while(pNode->LeftChild())
1504 pNode = pNode->LeftChild();
1505
1506 assert(dynamic_cast<BinNode*>(pNode));
1507 return (BinNode*)pNode;
1508 }
1509 else
1510 pNode = pNode->Parent();
1511 }
1512
1513 return 0;
1514 }
1515
1516
1517 template<class _DataPoint>
1518 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::iterator::Previous() const
1519 {
1520
1521
1522
1523
1524 BaseNode* pNode = fBin;
1525
1526 while(!pNode->IsHeadNode())
1527 {
1528 if(pNode->Parent()->RightChild() == pNode)
1529 {
1530 assert(pNode->Parent()->LeftChild());
1531 pNode = pNode->Parent()->LeftChild();
1532 while(pNode->RightChild())
1533 pNode = pNode->RightChild();
1534
1535 assert(dynamic_cast<BinNode*>(pNode));
1536 return (BinNode*)pNode;
1537 }
1538 else
1539 pNode = pNode->Parent();
1540 }
1541
1542 return 0;
1543 }
1544
1545 }
1546 }
1547
1548 #endif