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))
219 fHead->GetClosestPoints(rRef,nPoints,vFoundPoints);
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)
404 it.TN()->SetOwner(bIsOwner);
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
575 Parent()->GetClosestPoints(rRef,nPoints,vFoundPoints);
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
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>
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>
1036 template<
class _DataPo
int>
1038 std::vector<std::pair<const _DataPoint*,Double_t> >& vFoundPoints)
const
1049 value_type fMaxDist = (vFoundPoints.size() < nPoints) ? std::numeric_limits<value_type>::max() : vFoundPoints.back().second;
1051 typedef typename std::vector<std::pair<const _DataPoint*,Double_t> >::iterator t_pit;
1054 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1056 fDist = (*it)->Distance(rRef);
1058 if(fDist < fMaxDist)
1061 t_pit pit = vFoundPoints.begin();
1062 while(pit != vFoundPoints.end())
1064 if(pit->second > fDist)
1070 vFoundPoints.insert(pit,std::make_pair(*it,fDist));
1072 if(vFoundPoints.size() > nPoints)
1073 vFoundPoints.resize(nPoints);
1075 fMaxDist = (vFoundPoints.size() < nPoints) ? vFoundPoints.back().second : std::numeric_limits<value_type>::max();
1081 template<
class _DataPo
int>
1083 std::vector<const _DataPoint*>& vFoundPoints)
const
1094 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1096 if((*it)->Distance(rRef) <= fDist)
1097 vFoundPoints.push_back(*it);
1102 template<
class _DataPo
int>
1111 fDataPoints.push_back(&rPoint);
1114 this->fSumw += rPoint.GetWeight();
1115 this->fSumw2 += pow(rPoint.GetWeight(),2);
1119 switch(fSplitOption)
1129 default: assert(
false);
1136 template<
class _DataPo
int>
1141 std::cout <<
"TerminalNode at " <<
this <<
" in row " << iRow << std::endl;
1144 std::cout <<
"next split axis: " << fSplitAxis << std::endl << std::endl;
1145 for(
const_data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1150 std::cout << (*it)->GetCoordinate(i);
1154 std::cout <<
"), w = " << (*it)->GetWeight() << std::endl;
1157 std::cout << std::endl;
1161 template<
class _DataPo
int>
1186 switch(fSplitOption)
1188 case kEffective: cut = SplitEffectiveEntries();
break;
1190 default: assert(
false);
1194 value_type fSplitValue = (*cut)->GetCoordinate(fSplitAxis);
1202 fDataPoints.erase(cut,fDataPoints.end());
1204 this->fSumw = this->fSumw2 = 0;
1205 for(
data_it it = fDataPoints.begin(); it != fDataPoints.end(); ++it)
1207 this->fSumw += (*it)->GetWeight();
1208 this->fSumw2 += pow((*it)->GetWeight(),2);
1210 this->fEntries = fDataPoints.size();
1213 SplitNode* pSplit =
new SplitNode(fSplitAxis,fSplitValue,*
this,*pNew,this->Parent());
1216 this->GetParentPointer() = pSplit;
1219 this->Parent() = pSplit;
1223 this->UpdateBoundaries();
1232 template<
class _DataPo
int>
1246 data_it first = fDataPoints.begin();
1249 UInt_t step = fDataPoints.size();
1256 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (step > 1))
1258 middle = first + (++step /= 2);
1259 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1261 while(((fSumwTemp * fSumwTemp)/fSumw2Temp < fEffective/2) && (cut != middle-1))
1263 fSumwTemp += (*cut)->GetWeight();
1264 fSumw2Temp += pow((*cut)->GetWeight(),2);
1274 template<
class _DataPo
int>
1288 data_it first = fDataPoints.begin();
1291 UInt_t step = fDataPoints.size();
1293 Double_t fBinContent = this->GetSumw();
1297 while((fSumwTemp < fBinContent/2) && (step > 1))
1299 middle = first + (++step /= 2);
1300 std::partial_sort(first,middle,fDataPoints.end(),cComp);
1302 while((fSumwTemp < fBinContent/2) && (cut != middle-1))
1304 fSumwTemp += (*cut)->GetWeight();
1314 template<
class _DataPo
int>
1330 const value_type fMAX = 0.4 * std::numeric_limits<value_type>::max();
1333 this->fBoundaries = std::vector<tBoundary>(
Dimension(),std::make_pair(fMIN,fMAX));
1336 const BaseNode* pNode = this->Parent();
1338 const Cut* pCut = 0;
1339 bool bLeft = this->IsLeftChild();
1342 pSplit =
dynamic_cast<const SplitNode*
>(pNode);
1347 this->fBoundaries.at(pCut->
GetAxis()).second = std::min(pCut->
GetCutValue(),this->fBoundaries.at(pCut->
GetAxis()).second);
1350 this->fBoundaries.at(pCut->
GetAxis()).first = std::max(pCut->
GetCutValue(),this->fBoundaries.at(pCut->
GetAxis()).first);
1357 if(fDataPoints.size())
1360 for(
UInt_t dim = 0; dim < this->fBoundaries.size(); ++dim)
1363 if(this->fBoundaries.at(dim).first < 0.8*fMIN)
1365 this->fBoundaries.at(dim).first = fMAX;
1367 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1368 it != fDataPoints.end(); ++it)
1370 if((*it)->GetCoordinate(dim) < this->fBoundaries.at(dim).first)
1371 this->fBoundaries.at(dim).first = (*it)->GetCoordinate(dim);
1375 if(this->fBoundaries.at(dim).second > 0.8*fMAX)
1377 this->fBoundaries.at(dim).second = fMIN;
1379 for(
typename std::vector<const _DataPoint*>::const_iterator it = fDataPoints.begin();
1380 it != fDataPoints.end(); ++it)
1382 if((*it)->GetCoordinate(dim) > this->fBoundaries.at(dim).second)
1383 this->fBoundaries.at(dim).second = (*it)->GetCoordinate(dim);
1391 template<
class _DataPo
int>
1401 template<
class _DataPo
int>
1411 template<
class _DataPo
int>
1422 template<
class _DataPo
int>
1433 template<
class _DataPo
int>
1443 template<
class _DataPo
int>
1453 template<
class _DataPo
int>
1464 template<
class _DataPo
int>
1475 template<
class _DataPo
int>
1485 template<
class _DataPo
int>
1503 assert(
dynamic_cast<BinNode*
>(pNode));
1514 template<
class _DataPo
int>
1532 assert(
dynamic_cast<BinNode*
>(pNode));
BaseNode *& GetParentPointer()
Bool_t IsLeftChild() const
virtual Bool_t IsHeadNode() const
BaseNode(BaseNode *pParent=0)
virtual BaseNode * Clone()=0
void Print(int iRow=0) const override
virtual const std::vector< tBoundary > & GetBoundaries() const
std::vector< tBoundary > fBoundaries
bin boundaries
BinNode * Clone() override
BinNode(BaseNode *pParent=0)
point_type GetBinCenter() const
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
const BinNode * FindNode(const point_type &rPoint) const override
UInt_t fEntries
number of entries
Bool_t Insert(const point_type &rPoint) override
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
void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const override
void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const override
HeadNode * Clone() override
Bool_t Insert(const point_type &rPoint) override
SplitNode(UInt_t iAxis, Double_t fCutValue, BaseNode &rLeft, BaseNode &rRight, BaseNode *pParent=0)
void Print(Int_t iRow=0) const override
SplitNode * Clone() override
const BinNode * FindNode(const point_type &rPoint) const override
const Cut * GetCut() const
void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const override
void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const override
Bool_t Insert(const point_type &rPoint) override
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)
BinNode * ConvertToBinNode()
TerminalNode(Double_t iBucketSize, BaseNode *pParent=0)
std::vector< constpoint_type * >::const_iterator const_data_it
const std::vector< tBoundary > & GetBoundaries() const override
void Print(int iRow=0) const override
void GetPointsWithinDist(const point_type &rRef, value_type fDist, std::vector< const _DataPoint * > &vFoundPoints) const override
data_it SplitEffectiveEntries()
void GetClosestPoints(const point_type &rRef, UInt_t nPoints, std::vector< std::pair< const _DataPoint *, Double_t > > &vFoundPoints) const override
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)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.