272template <
typename Index,
typename Value>
294template <
typename Index,
typename Value>
346template <
typename Index,
typename Value>
375template <
typename Index,
typename Value>
386 for(
int idim=0; idim<
fNDim; idim++)
delete []
fData[idim];
413template <
typename Index,
typename Value>
457 Int_t nodeStack[128];
458 Int_t npointStack[128];
460 Int_t currentIndex = 0;
466 while (currentIndex>=0){
468 Int_t npoints = npointStack[currentIndex];
473 Int_t crow = rowStack[currentIndex];
474 Int_t cpos = posStack[currentIndex];
475 Int_t cnode = nodeStack[currentIndex];
482 if (restRows<0) restRows =0;
483 for (;nbuckets0>(2<<restRows); restRows++) {}
484 Int_t nfull = 1<<restRows;
485 Int_t nrest = nbuckets0-nfull;
486 Int_t nleft =0, nright =0;
488 if (nrest>(nfull/2)){
490 nright = npoints-nleft;
493 nleft = npoints-nright;
499 Value tempspread, min, max;
505 tempspread = max - min;
506 if (maxspread < tempspread) {
507 maxspread=tempspread;
514 array =
fData[axspread];
516 fAxis[cnode] = axspread;
521 npointStack[currentIndex] = nleft;
522 rowStack[currentIndex] = crow+1;
523 posStack[currentIndex] = cpos;
524 nodeStack[currentIndex] = cnode*2+1;
526 npointStack[currentIndex] = nright;
527 rowStack[currentIndex] = crow+1;
528 posStack[currentIndex] = cpos+nleft;
529 nodeStack[currentIndex] = (cnode*2)+2;
533 Info(
"Build()",
"%s",
Form(
"points %d left %d right %d", npoints, nleft, nright));
534 if (nleft<nright)
Warning(
"Build",
"Problem Left-Right");
535 if (nleft<0 || nright<0)
Warning(
"Build()",
"Problem Negative number");
545template <
typename Index,
typename Value>
550 Error(
"FindNearestNeighbors",
"Working arrays must be allocated by the user!");
554 dist[i]=std::numeric_limits<Value>::max();
565template <
typename Index,
typename Value>
571 if (min > dist[
kNN-1]){
577 Index
f1, l1, f2, l2;
579 for (
Int_t ipoint=
f1; ipoint<=l1; ipoint++){
584 while(ishift<kNN && d>dist[ishift])
612template <
typename Index,
typename Value>
618 dist+=(point[idim]-
fData[idim][ind])*(point[idim]-
fData[idim][ind]);
637template <
typename Index,
typename Value>
647 dist1 = (point[idim/2]-bound[idim])*(point[idim/2]-bound[idim]);
648 dist2 = (point[idim/2]-bound[idim+1])*(point[idim/2]-bound[idim+1]);
650 if (point[idim/2]<bound[idim] || point[idim/2]>bound[idim+1])
651 min+= (dist1>dist2)? dist2 : dist1;
653 max+= (dist1>dist2)? dist1 : dist2;
659 dist1 =
TMath::Abs(point[idim/2]-bound[idim]);
660 dist2 =
TMath::Abs(point[idim/2]-bound[idim+1]);
662 min+= (dist1>dist2)? dist2 : dist1;
664 max+= (dist1>dist2)? dist1 : dist2;
674template <
typename Index,
typename Value>
677 Index stackNode[128], inode;
678 Int_t currentIndex =0;
680 while (currentIndex>=0){
681 inode = stackNode[currentIndex];
687 stackNode[currentIndex]=(inode<<1)+1;
691 stackNode[currentIndex]=(inode+1)<<1;
705template <
typename Index,
typename Value>
707 Int_t stackNode[128];
708 Int_t currentIndex =0;
712 while (currentIndex>=0){
714 Int_t inode = stackNode[currentIndex];
719 printf(
"terminal %d indexP %d\n", inode, indexIP);
723 printf(
"ibucket %d index %d\n", ibucket, indexIP);
727 if (isOK) index = index0;
734 stackNode[currentIndex]=(inode*2)+1;
738 stackNode[currentIndex]=(inode*2)+2;
751template <
typename Index,
typename Value>
761template <
typename Index,
typename Value>
770 if (max<range && max>0) {
773 Index
f1, l1, f2, l2;
776 for (
Int_t ipoint=
f1; ipoint<=l1; ipoint++){
779 for (
Int_t ipoint=f2; ipoint<=l2; ipoint++){
788 Index
f1, l1, f2, l2;
791 for (
Int_t ipoint=
f1; ipoint<=l1; ipoint++){
814template <
typename Index,
typename Value>
818 printf(
"GetPointsIndexes() only for terminal nodes, use GetNodePointsIndexes() instead\n");
843template <
typename Index,
typename Value>
860 Index
f1, l1, f2, l2;
862 while (ileft<firsttermnode)
865 while (iright<firsttermnode)
897template <
typename Index,
typename Value>
920template <
typename Index,
typename Value>
945template <
typename Index,
typename Value>
949 Error(
"SetData",
"The tree has already been built, no updates possible");
965template <
typename Index,
typename Value>
971 for (i=0; i<ntotal; i++){
972 if (
a[index[i]]<min) min =
a[index[i]];
973 if (
a[index[i]]>max) max =
a[index[i]];
982template <
typename Index,
typename Value>
985 Index i, ir, j,
l, mid;
994 if (ir ==
l+1 &&
a[index[ir]]<
a[index[
l]])
995 {temp = index[
l]; index[
l]=index[ir]; index[ir]=temp;}
1000 {temp = index[mid]; index[mid]=index[
l+1]; index[
l+1]=temp;}
1001 if (
a[index[
l]]>
a[index[ir]])
1002 {temp = index[
l]; index[
l]=index[ir]; index[ir]=temp;}
1004 if (
a[index[
l+1]]>
a[index[ir]])
1005 {temp=index[
l+1]; index[
l+1]=index[ir]; index[ir]=temp;}
1007 if (
a[index[
l]]>
a[index[
l+1]])
1008 {temp = index[
l]; index[
l]=index[
l+1]; index[
l+1]=temp;}
1014 do i++;
while (
a[index[i]]<
a[arr]);
1015 do j--;
while (
a[index[j]]>
a[arr]);
1017 {temp=index[i]; index[i]=index[j]; index[j]=temp;}
1019 index[
l+1]=index[j];
1021 if (j>=rk) ir = j-1;
1036template <
typename Index,
typename Value>
1048 Value *tbounds =
nullptr, *cbounds =
nullptr;
1050 for(
int inode=
fNNodes-1; inode>=0; inode--){
1058 for(
int idim=0; idim<
fNDim; idim++) tbounds[idim<<1] = cbounds[idim<<1];
1064 for(
int idim=0; idim<
fNDim; idim++) tbounds[(idim<<1)+1] = cbounds[(idim<<1)+1];
1071template <
typename Index,
typename Value>
1074 Int_t index = (node<<1) + (LEFT ? 1 : 2);
1086 while(pn >= 0 && nvals <
fNDimm){
1088 index = (
fAxis[pn]<<1)+1;
1090 tbounds[index] =
fValue[pn];
1091 flag[index] =
kTRUE;
1095 index =
fAxis[pn]<<1;
1097 tbounds[index] =
fValue[pn];
1098 flag[index] =
kTRUE;
1116template <
typename Index,
typename Value>
1131 for (Index idim=0; idim<
fNDim; idim++){
1132 min[idim]= std::numeric_limits<Value>::max();
1133 max[idim]=-std::numeric_limits<Value>::max();
1138 for (Index ipoint=0; ipoint<npoints; ipoint++){
1139 for (Index idim=0; idim<
fNDim; idim++){
1146 for (Index idim=0; idim<
fNDimm; idim+=2){
1156 for (Index inode=
fNNodes-1; inode>=0; inode--){
1160 for (Index idim=0; idim<
fNDimm; idim+=2){
1175template <
typename Index,
typename Value>
1180 inode = (point[
fAxis[inode]] <
fValue[inode]) ? (inode*2)+1: (inode*2)+2;
1187template <
typename Index,
typename Value>
1198template <
typename Index,
typename Value>
1208template <
typename Index,
typename Value>
1218template <
typename Index,
typename Value>
1234 data[0] = &data0[0];
1235 data[1] = &data0[npoints];
1236 for (
Int_t i=0;i<npoints;i++) {
int Int_t
Signed integer 4 bytes (int).
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
float Float_t
Float 4 bytes (float).
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
TKDTreeIF * TKDTreeTestBuild()
TKDTree< Int_t, Float_t > TKDTreeIF
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Class implementing a kd-tree.
Int_t GetLeft(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
void SetData(Index npoints, Index ndim, UInt_t bsize, Value **data)
Set the data array. See the constructor function comments for details.
Int_t fCrossNode
! cross node - node that begins the last row (with terminal nodes only)
~TKDTree() override
Destructor By default, the original data is not owned by kd-tree and is not deleted with it.
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...
Index * fIndPoints
! array of points indexes
Value * fValue
[fNNodes] nodes cutting value
Value * GetBoundaryExact(const Int_t node)
Get a boundary.
void FindBNodeA(Value *point, Value *delta, Int_t &inode)
find the smallest node covering the full range - start
Value * fRange
[fNDimm] range of data for each dimension
void UpdateRange(Index inode, Value *point, Value range, std::vector< Index > &res)
Internal recursive function with the implementation of range searches.
Index FindNode(const Value *point) const
returns the index of the terminal node to which point belongs (index in the fAxis,...
Int_t fNNodes
size of node array
Value ** fData
! data points
Value KOrdStat(Index ntotal, Value *a, Index k, Index *index) const
copy of the TMath::KOrdStat because I need an Index work array
Value * GetBoundariesExact()
Get the boundaries.
UChar_t * fAxis
[fNNodes] nodes cutting axis
Int_t fDataOwner
! 0 - not owner, 2 - owner of the pointer array, 1 - owner of the whole 2-d array
Index fNDim
number of dimensions
void MakeBoundariesExact()
Build boundaries for each node.
void CookBoundaries(const Int_t node, Bool_t left)
define index of this terminal node
void MakeBoundaries(Value *range=nullptr)
Build boundaries for each node.
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 GetRight(Int_t inode) const
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 ...
Index fBucketSize
size of the terminal nodes
Index * GetPointsIndexes(Int_t node) const
return the indices of the points in that terminal node for all the nodes except last,...
void Spread(Index ntotal, Value *a, Index *index, Value &min, Value &max) const
Calculate spread of the array a.
void Build()
Build the kd-tree.
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.
TKDTree()
Default constructor. Nothing is built.
Int_t fRowT0
! smallest terminal row - first row that contains terminal nodes
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.
Value * fBoundaries
! nodes boundaries
Bool_t IsTerminal(Index inode) const
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...
Value * GetBoundaries()
Get the boundaries.
Index fNDimm
dummy 2*fNDim
Value * GetBoundary(const Int_t node)
Get a boundary.
Int_t fTotalNodes
total number of nodes (fNNodes + terminal nodes)
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,...
Index fNPoints
number of multidimensional points
kNN::Event describes point in input variable vector-space, with additional functionality like distanc...
virtual void Clear(Option_t *="")
TObject()
TObject constructor.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
static uint64_t sum(uint64_t i)