294 template <
typename Index,
typename Value>
346 template <
typename Index,
typename Value>
375 template <
typename Index,
typename Value>
386 for(
int idim=0; idim<
fNDim; idim++)
delete []
fData[idim];
413 template <
typename Index,
typename Value>
457 Int_t nodeStack[128];
458 Int_t npointStack[128];
460 Int_t currentIndex = 0;
467 Int_t nbucketsall =0;
468 while (currentIndex>=0){
471 Int_t npoints = npointStack[currentIndex];
472 if (npoints<=fBucketSize) {
478 Int_t crow = rowStack[currentIndex];
479 Int_t cpos = posStack[currentIndex];
480 Int_t cnode = nodeStack[currentIndex];
485 if (npoints%fBucketSize) nbuckets0++;
487 if (restRows<0) restRows =0;
488 for (;nbuckets0>(2<<restRows); restRows++) {}
489 Int_t nfull = 1<<restRows;
490 Int_t nrest = nbuckets0-nfull;
491 Int_t nleft =0, nright =0;
493 if (nrest>(nfull/2)){
495 nright = npoints-nleft;
497 nright = nfull*fBucketSize/2;
498 nleft = npoints-nright;
510 tempspread = max -
min;
511 if (maxspread < tempspread) {
512 maxspread=tempspread;
519 array =
fData[axspread];
521 fAxis[cnode] = axspread;
526 npointStack[currentIndex] = nleft;
527 rowStack[currentIndex] = crow+1;
528 posStack[currentIndex] = cpos;
529 nodeStack[currentIndex] = cnode*2+1;
531 npointStack[currentIndex] = nright;
532 rowStack[currentIndex] = crow+1;
533 posStack[currentIndex] = cpos+nleft;
534 nodeStack[currentIndex] = (cnode*2)+2;
538 Info(
"Build()",
"%s",
Form(
"points %d left %d right %d", npoints, nleft, nright));
539 if (nleft<nright)
Warning(
"Build",
"Problem Left-Right");
540 if (nleft<0 || nright<0)
Warning(
"Build()",
"Problem Negative number");
550 template <
typename Index,
typename Value>
555 Error(
"FindNearestNeighbors",
"Working arrays must be allocated by the user!");
558 for (
Int_t i=0; i<kNN; i++){
570 template <
typename Index,
typename Value>
576 if (min > dist[kNN-1]){
584 for (
Int_t ipoint=f1; ipoint<=l1; ipoint++){
589 while(ishift<kNN && d>dist[ishift])
593 for (
Int_t i=kNN-1; i>ishift; i--){
617 template <
typename Index,
typename Value>
623 dist+=(point[idim]-
fData[idim][ind])*(point[idim]-
fData[idim][ind]);
642 template <
typename Index,
typename Value>
652 dist1 = (point[idim/2]-bound[idim])*(point[idim/2]-bound[idim]);
653 dist2 = (point[idim/2]-bound[idim+1])*(point[idim/2]-bound[idim+1]);
655 if (point[idim/2]<bound[idim] || point[idim/2]>bound[idim+1])
656 min+= (dist1>dist2)? dist2 : dist1;
658 max+= (dist1>dist2)? dist1 : dist2;
664 dist1 =
TMath::Abs(point[idim/2]-bound[idim]);
665 dist2 =
TMath::Abs(point[idim/2]-bound[idim+1]);
667 min+= (dist1>dist2)? dist2 : dist1;
669 max+= (dist1>dist2)? dist1 : dist2;
679 template <
typename Index,
typename Value>
682 Index stackNode[128], inode;
683 Int_t currentIndex =0;
685 while (currentIndex>=0){
686 inode = stackNode[currentIndex];
692 stackNode[currentIndex]=(inode<<1)+1;
696 stackNode[currentIndex]=(inode+1)<<1;
710 template <
typename Index,
typename Value>
712 Int_t stackNode[128];
713 Int_t currentIndex =0;
717 while (currentIndex>=0){
719 Int_t inode = stackNode[currentIndex];
724 printf(
"terminal %d indexP %d\n", inode, indexIP);
728 printf(
"ibucket %d index %d\n", ibucket, indexIP);
732 if (isOK) index = index0;
739 stackNode[currentIndex]=(inode*2)+1;
743 stackNode[currentIndex]=(inode*2)+2;
756 template <
typename Index,
typename Value>
766 template <
typename Index,
typename Value>
775 if (max<range && max>0) {
781 for (
Int_t ipoint=f1; ipoint<=l1; ipoint++){
784 for (
Int_t ipoint=f2; ipoint<=l2; ipoint++){
796 for (
Int_t ipoint=f1; ipoint<=l1; ipoint++){
819 template <
typename Index,
typename Value>
823 printf(
"GetPointsIndexes() only for terminal nodes, use GetNodePointsIndexes() instead\n");
848 template <
typename Index,
typename Value>
867 while (ileft<firsttermnode)
870 while (iright<firsttermnode)
902 template <
typename Index,
typename Value>
925 template <
typename Index,
typename Value>
950 template <
typename Index,
typename Value>
954 Error(
"SetData",
"The tree has already been built, no updates possible");
970 template <
typename Index,
typename Value>
976 for (i=0; i<ntotal; i++){
977 if (a[index[i]]<min) min = a[index[i]];
978 if (a[index[i]]>max) max = a[index[i]];
987 template <
typename Index,
typename Value>
999 if (ir == l+1 && a[index[ir]]<a[index[l]])
1000 {temp = index[
l]; index[
l]=index[ir]; index[ir]=temp;}
1001 Value tmp = a[index[rk]];
1005 {temp = index[mid]; index[mid]=index[l+1]; index[l+1]=temp;}
1006 if (a[index[l]]>a[index[ir]])
1007 {temp = index[
l]; index[
l]=index[ir]; index[ir]=temp;}
1009 if (a[index[l+1]]>a[index[ir]])
1010 {temp=index[l+1]; index[l+1]=index[ir]; index[ir]=temp;}
1012 if (a[index[l]]>a[index[l+1]])
1013 {temp = index[
l]; index[
l]=index[l+1]; index[l+1]=temp;}
1019 do i++;
while (a[index[i]]<a[arr]);
1020 do j--;
while (a[index[j]]>a[arr]);
1022 {temp=index[i]; index[i]=index[j]; index[j]=temp;}
1024 index[l+1]=index[j];
1026 if (j>=rk) ir = j-1;
1041 template <
typename Index,
typename Value>
1053 Value *tbounds = 0x0, *cbounds = 0x0;
1055 for(
int inode=
fNNodes-1; inode>=0; inode--){
1063 for(
int idim=0; idim<
fNDim; idim++) tbounds[idim<<1] = cbounds[idim<<1];
1069 for(
int idim=0; idim<
fNDim; idim++) tbounds[(idim<<1)+1] = cbounds[(idim<<1)+1];
1076 template <
typename Index,
typename Value>
1079 Int_t index = (node<<1) + (LEFT ? 1 : 2);
1091 while(pn >= 0 && nvals <
fNDimm){
1093 index = (
fAxis[pn]<<1)+1;
1095 tbounds[index] =
fValue[pn];
1096 flag[index] =
kTRUE;
1100 index =
fAxis[pn]<<1;
1102 tbounds[index] =
fValue[pn];
1103 flag[index] =
kTRUE;
1121 template <
typename Index,
typename Value>
1143 for (
Index ipoint=0; ipoint<npoints; ipoint++){
1145 if (
fData[idim][points[ipoint]]<min[idim])
1146 min[idim]=
fData[idim][points[ipoint]];
1147 if (
fData[idim][points[ipoint]]>max[idim])
1148 max[idim]=
fData[idim][points[ipoint]];
1180 template <
typename Index,
typename Value>
1185 inode = (point[
fAxis[inode]] <
fValue[inode]) ? (inode*2)+1: (inode*2)+2;
1192 template <
typename Index,
typename Value>
1203 template <
typename Index,
typename Value>
1213 template <
typename Index,
typename Value>
1223 template <
typename Index,
typename Value>
1239 data[0] = &data0[0];
1240 data[1] = &data0[npoints];
1241 for (
Int_t i=0;i<npoints;i++) {
virtual void Clear(Option_t *="")
double dist(Rotation3D const &r1, Rotation3D const &r2)
void Spread(Index ntotal, Value *a, Index *index, Value &min, Value &max) const
Calculate spread of the array a.
Int_t fOffset
cross node - node that begins the last row (with terminal nodes only)
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
void SetData(Index npoints, Index ndim, UInt_t bsize, Value **data)
Set the data array. See the constructor function comments for details.
Index FindNode(const Value *point) const
returns the index of the terminal node to which point belongs (index in the fAxis, fValue, etc arrays) returns -1 in case of failure
Index * GetPointsIndexes(Int_t node) const
return the indices of the points in that terminal node for all the nodes except last, the size is fBucketSize for the last node it's fOffsetfBucketSize
TKDTree< Int_t, Float_t > TKDTreeIF
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
Bool_t IsTerminal(Index inode) const
void FindBNodeA(Value *point, Value *delta, Int_t &inode)
find the smallest node covering the full range - start
void FindInRange(Value *point, Value range, std::vector< Index > &res)
Find all points in the sphere of a given radius "range" around the given point 1st argument - the poi...
Short_t Min(Short_t a, Short_t b)
void MakeBoundariesExact()
Build boundaries for each node.
Index GetNPointsNode(Int_t node) const
Get number of points in this node for all the terminal nodes except last, the size is fBucketSize for...
Double_t Distance(const Value *point, Index ind, Int_t type=2) const
Find the distance between point of the first argument and the point at index value ind Type argument ...
void Build()
Build the kd-tree.
#define templateClassImp(name)
Int_t GetRight(Int_t inode) const
void FindPoint(Value *point, Index &index, Int_t &iter)
find the index of point works only if we keep fData pointers
TKDTree()
Default constructor. Nothing is built.
TKDTreeIF * TKDTreeTestBuild(const Int_t npoints, const Int_t bsize)
Example function to.
Index * fIndPoints
nodes boundaries
Class implementing a kd-tree.
void UpdateNearestNeighbors(Index inode, const Value *point, Int_t kNN, Index *ind, Value *dist)
Update the nearest neighbors values by examining the node inode.
Int_t fRowT0
array of points indexes
~TKDTree()
Destructor By default, the original data is not owned by kd-tree and is not deleted with it...
Value KOrdStat(Index ntotal, Value *a, Index k, Index *index) const
copy of the TMath::KOrdStat because I need an Index work array
Int_t GetLeft(Int_t inode) const
void GetNodePointsIndexes(Int_t node, Int_t &first1, Int_t &last1, Int_t &first2, Int_t &last2) const
Return the indices of points in that node Indices are returned as the first and last value of the par...
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
char * Form(const char *fmt,...)
void FindNearestNeighbors(const Value *point, Int_t k, Index *ind, Value *dist)
Find kNN nearest neighbors to the point in the first argument Returns 1 on success, 0 on failure Arrays ind and dist are provided by the user and are assumed to be at least kNN elements long.
void CookBoundaries(const Int_t node, Bool_t left)
define index of this terminal node
R__EXTERN TRandom * gRandom
void DistanceToNode(const Value *point, Index inode, Value &min, Value &max, Int_t type=2)
Find the minimal and maximal distance from a given point to a given node.
void MakeBoundaries(Value *range=0x0)
Build boundaries for each node.
RooCmdArg Index(RooCategory &icat)
Value * GetBoundariesExact()
Get the boundaries.
Int_t fCrossNode
smallest terminal row - first row that contains terminal nodes
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Mother of all ROOT objects.
double f2(const double *x)
void UpdateRange(Index inode, Value *point, Value range, std::vector< Index > &res)
Internal recursive function with the implementation of range searches.
Int_t fNNodes
0 - not owner, 2 - owner of the pointer array, 1 - owner of the whole 2-d array
Short_t Max(Short_t a, Short_t b)
Value * GetBoundaries()
Get the boundaries.
Double_t Sqrt(Double_t x)
Value * GetBoundaryExact(const Int_t node)
Get a boundary.
Value * fBoundaries
data points
Value * GetBoundary(const Int_t node)
Get a boundary.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.