17#ifndef ROOT_Math_KDTree
18#error "Do not use KDTree.icc directly. #include \"KDTree.h\" instead."
32 template<
class _DataPo
int>
34 fBucketSize(iBucketSize),
59 template<
class _DataPo
int>
71 template<
class _DataPo
int>
84 template<
class _DataPo
int>
97 for(
iterator it = First(); it != End(); ++it)
102 template<
class _DataPo
int>
116 template<
class _DataPo
int>
130 template<
class _DataPo
int>
141 assert(
dynamic_cast<BinNode*
>(pNode));
146 template<
class _DataPo
int>
157 assert(
dynamic_cast<BinNode*
>(pNode));
162 template<
class _DataPo
int>
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();
199 template<
class _DataPo
int>
201 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
218 if((nPoints > 0) && (!fIsFrozen))
223 template<
class _DataPo
int>
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>
248 for(
iterator it = First(); it != End(); ++it)
249 iPoints += it->GetEntries();
255 template<
class _DataPo
int>
272 template<
class _DataPo
int>
278 for(
iterator it = First(); it != End(); ++it)
285 template<
class _DataPo
int>
287 std::vector<const _DataPoint*>& vFoundPoints)
const
302 if((fDist > 0) && (!fIsFrozen))
303 fHead->GetPointsWithinDist(rRef,fDist,vFoundPoints);
307 template<
class _DataPo
int>
313 for(
iterator it = First(); it != End(); ++it)
314 fSumw += it->GetSumw();
320 template<
class _DataPo
int>
326 for(
iterator it = First(); it != End(); ++it)
327 fSumw2 += it->GetSumw2();
333 template<
class _DataPo
int>
349 template<
class _DataPo
int>
360 assert(
dynamic_cast<BinNode*
>(pNode));
365 template<
class _DataPo
int>
379 delete fHead->Parent();
382 pTerminal->
Parent() = fHead;
383 fHead->
Parent() = pTerminal;
390 template<
class _DataPo
int>
403 for(
iterator it = First(); it != End(); ++it)
409 template<
class _DataPo
int>
426 for(
iterator it = First(); it != End(); ++it)
427 it.TN()->SetSplitOption(opt);
432 template<
class _DataPo
int>
451 return (pFirst->GetCoordinate(
fAxis) < pSecond->GetCoordinate(
fAxis));
455 template<
class _DataPo
int>
471 return (fCutValue < rPoint.GetCoordinate(fAxis));
475 template<
class _DataPo
int>
491 return (fCutValue > rPoint.GetCoordinate(fAxis));
495 template<
class _DataPo
int>
505 template<
class _DataPo
int>
519 template<
class _DataPo
int>
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>
548 if(Parent()->IsHeadNode())
551 return (Parent()->LeftChild() ==
this);
555 template<
class _DataPo
int>
565 pParent->
Parent() = pHead;
571 template<
class _DataPo
int>
573 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
579 template<
class _DataPo
int>
581 std::vector<const _DataPoint*>& vFoundPoints)
const
583 Parent()->GetPointsWithinDist(rRef,fDist,vFoundPoints);
587 template<
class _DataPo
int>
591 fCut(new
Cut(iAxis,fCutValue))
609 template<
class _DataPo
int>
618 template<
class _DataPo
int>
628 SplitNode* pSplit =
new SplitNode(fCut->GetAxis(),fCut->GetCutValue(),*pLeft,*pRight);
631 pRight->
Parent() = pSplit;
637 template<
class _DataPo
int>
644 return this->LeftChild()->
FindNode(rPoint);
647 return this->RightChild()->
FindNode(rPoint);
651 template<
class _DataPo
int>
653 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
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>
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>
727 return this->LeftChild()->Insert(rPoint);
730 return this->RightChild()->Insert(rPoint);
734 template<
class _DataPo
int>
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>
759 template<
class _DataPo
int>
762 fBoundaries(copy.fBoundaries),
765 fEntries(copy.fEntries)
778 template<
class _DataPo
int>
787 template<
class _DataPo
int>
797 template<
class _DataPo
int>
813 template<
class _DataPo
int>
825 template<
class _DataPo
int>
836 rPoint.SetCoordinate(k,0.5 * (fBoundaries.at(k).first + fBoundaries.at(k).second));
842 template<
class _DataPo
int>
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>
867 fSumw += rPoint.GetWeight();
868 fSumw2 += pow(rPoint.GetWeight(),2);
877 template<
class _DataPo
int>
883 if((rPoint.GetCoordinate(k) < fBoundaries.at(k).first) || (fBoundaries.at(k).second < rPoint.GetCoordinate(k)))
890 template<
class _DataPo
int>
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();
902 std::cout << rBinCenter.GetCoordinate(dim);
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>
935 template<
class _DataPo
int>
942 fDataPoints(std::vector<const _DataPoint*>(first,end))
954 this->
fSumw += (*it)->GetWeight();
955 this->
fSumw2 += pow((*it)->GetWeight(),2);
962 template<
class _DataPo
int>
971 for(
typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
972 it != fDataPoints.end(); ++it)
978 template<
class _DataPo
int>
995 template<
class _DataPo
int>
1005 for(
typename std::vector<const _DataPoint*>::iterator it = fDataPoints.begin();
1006 it != fDataPoints.end(); ++it)
1009 fDataPoints.clear();
1014 template<
class _DataPo
int>
1039 template<
class _DataPo
int>
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>
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>
1114 fDataPoints.push_back(&rPoint);
1117 this->fSumw += rPoint.GetWeight();
1118 this->fSumw2 += pow(rPoint.GetWeight(),2);
1122 switch(fSplitOption)
1132 default: assert(
false);
1139 template<
class _DataPo
int>
1144 std::cout <<
"TerminalNode at " <<
this <<
" in row " << iRow << std::endl;
1147 std::cout <<
"next split axis: " << fSplitAxis << std::endl << std::endl;
1148 for(
const_data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1153 std::cout << (*it)->GetCoordinate(i);
1157 std::cout <<
"), w = " << (*it)->GetWeight() << std::endl;
1160 std::cout << std::endl;
1164 template<
class _DataPo
int>
1189 switch(fSplitOption)
1191 case kEffective: cut = SplitEffectiveEntries();
break;
1193 default: assert(
false);
1197 value_type fSplitValue = (*cut)->GetCoordinate(fSplitAxis);
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;
1226 this->UpdateBoundaries();
1235 template<
class _DataPo
int>
1249 data_it first = fDataPoints.begin();
1252 UInt_t step = fDataPoints.size();
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>
1291 data_it first = fDataPoints.begin();
1294 UInt_t step = fDataPoints.size();
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>
1333 const value_type fMAX = 0.4 * std::numeric_limits<value_type>::max();
1336 this->fBoundaries = std::vector<tBoundary>(
Dimension(),std::make_pair(fMIN,fMAX));
1339 const BaseNode* pNode = this->Parent();
1341 const Cut* pCut = 0;
1342 bool bLeft = this->IsLeftChild();
1345 pSplit =
dynamic_cast<const SplitNode*
>(pNode);
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);
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>
1404 template<
class _DataPo
int>
1414 template<
class _DataPo
int>
1425 template<
class _DataPo
int>
1436 template<
class _DataPo
int>
1446 template<
class _DataPo
int>
1456 template<
class _DataPo
int>
1467 template<
class _DataPo
int>
1478 template<
class _DataPo
int>
1488 template<
class _DataPo
int>
1506 assert(
dynamic_cast<BinNode*
>(pNode));
1517 template<
class _DataPo
int>
1535 assert(
dynamic_cast<BinNode*
>(pNode));
BaseNode *& GetParentPointer()
virtual void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const =0
Bool_t IsLeftChild() const
virtual Bool_t IsHeadNode() const
BaseNode(BaseNode *pParent=0)
virtual BaseNode * Clone()=0
virtual const std::vector< tBoundary > & GetBoundaries() const
std::vector< tBoundary > fBoundaries
bin boundaries
virtual const BinNode * FindNode(const point_type &rPoint) const
BinNode(BaseNode *pParent=0)
virtual BinNode * Clone()
point_type GetBinCenter() const
virtual void GetClosestPoints(const point_type &, UInt_t, std::vector< std::pair< const _DataPoint *, Double_t > > &) const
virtual Bool_t Insert(const point_type &rPoint)
std::pair< value_type, value_type > tBoundary
Bool_t IsInBin(const point_type &rPoint) const
BinNode & operator=(const BinNode &rhs)
Double_t fSumw2
sum of weights^2
virtual void Print(int iRow=0) const
UInt_t fEntries
number of entries
Double_t fSumw
sum of weights
Double_t GetVolume() const
Bool_t operator()(const point_type *pFirst, const point_type *pSecond) const
void SetAxis(UInt_t iAxis)
value_type GetCutValue() const
Bool_t operator>(const point_type &rPoint) const
Bool_t operator<(const point_type &rPoint) const
virtual void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const
virtual HeadNode * Clone()
virtual void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const
SplitNode(UInt_t iAxis, Double_t fCutValue, BaseNode &rLeft, BaseNode &rRight, BaseNode *pParent=0)
virtual void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const
virtual void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const
const Cut * GetCut() const
virtual const BinNode * FindNode(const point_type &rPoint) const
virtual SplitNode * Clone()
virtual void Print(Int_t iRow=0) const
virtual Bool_t Insert(const point_type &rPoint)
virtual const std::vector< tBoundary > & GetBoundaries() const
data_it SplitBinContent()
std::vector< constpoint_type * >::iterator data_it
Double_t fBucketSize
target number of entries per bucket
void SetOwner(Bool_t bIsOwner=true)
void SetSplitOption(eSplitOption opt)
virtual void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const
BinNode * ConvertToBinNode()
virtual void Print(int iRow=0) const
TerminalNode(Double_t iBucketSize, BaseNode *pParent=0)
virtual Bool_t Insert(const point_type &rPoint)
std::vector< constpoint_type * >::const_iterator const_data_it
virtual void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const
data_it SplitEffectiveEntries()
std::vector< const _DataPoint * > fDataPoints
data points in this bucket
iterator & operator=(const iterator &rhs)
Double_t GetTotalSumw2() const
void SetOwner(Bool_t bIsOwner=true)
KDTree< _DataPoint > * GetFrozenCopy()
Double_t GetTotalSumw() const
_DataPoint::value_type value_type
UInt_t GetEntries() const
void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const point_type * > &vFoundPoints) const
Double_t GetEffectiveEntries() const
void SetSplitOption(eSplitOption opt)
void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const
static UInt_t Dimension()
Namespace for new Math classes and functions.
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.