17 #ifndef ROOT_Math_KDTree
18 #error "Do not use KDTree.icc directly. #include \"KDTree.h\" instead."
19 #endif // ROOT_Math_KDTree
32 template<
class _DataPo
int>
33 KDTree<_DataPoint>::KDTree(UInt_t iBucketSize):
34 fBucketSize(iBucketSize),
53 TerminalNode* pTerminal =
new TerminalNode(iBucketSize);
54 fHead =
new HeadNode(*pTerminal);
55 pTerminal->Parent() = fHead;
59 template<
class _DataPo
int>
60 KDTree<_DataPoint>::KDTree():
71 template<
class _DataPo
int>
72 KDTree<_DataPoint>::~KDTree()
84 template<
class _DataPo
int>
85 inline void KDTree<_DataPoint>::EmptyBins()
97 for(iterator it = First(); it != End(); ++it)
102 template<
class _DataPo
int>
103 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::End()
116 template<
class _DataPo
int>
117 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::End()
const
130 template<
class _DataPo
int>
131 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::First()
137 BaseNode* pNode = fHead->Parent();
138 while(pNode->LeftChild())
139 pNode = pNode->LeftChild();
141 assert(dynamic_cast<BinNode*>(pNode));
142 return iterator((BinNode*)pNode);
146 template<
class _DataPo
int>
147 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::First()
const
153 BaseNode* pNode = fHead->Parent();
154 while(pNode->LeftChild())
155 pNode = pNode->LeftChild();
157 assert(dynamic_cast<BinNode*>(pNode));
158 return iterator((BinNode*)pNode);
162 template<
class _DataPo
int>
163 void KDTree<_DataPoint>::Freeze()
180 std::vector<TerminalNode*> vBins;
182 for(iterator it = First(); it != End(); ++it)
183 vBins.push_back(it.TN());
186 for(
typename std::vector<TerminalNode*>::iterator bit = vBins.begin(); bit != vBins.end(); ++bit)
188 pBin = (*bit)->ConvertToBinNode();
189 (*bit)->GetParentPointer() = pBin;
190 pBin->Parent() = (*bit)->Parent();
199 template<
class _DataPo
int>
200 void KDTree<_DataPoint>::GetClosestPoints(
const _DataPoint& rRef,UInt_t nPoints,
201 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
218 if((nPoints > 0) && (!fIsFrozen))
219 fHead->GetClosestPoints(rRef,nPoints,vFoundPoints);
223 template<
class _DataPo
int>
224 Double_t KDTree<_DataPoint>::GetEffectiveEntries()
const
232 for(iterator it = First(); it != End(); ++it)
234 fSumw += it->GetBinContent();
235 fSumw2 += it->GetSumw2();
238 return ((fSumw2) ? fSumw * fSumw / fSumw2 : 0);
242 template<
class _DataPo
int>
243 UInt_t KDTree<_DataPoint>::GetEntries()
const
248 for(iterator it = First(); it != End(); ++it)
249 iPoints += it->GetEntries();
255 template<
class _DataPo
int>
256 KDTree<_DataPoint>* KDTree<_DataPoint>::GetFrozenCopy()
263 KDTree<_DataPoint>* pTree =
new KDTree<_DataPoint>();
264 pTree->fBucketSize = fBucketSize;
265 pTree->fHead = fHead->Clone();
266 pTree->fIsFrozen =
true;
272 template<
class _DataPo
int>
273 UInt_t KDTree<_DataPoint>::GetNBins()
const
278 for(iterator it = First(); it != End(); ++it)
285 template<
class _DataPo
int>
286 void KDTree<_DataPoint>::GetPointsWithinDist(
const _DataPoint& rRef,value_type fDist,
287 std::vector<const _DataPoint*>& vFoundPoints)
const
302 if((fDist > 0) && (!fIsFrozen))
303 fHead->GetPointsWithinDist(rRef,fDist,vFoundPoints);
307 template<
class _DataPo
int>
308 Double_t KDTree<_DataPoint>::GetTotalSumw()
const
313 for(iterator it = First(); it != End(); ++it)
314 fSumw += it->GetSumw();
320 template<
class _DataPo
int>
321 Double_t KDTree<_DataPoint>::GetTotalSumw2()
const
326 for(iterator it = First(); it != End(); ++it)
327 fSumw2 += it->GetSumw2();
333 template<
class _DataPo
int>
334 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::Last()
340 BaseNode* pNode = fHead->Parent();
341 while(pNode->RightChild())
342 pNode = pNode->RightChild();
344 assert(dynamic_cast<TerminalNode*>(pNode));
345 return iterator((TerminalNode*)pNode);
349 template<
class _DataPo
int>
350 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::Last()
const
356 BaseNode* pNode = fHead->Parent();
357 while(pNode->RightChild())
358 pNode = pNode->RightChild();
360 assert(dynamic_cast<BinNode*>(pNode));
361 return iterator((BinNode*)pNode);
365 template<
class _DataPo
int>
366 void KDTree<_DataPoint>::Reset()
379 delete fHead->Parent();
381 TerminalNode* pTerminal =
new TerminalNode(fBucketSize);
382 pTerminal->Parent() = fHead;
383 fHead->Parent() = pTerminal;
390 template<
class _DataPo
int>
391 void KDTree<_DataPoint>::SetOwner(Bool_t bIsOwner)
403 for(iterator it = First(); it != End(); ++it)
404 it.TN()->SetOwner(bIsOwner);
409 template<
class _DataPo
int>
410 void KDTree<_DataPoint>::SetSplitOption(eSplitOption opt)
426 for(iterator it = First(); it != End(); ++it)
427 it.TN()->SetSplitOption(opt);
432 template<
class _DataPo
int>
433 bool KDTree<_DataPoint>::ComparePoints::operator()(
const _DataPoint* pFirst,
const _DataPoint* pSecond)
const
449 assert(pFirst && pSecond && (fAxis < KDTree<_DataPoint>::Dimension()));
451 return (pFirst->GetCoordinate(fAxis) < pSecond->GetCoordinate(fAxis));
455 template<
class _DataPo
int>
456 bool KDTree<_DataPoint>::Cut::operator<(
const _DataPoint& rPoint)
const
470 assert(Dimension() > fAxis);
471 return (fCutValue < rPoint.GetCoordinate(fAxis));
475 template<
class _DataPo
int>
476 bool KDTree<_DataPoint>::Cut::operator>(
const _DataPoint& rPoint)
const
490 assert(Dimension() > fAxis);
491 return (fCutValue > rPoint.GetCoordinate(fAxis));
495 template<
class _DataPo
int>
496 KDTree<_DataPoint>::BaseNode::BaseNode(BaseNode* pParent):
505 template<
class _DataPo
int>
506 KDTree<_DataPoint>::BaseNode::~BaseNode()
519 template<
class _DataPo
int>
520 typename KDTree<_DataPoint>::BaseNode*& KDTree<_DataPoint>::BaseNode::GetParentPointer()
526 assert(!IsHeadNode());
528 if(Parent()->Parent() ==
this)
529 return Parent()->Parent();
530 if(Parent()->LeftChild() ==
this)
531 return Parent()->LeftChild();
532 if(Parent()->RightChild() ==
this)
533 return Parent()->RightChild();
541 template<
class _DataPo
int>
542 bool KDTree<_DataPoint>::BaseNode::IsLeftChild()
const
548 if(Parent()->IsHeadNode())
551 return (Parent()->LeftChild() ==
this);
555 template<
class _DataPo
int>
556 typename KDTree<_DataPoint>::HeadNode* KDTree<_DataPoint>::HeadNode::Clone()
563 BaseNode* pParent = Parent()->Clone();
564 HeadNode* pHead =
new HeadNode(*pParent);
565 pParent->Parent() = pHead;
571 template<
class _DataPo
int>
572 inline void KDTree<_DataPoint>::HeadNode::GetClosestPoints(
const _DataPoint& rRef,UInt_t nPoints,
573 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
575 Parent()->GetClosestPoints(rRef,nPoints,vFoundPoints);
579 template<
class _DataPo
int>
580 inline void KDTree<_DataPoint>::HeadNode::GetPointsWithinDist(
const _DataPoint& rRef,value_type fDist,
581 std::vector<const _DataPoint*>& vFoundPoints)
const
583 Parent()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
587 template<
class _DataPo
int>
588 KDTree<_DataPoint>::SplitNode::SplitNode(UInt_t iAxis,Double_t fCutValue,BaseNode& rLeft,
589 BaseNode& rRight,BaseNode* pParent):
591 fCut(new Cut(iAxis,fCutValue))
604 this->LeftChild() = &rLeft;
605 this->RightChild() = &rRight;
609 template<
class _DataPo
int>
610 KDTree<_DataPoint>::SplitNode::~SplitNode()
618 template<
class _DataPo
int>
619 typename KDTree<_DataPoint>::SplitNode* KDTree<_DataPoint>::SplitNode::Clone()
625 BaseNode* pLeft = this->LeftChild()->Clone();
626 BaseNode* pRight = this->RightChild()->Clone();
628 SplitNode* pSplit =
new SplitNode(fCut->GetAxis(),fCut->GetCutValue(),*pLeft,*pRight);
630 pLeft->Parent() = pSplit;
631 pRight->Parent() = pSplit;
637 template<
class _DataPo
int>
638 const typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::SplitNode::FindNode(
const _DataPoint& rPoint)
const
644 return this->LeftChild()->FindNode(rPoint);
647 return this->RightChild()->FindNode(rPoint);
651 template<
class _DataPo
int>
652 void KDTree<_DataPoint>::SplitNode::GetClosestPoints(
const _DataPoint& rRef,UInt_t nPoints,
653 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
666 this->LeftChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
671 if((vFoundPoints.size() < nPoints) || (vFoundPoints.back().second > fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue())))
672 this->RightChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
677 this->RightChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
682 if((vFoundPoints.size() < nPoints) || (vFoundPoints.back().second > fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue())))
683 this->LeftChild()->GetClosestPoints(rRef,nPoints,vFoundPoints);
688 template<
class _DataPo
int>
689 void KDTree<_DataPoint>::SplitNode::GetPointsWithinDist(
const _DataPoint& rRef,value_type fDist,
690 std::vector<const _DataPoint*>& vFoundPoints)
const
702 if(fabs(rRef.GetCoordinate(fCut->GetAxis()) - fCut->GetCutValue()) > fDist)
706 this->LeftChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
709 this->RightChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
714 this->RightChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
715 this->LeftChild()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
720 template<
class _DataPo
int>
721 inline Bool_t KDTree<_DataPoint>::SplitNode::Insert(
const _DataPoint& rPoint)
727 return this->LeftChild()->Insert(rPoint);
730 return this->RightChild()->Insert(rPoint);
734 template<
class _DataPo
int>
735 void KDTree<_DataPoint>::SplitNode::Print(
int iRow)
const
739 std::cout <<
"SplitNode at " <<
this <<
" in row " << iRow << std::endl;
740 std::cout <<
"cut on " << fCut->GetCutValue() <<
" at axis " << fCut->GetAxis() << std::endl;
742 this->LeftChild()->Print(iRow+1);
743 this->RightChild()->Print(iRow+1);
747 template<
class _DataPo
int>
748 KDTree<_DataPoint>::BinNode::BinNode(BaseNode* pParent):
750 fBoundaries(std::vector<tBoundary>(Dimension(),std::make_pair(0,0))),
759 template<
class _DataPo
int>
760 KDTree<_DataPoint>::BinNode::BinNode(
const BinNode& copy):
762 fBoundaries(copy.fBoundaries),
765 fEntries(copy.fEntries)
773 this->LeftChild() = 0;
774 this->RightChild() = 0;
778 template<
class _DataPo
int>
779 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::BinNode::Clone()
783 return new BinNode(*
this);
787 template<
class _DataPo
int>
788 void KDTree<_DataPoint>::BinNode::EmptyBin()
797 template<
class _DataPo
int>
798 typename KDTree<_DataPoint>::BinNode& KDTree<_DataPoint>::BinNode::operator=(
const BinNode& rhs)
805 fBoundaries = rhs.fBoundaries;
808 fEntries = rhs.fEntries;
813 template<
class _DataPo
int>
814 const typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::BinNode::FindNode(
const _DataPoint& rPoint)
const
825 template<
class _DataPo
int>
826 _DataPoint KDTree<_DataPoint>::BinNode::GetBinCenter()
const
835 for(UInt_t k = 0; k < Dimension(); ++k)
836 rPoint.SetCoordinate(k,0.5 * (fBoundaries.at(k).first + fBoundaries.at(k).second));
842 template<
class _DataPo
int>
843 Double_t KDTree<_DataPoint>::BinNode::GetVolume()
const
851 for(
typename std::vector<tBoundary>::const_iterator it = fBoundaries.begin(); it != fBoundaries.end(); ++it)
852 dVol *= (it->second - it->first);
859 template<
class _DataPo
int>
860 Bool_t KDTree<_DataPoint>::BinNode::Insert(
const _DataPoint& rPoint)
867 fSumw += rPoint.GetWeight();
868 fSumw2 += pow(rPoint.GetWeight(),2);
877 template<
class _DataPo
int>
878 Bool_t KDTree<_DataPoint>::BinNode::IsInBin(
const _DataPoint& rPoint)
const
882 for(UInt_t k = 0; k < Dimension(); ++k)
883 if((rPoint.GetCoordinate(k) < fBoundaries.at(k).first) || (fBoundaries.at(k).second < rPoint.GetCoordinate(k)))
890 template<
class _DataPo
int>
891 void KDTree<_DataPoint>::BinNode::Print(
int)
const
895 std::cout <<
"BinNode at " <<
this << std::endl;
896 std::cout <<
"containing " << GetEntries() <<
" entries" << std::endl;
897 std::cout <<
"sumw = " << GetBinContent() <<
" sumw2 = " << GetSumw2() <<
" => effective entries = " << GetEffectiveEntries() << std::endl;
898 std::cout <<
"volume = " << GetVolume() <<
" and bin center at (";
899 _DataPoint rBinCenter = GetBinCenter();
900 for(UInt_t dim = 0; dim < Dimension(); ++dim)
902 std::cout << rBinCenter.GetCoordinate(dim);
903 if(dim < Dimension() -1)
906 std::cout <<
")" << std::endl;
907 std::cout <<
"boundaries are ";
908 for(
typename std::vector<tBoundary>::const_iterator it = fBoundaries.begin(); it != fBoundaries.end(); ++it)
909 std::cout <<
"(" << it->first <<
" ... " << it->second <<
") ";
910 std::cout << std::endl;
914 template<
class _DataPo
int>
915 KDTree<_DataPoint>::TerminalNode::TerminalNode(Double_t iBucketSize,BaseNode* pParent):
918 fSplitOption(kEffective),
919 fBucketSize(iBucketSize),
931 assert(fBucketSize > 0);
935 template<
class _DataPo
int>
936 KDTree<_DataPoint>::TerminalNode::TerminalNode(Double_t iBucketSize,UInt_t iSplitAxis,data_it first,data_it end):
939 fSplitOption(kEffective),
940 fBucketSize(iBucketSize),
941 fSplitAxis(iSplitAxis % Dimension()),
942 fDataPoints(std::vector<const _DataPoint*>(first,end))
952 for(data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
954 this->fSumw += (*it)->GetWeight();
955 this->fSumw2 += pow((*it)->GetWeight(),2);
958 this->fEntries = fDataPoints.size();
962 template<
class _DataPo
int>
963 KDTree<_DataPoint>::TerminalNode::~TerminalNode()
971 for(
typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
972 it != fDataPoints.end(); ++it)
978 template<
class _DataPo
int>
979 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::TerminalNode::ConvertToBinNode()
989 BinNode* pBin =
new BinNode(*
this);
995 template<
class _DataPo
int>
996 void KDTree<_DataPoint>::TerminalNode::EmptyBin()
1005 for(
typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
1006 it != fDataPoints.end(); ++it)
1009 fDataPoints.clear();
1011 BinNode::EmptyBin();
1014 template<
class _DataPo
int>
1016 void KDTree<_DataPoint>::TerminalNode::GetBoundaries()
const { }
1018 const std::vector<typename KDTree<_DataPoint>::TerminalNode::tBoundary>& KDTree<_DataPoint>::TerminalNode::GetBoundaries()
const
1033 const_cast<TerminalNode*
>(
this)->UpdateBoundaries();
1035 return BinNode::GetBoundaries();
1039 template<
class _DataPo
int>
1040 void KDTree<_DataPoint>::TerminalNode::GetClosestPoints(
const _DataPoint& rRef,UInt_t nPoints,
1041 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
1052 value_type fMaxDist = (vFoundPoints.size() < nPoints) ? std::numeric_limits<value_type>::max() : vFoundPoints.back().second;
1054 typedef typename std::vector<std::pair<const _DataPoint*,Double_t> >::iterator t_pit;
1057 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1059 fDist = (*it)->Distance(rRef);
1061 if(fDist < fMaxDist)
1064 t_pit pit = vFoundPoints.begin();
1065 while(pit != vFoundPoints.end())
1067 if(pit->second > fDist)
1073 vFoundPoints.insert(pit,std::make_pair(*it,fDist));
1075 if(vFoundPoints.size() > nPoints)
1076 vFoundPoints.resize(nPoints);
1078 fMaxDist = (vFoundPoints.size() < nPoints) ? vFoundPoints.back().second : std::numeric_limits<value_type>::max();
1084 template<
class _DataPo
int>
1085 void KDTree<_DataPoint>::TerminalNode::GetPointsWithinDist(
const _DataPoint& rRef,value_type fDist,
1086 std::vector<const _DataPoint*>& vFoundPoints)
const
1097 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1099 if((*it)->Distance(rRef) <= fDist)
1100 vFoundPoints.push_back(*it);
1105 template<
class _DataPo
int>
1106 Bool_t KDTree<_DataPoint>::TerminalNode::Insert(
const _DataPoint& rPoint)
1114 fDataPoints.push_back(&rPoint);
1117 this->fSumw += rPoint.GetWeight();
1118 this->fSumw2 += pow(rPoint.GetWeight(),2);
1122 switch(fSplitOption)
1125 if(this->GetEffectiveEntries() > 2 * fBucketSize)
1129 if(this->GetSumw() > 2 * fBucketSize)
1132 default: assert(
false);
1139 template<
class _DataPo
int>
1140 void KDTree<_DataPoint>::TerminalNode::Print(
int iRow)
const
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)
1151 for(UInt_t i = 0; i < Dimension(); ++i)
1153 std::cout << (*it)->GetCoordinate(i);
1154 if(i != Dimension() - 1)
1157 std::cout <<
"), w = " << (*it)->GetWeight() << std::endl;
1160 std::cout << std::endl;
1164 template<
class _DataPo
int>
1165 void KDTree<_DataPoint>::TerminalNode::Split()
1189 switch(fSplitOption)
1191 case kEffective: cut = SplitEffectiveEntries();
break;
1192 case kBinContent: cut = SplitBinContent();
break;
1193 default: assert(
false);
1197 value_type fSplitValue = (*cut)->GetCoordinate(fSplitAxis);
1199 TerminalNode* pNew =
new TerminalNode(fBucketSize,fSplitAxis+1,cut,fDataPoints.end());
1201 pNew->SetOwner(fOwnData);
1202 pNew->SetSplitOption(fSplitOption);
1205 fDataPoints.erase(cut,fDataPoints.end());
1207 this->fSumw = this->fSumw2 = 0;
1208 for(data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1210 this->fSumw += (*it)->GetWeight();
1211 this->fSumw2 += pow((*it)->GetWeight(),2);
1213 this->fEntries = fDataPoints.size();
1216 SplitNode* pSplit =
new SplitNode(fSplitAxis,fSplitValue,*
this,*pNew,this->Parent());
1219 this->GetParentPointer() = pSplit;
1222 this->Parent() = pSplit;
1223 pNew->Parent() = pSplit;
1226 this->UpdateBoundaries();
1227 pNew->UpdateBoundaries();
1231 fSplitAxis = fSplitAxis % Dimension();
1235 template<
class _DataPo
int>
1236 typename KDTree<_DataPoint>::TerminalNode::data_it KDTree<_DataPoint>::TerminalNode::SplitEffectiveEntries()
1246 typename KDTree<_DataPoint>::ComparePoints cComp;
1247 cComp.SetAxis(fSplitAxis);
1249 data_it first = fDataPoints.begin();
1250 data_it cut = first;
1252 UInt_t step = fDataPoints.size();
1253 Double_t fSumwTemp = 0;
1254 Double_t fSumw2Temp = 1e-7;
1255 Double_t fEffective = this->GetEffectiveEntries();
1259 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (step > 1))
1261 middle = first + (++step /= 2);
1262 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1264 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (cut != middle-1))
1266 fSumwTemp += (*cut)->GetWeight();
1267 fSumw2Temp += pow((*cut)->GetWeight(),2);
1277 template<
class _DataPo
int>
1278 typename KDTree<_DataPoint>::TerminalNode::data_it KDTree<_DataPoint>::TerminalNode::SplitBinContent()
1288 typename KDTree<_DataPoint>::ComparePoints cComp;
1289 cComp.SetAxis(fSplitAxis);
1291 data_it first = fDataPoints.begin();
1292 data_it cut = first;
1294 UInt_t step = fDataPoints.size();
1295 Double_t fSumwTemp = 0;
1296 Double_t fBinContent = this->GetSumw();
1300 while((fSumwTemp < fBinContent/2) && (step > 1))
1302 middle = first + (++step /= 2);
1303 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1305 while((fSumwTemp < fBinContent/2) && (cut != middle-1))
1307 fSumwTemp += (*cut)->GetWeight();
1317 template<
class _DataPo
int>
1318 void KDTree<_DataPoint>::TerminalNode::UpdateBoundaries()
1333 const value_type fMAX = 0.4 * std::numeric_limits<value_type>::max();
1334 const value_type fMIN = -1.0 * fMAX;
1336 this->fBoundaries = std::vector<tBoundary>(Dimension(),std::make_pair(fMIN,fMAX));
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())
1345 pSplit =
dynamic_cast<const SplitNode*
>(pNode);
1347 pCut = pSplit->GetCut();
1350 this->fBoundaries.at(pCut->GetAxis()).second = std::min(pCut->GetCutValue(),this->fBoundaries.at(pCut->GetAxis()).second);
1353 this->fBoundaries.at(pCut->GetAxis()).first = std::max(pCut->GetCutValue(),this->fBoundaries.at(pCut->GetAxis()).first);
1355 bLeft = pNode->IsLeftChild();
1356 pNode = pNode->Parent();
1360 if(fDataPoints.size())
1363 for(UInt_t dim = 0; dim < this->fBoundaries.size(); ++dim)
1366 if(this->fBoundaries.at(dim).first < 0.8*fMIN)
1368 this->fBoundaries.at(dim).first = fMAX;
1370 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1371 it != fDataPoints.end(); ++it)
1373 if((*it)->GetCoordinate(dim) < this->fBoundaries.at(dim).first)
1374 this->fBoundaries.at(dim).first = (*it)->GetCoordinate(dim);
1378 if(this->fBoundaries.at(dim).second > 0.8*fMAX)
1380 this->fBoundaries.at(dim).second = fMIN;
1382 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1383 it != fDataPoints.end(); ++it)
1385 if((*it)->GetCoordinate(dim) > this->fBoundaries.at(dim).second)
1386 this->fBoundaries.at(dim).second = (*it)->GetCoordinate(dim);
1394 template<
class _DataPo
int>
1395 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator++()
1404 template<
class _DataPo
int>
1405 inline const typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator++()
const
1414 template<
class _DataPo
int>
1415 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator++(
int)
1419 iterator tmp(*
this);
1425 template<
class _DataPo
int>
1426 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator++(
int)
const
1430 iterator tmp(*
this);
1436 template<
class _DataPo
int>
1437 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator--()
1446 template<
class _DataPo
int>
1447 inline const typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator--()
const
1456 template<
class _DataPo
int>
1457 inline typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator--(
int)
1461 iterator tmp(*
this);
1467 template<
class _DataPo
int>
1468 inline const typename KDTree<_DataPoint>::iterator KDTree<_DataPoint>::iterator::operator--(
int)
const
1472 iterator tmp(*
this);
1478 template<
class _DataPo
int>
1479 inline typename KDTree<_DataPoint>::iterator& KDTree<_DataPoint>::iterator::operator=(
const typename KDTree<_DataPoint>::iterator& rhs)
1488 template<
class _DataPo
int>
1489 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::iterator::Next()
const
1495 BaseNode* pNode = fBin;
1497 while(!pNode->IsHeadNode())
1499 if(pNode->IsLeftChild())
1501 assert(pNode->Parent()->RightChild());
1502 pNode = pNode->Parent()->RightChild();
1503 while(pNode->LeftChild())
1504 pNode = pNode->LeftChild();
1506 assert(dynamic_cast<BinNode*>(pNode));
1507 return (BinNode*)pNode;
1510 pNode = pNode->Parent();
1517 template<
class _DataPo
int>
1518 typename KDTree<_DataPoint>::BinNode* KDTree<_DataPoint>::iterator::Previous()
const
1524 BaseNode* pNode = fBin;
1526 while(!pNode->IsHeadNode())
1528 if(pNode->Parent()->RightChild() == pNode)
1530 assert(pNode->Parent()->LeftChild());
1531 pNode = pNode->Parent()->LeftChild();
1532 while(pNode->RightChild())
1533 pNode = pNode->RightChild();
1535 assert(dynamic_cast<BinNode*>(pNode));
1536 return (BinNode*)pNode;
1539 pNode = pNode->Parent();
1548 #endif //KD_TREE_ICC