Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TKDTree< Index, Value > Class Template Reference

template<typename Index, typename Value>
class TKDTree< Index, Value >

Class implementing a kd-tree.

Contents:

  1. What is kd-tree
  2. How to cosntruct kdtree - Pseudo code
  3. Using TKDTree a. Creating the kd-tree and setting the data b. Navigating the kd-tree
  4. TKDTree implementation - technical details a. The order of nodes in internal arrays b. Division algorithm c. The order of nodes in boundary related arrays

1. What is kdtree ? ( [http://en.wikipedia.org/wiki/Kd-tree] )

In computer science, a kd-tree (short for k-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. kd-trees are a useful data structure for several applications, such as searches involving a multidimensional search key (e.g. range searches and nearest neighbour searches). kd-trees are a special case of BSP trees.

A kd-tree uses only splitting planes that are perpendicular to one of the coordinate system axes. This differs from BSP trees, in which arbitrary splitting planes can be used. In addition, in the typical definition every node of a kd-tree, from the root to the leaves, stores a point. This differs from BSP trees, in which leaves are typically the only nodes that contain points (or other geometric primitives). As a consequence, each splitting plane must go through one of the points in the kd-tree. kd-trees are a variant that store data only in leaf nodes.

2. Constructing a classical kd-tree ( Pseudo code)

Since there are many possible ways to choose axis-aligned splitting planes, there are many different ways to construct kd-trees. The canonical method of kd-tree construction has the following constraints:

As one moves down the tree, one cycles through the axes used to select the splitting planes. (For example, the root would have an x-aligned plane, the root's children would both have y-aligned planes, the root's grandchildren would all have z-aligned planes, and so on.) At each step, the point selected to create the splitting plane is the median of the points being put into the kd-tree, with respect to their coordinates in the axis being used. (Note the assumption that we feed the entire set of points into the algorithm up-front.)

This method leads to a balanced kd-tree, in which each leaf node is about the same distance from the root. However, balanced trees are not necessarily optimal for all applications. The following pseudo-code illustrates this canonical construction procedure (NOTE, that the procedure used by the TKDTree class is a bit different, the following pseudo-code is given as a simple illustration of the concept):

function kdtree (list of points pointList, int depth)
{
if pointList is empty
return nil;
else
{
// Select axis based on depth so that axis cycles through all valid values
var int axis := depth mod k;
// Sort point list and choose median as pivot element
select median from pointList;
// Create node and construct subtrees
var tree_node node;
node.location := median;
node.leftChild := kdtree(points in pointList before median, depth+1);
node.rightChild := kdtree(points in pointList after median, depth+1);
return node;
}
}
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points

Our construction method is optimized to save memory, and differs a bit from the constraints above. In particular, the division axis is chosen as the one with the biggest spread, and the point to create the splitting plane is chosen so, that one of the two subtrees contains exactly 2^k terminal nodes and is a perfectly balanced binary tree, and, while at the same time, trying to keep the number of terminal nodes in the 2 subtrees as close as possible. The following section gives more details about our implementation.

3. Using TKDTree

3a. Creating the tree and setting the data

The interface of the TKDTree, that allows to set input data, has been developed to simplify using it together with TTree::Draw() functions. That's why the data has to be provided column-wise. For example:

{
TTree *datatree = ...
...
datatree->Draw("x:y:z", "selection", "goff");
//now make a kd-tree on the drawn variables
TKDTreeID *kdtree = new TKDTreeID(npoints, 3, 1);
kdtree->SetData(0, datatree->GetV1());
kdtree->SetData(1, datatree->GetV2());
kdtree->SetData(2, datatree->GetV3());
kdtree->Build();
}
NOTE, that this implementation of kd-tree doesn't support adding new points after the tree has been built
Of course, it's not necessary to use TTree::Draw(). What is important, is to have data columnwise.
An example with regular arrays:
{
Int_t npoints = 100000;
Int_t ndim = 3;
Int_t bsize = 1;
Double_t xmin = -0.5;
Double_t xmax = 0.5;
Double_t *data0 = new Double_t[npoints];
Double_t *data1 = new Double_t[npoints];
Double_t *data2 = new Double_t[npoints];
Double_t *y = new Double_t[npoints];
for (Int_t i=0; i<npoints; i++){
data0[i]=gRandom->Uniform(xmin, xmax);
data1[i]=gRandom->Uniform(xmin, xmax);
data2[i]=gRandom->Uniform(xmin, xmax);
}
TKDTreeID *kdtree = new TKDTreeID(npoints, ndim, bsize);
kdtree->SetData(0, data0);
kdtree->SetData(1, data1);
kdtree->SetData(2, data2);
kdtree->Build();
}
int Int_t
Definition RtypesCore.h:45
double Double_t
Definition RtypesCore.h:59
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
float xmin
float xmax
TKDTree< Int_t, Double_t > TKDTreeID
Definition TKDTree.h:104
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
Class implementing a kd-tree.
Definition TKDTree.h:10
void SetData(Index npoints, Index ndim, UInt_t bsize, Value **data)
Set the data array. See the constructor function comments for details.
Definition TKDTree.cxx:918
void Build()
Build the kd-tree.
Definition TKDTree.cxx:411
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition TRandom.cxx:672
A TTree represents a columnar dataset.
Definition TTree.h:79
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:431
virtual Double_t * GetV3()
Definition TTree.h:540
virtual Double_t * GetV1()
Definition TTree.h:536
virtual Double_t * GetV2()
Definition TTree.h:538
Double_t y[n]
Definition legend1.C:17
Definition tree.py:1
By default, the kd-tree doesn't own the data and doesn't delete it with itself. If you want the
data to be deleted together with the kd-tree, call TKDTree::SetOwner(kTRUE).

Most functions of the kd-tree don't require the original data to be present after the tree
has been built. Check the functions documentation for more details.

3b. Navigating the kd-tree

Nodes of the tree are indexed top to bottom, left to right. The root node has index 0. Functions
TKDTree::GetLeft(Index inode), TKDTree::GetRight(Index inode) and TKDTree::GetParent(Index inode)
allow to find the children and the parent of a given node.

For a given node, one can find the indexes of the original points, contained in this node,
by calling the GetNodePointsIndexes(Index inode) function. Additionally, for terminal nodes,
there is a function GetPointsIndexes(Index inode) that returns a pointer to the relevant
part of the index array. To find the number of point in the node
(not only terminal), call TKDTree::GetNpointsNode(Index inode).

4. TKDtree implementation details - internal information, not needed to use the kd-tree.

4a. Order of nodes in the node information arrays:

TKDtree is optimized to minimize memory consumption. Nodes of the TKDTree do not store pointers to the left and right children or to the parent node, but instead there are several 1-d arrays of size fNNodes with information about the nodes. The order of the nodes information in the arrays is described below. It's important to understand it, if one's class needs to store some kind of additional information on the per node basis, for example, the fit function parameters.

  • Drawback: Insertion to the TKDtree is not supported.
  • Advantage: Random access is supported

As noted above, the construction of the kd-tree involves choosing the axis and the point on that axis to divide the remaining points approximately in half. The exact algorithm for choosing the division point is described in the next section. The sequence of divisions is recorded in the following arrays:

fAxis[fNNodes] - Division axis (0,1,2,3 ...)
fValue[fNNodes] - Division value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Value * fValue
[fNNodes] nodes cutting value
Definition TKDTree.h:85
Int_t fNNodes
size of node array
Definition TKDTree.h:78
UChar_t * fAxis
[fNNodes] nodes cutting axis
Definition TKDTree.h:84

Given the index of a node in those arrays, it's easy to find the indices, corresponding to children nodes or the parent node: Suppose, the parent node is stored under the index inode. Then:

  • Left child index = inode*2+1
  • Right child index = (inode+1)*2

Suppose, that the child node is stored under the index inode. Then:

  • Parent index = inode/2

Number of division nodes and number of terminals : fNNodes = (fNPoints/fBucketSize)

The nodes are filled always from left side to the right side: Let inode be the index of a node, and irow - the index of a row The TKDTree looks the following way: Ideal case:

Number of _terminal_ nodes = 2^N, N=3
INode
irow 0 0 - 1 inode
irow 1 1 2 - 2 inodes
irow 2 3 4 5 6 - 4 inodes
irow 3 7 8 9 10 11 12 13 14 - 8 inodes
#define N

Non ideal case:

Number of _terminal_ nodes = 2^N+k, N=3 k=1
INode
irow 0 0 - 1 inode
irow 1 1 2 - 2 inodes
irow 2 3 4 5 6 - 3 inodes
irow 3 7 8 9 10 11 12 13 14 - 8 inodes
irow 4 15 16 - 2 inodes

4b. The division algorithm:

As described above, the kd-tree is built by repeatingly dividing the given set of points into 2 smaller sets. The cut is made on the axis with the biggest spread, and the value on the axis, on which the cut is performed, is chosen based on the following formula: Suppose, we want to divide n nodes into 2 groups, left and right. Then the left and right will have the following number of nodes:

n=2^k+rest
Left = 2^k-1 + ((rest>2^k-2) ? 2^k-2 : rest)
Right = 2^k-1 + ((rest>2^k-2) ? rest-2^k-2 : 0)
const Int_t n
Definition legend1.C:16

For example, let n_nodes=67. Then, the closest 2^k=64, 2^k-1=32, 2^k-2=16. Left node gets 32+3=35 sub-nodes, and the right node gets 32 sub-nodes

The division process continues until all the nodes contain not more than a predefined number of points.

4c. The order of nodes in boundary-related arrays

Some kd-tree based algorithms need to know the boundaries of each node. This information can be computed by calling the TKDTree::MakeBoundaries() function. It fills the following arrays:

  • fRange : array containing the boundaries of the domain: | 1st dimension (min + max) | 2nd dimension (min + max) | ... fBoundaries : nodes boundaries | 1st node {1st dim * 2 elements | 2nd dim * 2 elements | ...} | 2nd node {...} | ...

The nodes are arranged in the order described in section 3a.

  • Note: the storage of the TKDTree in a file which include also the contained data is not supported. One must store the data separately in a file (e.g. using a TTree) and then re-creating the TKDTree from the data, after having read them from the file

Definition at line 9 of file TKDTree.h.

Public Member Functions

 TKDTree ()
 Default constructor. Nothing is built.
 
 TKDTree (Index npoints, Index ndim, UInt_t bsize)
 
 TKDTree (Index npoints, Index ndim, UInt_t bsize, Value **data)
 Create a kd-tree from the provided data array.
 
 ~TKDTree () override
 Destructor By default, the original data is not owned by kd-tree and is not deleted with it.
 
void Build ()
 Build the kd-tree.
 
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 specifies the metric: type=2 - L2 metric, type=1 - L1 metric.
 
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 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 point 2nd argument - radius of the shere 3rd argument - a vector, in which the results will be returned.
 
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.
 
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
 
void FindPoint (Value *point, Index &index, Int_t &iter)
 find the index of point works only if we keep fData pointers
 
ValueGetBoundaries ()
 Get the boundaries.
 
ValueGetBoundariesExact ()
 Get the boundaries.
 
ValueGetBoundary (const Int_t node)
 Get a boundary.
 
ValueGetBoundaryExact (const Int_t node)
 Get a boundary.
 
Index GetBucketSize ()
 
Int_t GetCrossNode ()
 smallest terminal row
 
Index * GetIndPoints ()
 offset in fIndPoints
 
Int_t GetLeft (Int_t inode) const
 
Index GetNDim ()
 
Int_t GetNNodes () const
 
UChar_t GetNodeAxis (Int_t id) 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 part of indices array, that belong to this node Sometimes points are in 2 intervals, then the first and last value for the second one are returned in third and fourth parameter, otherwise first2 is set to 0 and last2 is set to -1 To iterate over all the points of the node #inode, one can do, for example: Index *indices = kdtree->GetPointsIndexes(); Int_t first1, last1, first2, last2; kdtree->GetPointsIndexes(inode, first1, last1, first2, last2); for (Int_t ipoint=first1; ipoint<=last1; ipoint++){ point = indices[ipoint]; //do something with point; } for (Int_t ipoint=first2; ipoint<=last2; ipoint++){ point = indices[ipoint]; //do something with point; }.
 
Value GetNodeValue (Int_t id) const
 
Index GetNPoints ()
 
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 the last node it's fOffsetfBucketSize, or if fOffsetfBucketSize==0, it's also fBucketSize.
 
Int_t GetOffset ()
 cross node
 
Int_t GetParent (Int_t inode) const
 
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
 
Int_t GetRight (Int_t inode) const
 
Int_t GetRowT0 ()
 
Int_t GetTotalNodes () const
 
TClassIsA () const override
 
Int_t IsOwner ()
 
Bool_t IsTerminal (Index inode) const
 
Value KOrdStat (Index ntotal, Value *a, Index k, Index *index) const
 copy of the TMath::KOrdStat because I need an Index work array
 
void MakeBoundaries (Value *range=nullptr)
 Build boundaries for each node.
 
void MakeBoundariesExact ()
 Build boundaries for each node.
 
Int_t SetData (Index idim, Value *data)
 Set the coordinate #ndim of all points (the column #ndim of the data matrix) After setting all the data columns, proceed by calling Build() function Note, that calling this function after Build() is not possible Note also, that no checks on the array sizes is performed anywhere.
 
void SetData (Index npoints, Index ndim, UInt_t bsize, Value **data)
 Set the data array. See the constructor function comments for details.
 
void SetOwner (Int_t owner)
 
void Spread (Index ntotal, Value *a, Index *index, Value &min, Value &max) const
 Calculate spread of the array a.
 
void Streamer (TBuffer &) override
 Stream an object of class TObject.
 
void StreamerNVirtual (TBuffer &ClassDef_StreamerNVirtual_b)
 
- Public Member Functions inherited from TObject
 TObject ()
 TObject constructor.
 
 TObject (const TObject &object)
 TObject copy ctor.
 
virtual ~TObject ()
 TObject destructor.
 
void AbstractMethod (const char *method) const
 Use this method to implement an "abstract" method that you don't want to leave purely abstract.
 
virtual void AppendPad (Option_t *option="")
 Append graphics object to current pad.
 
virtual void Browse (TBrowser *b)
 Browse object. May be overridden for another default action.
 
ULong_t CheckedHash ()
 Check and record whether this class has a consistent Hash/RecursiveRemove setup (*) and then return the regular Hash value for this object.
 
virtual const char * ClassName () const
 Returns name of class to which the object belongs.
 
virtual void Clear (Option_t *="")
 
virtual TObjectClone (const char *newname="") const
 Make a clone of an object using the Streamer facility.
 
virtual Int_t Compare (const TObject *obj) const
 Compare abstract method.
 
virtual void Copy (TObject &object) const
 Copy this to obj.
 
virtual void Delete (Option_t *option="")
 Delete this object.
 
virtual Int_t DistancetoPrimitive (Int_t px, Int_t py)
 Computes distance from point (px,py) to the object.
 
virtual void Draw (Option_t *option="")
 Default Draw method for all objects.
 
virtual void DrawClass () const
 Draw class inheritance tree of the class to which this object belongs.
 
virtual TObjectDrawClone (Option_t *option="") const
 Draw a clone of this object in the current selected pad with: gROOT->SetSelectedPad(c1).
 
virtual void Dump () const
 Dump contents of object on stdout.
 
virtual void Error (const char *method, const char *msgfmt,...) const
 Issue error message.
 
virtual void Execute (const char *method, const char *params, Int_t *error=nullptr)
 Execute method on this object with the given parameter string, e.g.
 
virtual void Execute (TMethod *method, TObjArray *params, Int_t *error=nullptr)
 Execute method on this object with parameters stored in the TObjArray.
 
virtual void ExecuteEvent (Int_t event, Int_t px, Int_t py)
 Execute action corresponding to an event at (px,py).
 
virtual void Fatal (const char *method, const char *msgfmt,...) const
 Issue fatal error message.
 
virtual TObjectFindObject (const char *name) const
 Must be redefined in derived classes.
 
virtual TObjectFindObject (const TObject *obj) const
 Must be redefined in derived classes.
 
virtual Option_tGetDrawOption () const
 Get option used by the graphics system to draw this object.
 
virtual const char * GetIconName () const
 Returns mime type name of object.
 
virtual const char * GetName () const
 Returns name of object.
 
virtual char * GetObjectInfo (Int_t px, Int_t py) const
 Returns string containing info about the object at position (px,py).
 
virtual Option_tGetOption () const
 
virtual const char * GetTitle () const
 Returns title of object.
 
virtual UInt_t GetUniqueID () const
 Return the unique object id.
 
virtual Bool_t HandleTimer (TTimer *timer)
 Execute action in response of a timer timing out.
 
virtual ULong_t Hash () const
 Return hash value for this object.
 
Bool_t HasInconsistentHash () const
 Return true is the type of this object is known to have an inconsistent setup for Hash and RecursiveRemove (i.e.
 
virtual void Info (const char *method, const char *msgfmt,...) const
 Issue info message.
 
virtual Bool_t InheritsFrom (const char *classname) const
 Returns kTRUE if object inherits from class "classname".
 
virtual Bool_t InheritsFrom (const TClass *cl) const
 Returns kTRUE if object inherits from TClass cl.
 
virtual void Inspect () const
 Dump contents of this object in a graphics canvas.
 
void InvertBit (UInt_t f)
 
Bool_t IsDestructed () const
 IsDestructed.
 
virtual Bool_t IsEqual (const TObject *obj) const
 Default equal comparison (objects are equal if they have the same address in memory).
 
virtual Bool_t IsFolder () const
 Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
 
R__ALWAYS_INLINE Bool_t IsOnHeap () const
 
virtual Bool_t IsSortable () const
 
R__ALWAYS_INLINE Bool_t IsZombie () const
 
virtual void ls (Option_t *option="") const
 The ls function lists the contents of a class on stdout.
 
void MayNotUse (const char *method) const
 Use this method to signal that a method (defined in a base class) may not be called in a derived class (in principle against good design since a child class should not provide less functionality than its parent, however, sometimes it is necessary).
 
virtual Bool_t Notify ()
 This method must be overridden to handle object notification (the base implementation is no-op).
 
void Obsolete (const char *method, const char *asOfVers, const char *removedFromVers) const
 Use this method to declare a method obsolete.
 
void operator delete (void *ptr)
 Operator delete.
 
void operator delete (void *ptr, void *vp)
 Only called by placement new when throwing an exception.
 
void operator delete[] (void *ptr)
 Operator delete [].
 
void operator delete[] (void *ptr, void *vp)
 Only called by placement new[] when throwing an exception.
 
void * operator new (size_t sz)
 
void * operator new (size_t sz, void *vp)
 
void * operator new[] (size_t sz)
 
void * operator new[] (size_t sz, void *vp)
 
TObjectoperator= (const TObject &rhs)
 TObject assignment operator.
 
virtual void Paint (Option_t *option="")
 This method must be overridden if a class wants to paint itself.
 
virtual void Pop ()
 Pop on object drawn in a pad to the top of the display list.
 
virtual void Print (Option_t *option="") const
 This method must be overridden when a class wants to print itself.
 
virtual Int_t Read (const char *name)
 Read contents of object with specified name from the current directory.
 
virtual void RecursiveRemove (TObject *obj)
 Recursively remove this object from a list.
 
void ResetBit (UInt_t f)
 
virtual void SaveAs (const char *filename="", Option_t *option="") const
 Save this object in the file specified by filename.
 
virtual void SavePrimitive (std::ostream &out, Option_t *option="")
 Save a primitive as a C++ statement(s) on output stream "out".
 
void SetBit (UInt_t f)
 
void SetBit (UInt_t f, Bool_t set)
 Set or unset the user status bits as specified in f.
 
virtual void SetDrawOption (Option_t *option="")
 Set drawing option for object.
 
virtual void SetUniqueID (UInt_t uid)
 Set the unique object id.
 
void StreamerNVirtual (TBuffer &ClassDef_StreamerNVirtual_b)
 
virtual void SysError (const char *method, const char *msgfmt,...) const
 Issue system error message.
 
R__ALWAYS_INLINE Bool_t TestBit (UInt_t f) const
 
Int_t TestBits (UInt_t f) const
 
virtual void UseCurrentStyle ()
 Set current style settings in this object This function is called when either TCanvas::UseCurrentStyle or TROOT::ForceStyle have been invoked.
 
virtual void Warning (const char *method, const char *msgfmt,...) const
 Issue warning message.
 
virtual Int_t Write (const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
 Write this object to the current directory.
 
virtual Int_t Write (const char *name=nullptr, Int_t option=0, Int_t bufsize=0) const
 Write this object to the current directory.
 

Static Public Member Functions

static TClassClass ()
 
static const char * Class_Name ()
 
static constexpr Version_t Class_Version ()
 
static const char * DeclFileName ()
 
- Static Public Member Functions inherited from TObject
static TClassClass ()
 
static const char * Class_Name ()
 
static constexpr Version_t Class_Version ()
 
static const char * DeclFileName ()
 
static Longptr_t GetDtorOnly ()
 Return destructor only flag.
 
static Bool_t GetObjectStat ()
 Get status of object stat flag.
 
static void SetDtorOnly (void *obj)
 Set destructor only flag.
 
static void SetObjectStat (Bool_t stat)
 Turn on/off tracking of objects in the TObjectTable.
 

Protected Attributes

UChar_tfAxis
 [fNNodes] nodes cutting axis
 
ValuefBoundaries
 ! nodes boundaries
 
Index fBucketSize
 size of the terminal nodes
 
Int_t fCrossNode
 ! cross node - node that begins the last row (with terminal nodes only)
 
Value ** fData
 ! data points
 
Int_t fDataOwner
 ! 0 - not owner, 2 - owner of the pointer array, 1 - owner of the whole 2-d array
 
Index * fIndPoints
 ! array of points indexes
 
Index fNDim
 number of dimensions
 
Index fNDimm
 dummy 2*fNDim
 
Int_t fNNodes
 size of node array
 
Index fNPoints
 number of multidimensional points
 
Int_t fOffset
 ! offset in fIndPoints - if there are 2 rows, that contain terminal nodes fOffset returns the index in the fIndPoints array of the first point that belongs to the first node on the second row.
 
ValuefRange
 [fNDimm] range of data for each dimension
 
Int_t fRowT0
 ! smallest terminal row - first row that contains terminal nodes
 
Int_t fTotalNodes
 total number of nodes (fNNodes + terminal nodes)
 
ValuefValue
 [fNNodes] nodes cutting value
 

Private Member Functions

 TKDTree (const TKDTree &)
 
void CookBoundaries (const Int_t node, Bool_t left)
 define index of this terminal node
 
TKDTree< Index, Value > & operator= (const TKDTree< Index, Value > &)
 
void UpdateNearestNeighbors (Index inode, const Value *point, Int_t kNN, Index *ind, Value *dist)
 Update the nearest neighbors values by examining the node inode.
 
void UpdateRange (Index inode, Value *point, Value range, std::vector< Index > &res)
 Internal recursive function with the implementation of range searches.
 

Additional Inherited Members

- Public Types inherited from TObject
enum  {
  kIsOnHeap = 0x01000000 , kNotDeleted = 0x02000000 , kZombie = 0x04000000 , kInconsistent = 0x08000000 ,
  kBitMask = 0x00ffffff
}
 
enum  { kSingleKey = (1ULL << ( 0 )) , kOverwrite = (1ULL << ( 1 )) , kWriteDelete = (1ULL << ( 2 )) }
 
enum  EDeprecatedStatusBits { kObjInCanvas = (1ULL << ( 3 )) }
 
enum  EStatusBits {
  kCanDelete = (1ULL << ( 0 )) , kMustCleanup = (1ULL << ( 3 )) , kIsReferenced = (1ULL << ( 4 )) , kHasUUID = (1ULL << ( 5 )) ,
  kCannotPick = (1ULL << ( 6 )) , kNoContextMenu = (1ULL << ( 8 )) , kInvalidObject = (1ULL << ( 13 ))
}
 
- Protected Types inherited from TObject
enum  { kOnlyPrepStep = (1ULL << ( 3 )) }
 
- Protected Member Functions inherited from TObject
virtual void DoError (int level, const char *location, const char *fmt, va_list va) const
 Interface to ErrorHandler (protected).
 
void MakeZombie ()
 

#include <TKDTree.h>

Inheritance diagram for TKDTree< Index, Value >:
[legend]

Constructor & Destructor Documentation

◆ TKDTree() [1/4]

template<typename Index , typename Value >
TKDTree< Index, Value >::TKDTree

Default constructor. Nothing is built.

Definition at line 270 of file TKDTree.cxx.

◆ TKDTree() [2/4]

template<typename Index , typename Value >
TKDTree< Index, Value >::TKDTree ( Index  npoints,
Index  ndim,
UInt_t  bsize 
)

Definition at line 292 of file TKDTree.cxx.

◆ TKDTree() [3/4]

template<typename Index , typename Value >
TKDTree< Index, Value >::TKDTree ( Index  npoints,
Index  ndim,
UInt_t  bsize,
Value **  data 
)

Create a kd-tree from the provided data array.

This function only sets the data, call Build() to build the tree!!! Parameters:

  • npoints - total number of points. Adding points after the tree is built is not supported
  • ndim - number of dimensions
  • bsize - maximal number of points in the terminal nodes
  • data - the data array

The data should be placed columnwise (like in a TTree). The columnwise orientation is chosen to simplify the usage together with TTree::GetV1() like functions. An example of filling such an array for a 2d case: Double_t **data = new Double_t*[2]; data[0] = new Double_t[npoints]; data[1] = new Double_t[npoints]; for (Int_t i=0; i<npoints; i++){ data[0][i]=gRandom->Uniform(-1, 1); //fill the x-coordinate data[1][i]=gRandom->Uniform(-1, 1); //fill the y-coordinate }

By default, the kd-tree doesn't own the data. If you want the kd-tree to delete the data array, call kdtree->SetOwner(kTRUE).

Definition at line 344 of file TKDTree.cxx.

◆ ~TKDTree()

template<typename Index , typename Value >
TKDTree< Index, Value >::~TKDTree
override

Destructor By default, the original data is not owned by kd-tree and is not deleted with it.

If you want to delete the data along with the kd-tree, call SetOwner(kTRUE).

Definition at line 373 of file TKDTree.cxx.

◆ TKDTree() [4/4]

template<typename Index , typename Value >
TKDTree< Index, Value >::TKDTree ( const TKDTree< Index, Value > &  )
private

Member Function Documentation

◆ Build()

template<typename Index , typename Value >
void TKDTree< Index, Value >::Build

Build the kd-tree.

  1. calculate number of nodes
  2. calculate first terminal row
  3. initialize index array
  4. non recursive building of the binary tree

The tree is divided recursively. See class description, section 4b for the details of the division algorithm

Definition at line 411 of file TKDTree.cxx.

◆ Class()

template<typename Index , typename Value >
static TClass * TKDTree< Index, Value >::Class ( )
static
Returns
TClass describing this class

◆ Class_Name()

template<typename Index , typename Value >
static const char * TKDTree< Index, Value >::Class_Name ( )
static
Returns
Name of this class

◆ Class_Version()

template<typename Index , typename Value >
static constexpr Version_t TKDTree< Index, Value >::Class_Version ( )
inlinestaticconstexpr
Returns
Version of this class

Definition at line 100 of file TKDTree.h.

◆ CookBoundaries()

template<typename Index , typename Value >
void TKDTree< Index, Value >::CookBoundaries ( const Int_t  node,
Bool_t  left 
)
private

define index of this terminal node

Definition at line 1069 of file TKDTree.cxx.

◆ DeclFileName()

template<typename Index , typename Value >
static const char * TKDTree< Index, Value >::DeclFileName ( )
inlinestatic
Returns
Name of the file containing the class declaration

Definition at line 100 of file TKDTree.h.

◆ Distance()

template<typename Index , typename Value >
Double_t TKDTree< Index, Value >::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 specifies the metric: type=2 - L2 metric, type=1 - L1 metric.

Definition at line 610 of file TKDTree.cxx.

◆ DistanceToNode()

template<typename Index , typename Value >
void TKDTree< Index, Value >::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.

Type argument specifies the metric: type=2 - L2 metric, type=1 - L1 metric If the point is inside the node, both min and max are set to 0.

Definition at line 635 of file TKDTree.cxx.

◆ FindBNodeA()

template<typename Index , typename Value >
void TKDTree< Index, Value >::FindBNodeA ( Value point,
Value delta,
Int_t inode 
)

find the smallest node covering the full range - start

Definition at line 1173 of file TKDTree.cxx.

◆ FindInRange()

template<typename Index , typename Value >
void TKDTree< Index, Value >::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 point 2nd argument - radius of the shere 3rd argument - a vector, in which the results will be returned.

Definition at line 749 of file TKDTree.cxx.

◆ FindNearestNeighbors()

template<typename Index , typename Value >
void TKDTree< Index, Value >::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.

Definition at line 543 of file TKDTree.cxx.

◆ FindNode()

template<typename Index , typename Value >
Index TKDTree< Index, Value >::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

Definition at line 672 of file TKDTree.cxx.

◆ FindPoint()

template<typename Index , typename Value >
void TKDTree< Index, Value >::FindPoint ( Value point,
Index &  index,
Int_t iter 
)

find the index of point works only if we keep fData pointers

Definition at line 703 of file TKDTree.cxx.

◆ GetBoundaries()

template<typename Index , typename Value >
Value * TKDTree< Index, Value >::GetBoundaries

Get the boundaries.

Definition at line 1185 of file TKDTree.cxx.

◆ GetBoundariesExact()

template<typename Index , typename Value >
Value * TKDTree< Index, Value >::GetBoundariesExact

Get the boundaries.

Definition at line 1196 of file TKDTree.cxx.

◆ GetBoundary()

template<typename Index , typename Value >
Value * TKDTree< Index, Value >::GetBoundary ( const Int_t  node)

Get a boundary.

Definition at line 1206 of file TKDTree.cxx.

◆ GetBoundaryExact()

template<typename Index , typename Value >
Value * TKDTree< Index, Value >::GetBoundaryExact ( const Int_t  node)

Get a boundary.

Definition at line 1216 of file TKDTree.cxx.

◆ GetBucketSize()

template<typename Index , typename Value >
Index TKDTree< Index, Value >::GetBucketSize ( )
inline

Definition at line 48 of file TKDTree.h.

◆ GetCrossNode()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetCrossNode ( )
inline

smallest terminal row

Definition at line 45 of file TKDTree.h.

◆ GetIndPoints()

template<typename Index , typename Value >
Index * TKDTree< Index, Value >::GetIndPoints ( )
inline

offset in fIndPoints

Definition at line 47 of file TKDTree.h.

◆ GetLeft()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetLeft ( Int_t  inode) const
inline

Definition at line 24 of file TKDTree.h.

◆ GetNDim()

template<typename Index , typename Value >
Index TKDTree< Index, Value >::GetNDim ( )
inline

Definition at line 40 of file TKDTree.h.

◆ GetNNodes()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetNNodes ( ) const
inline

Definition at line 33 of file TKDTree.h.

◆ GetNodeAxis()

template<typename Index , typename Value >
UChar_t TKDTree< Index, Value >::GetNodeAxis ( Int_t  id) const
inline

Definition at line 31 of file TKDTree.h.

◆ GetNodePointsIndexes()

template<typename Index , typename Value >
void TKDTree< Index, Value >::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 part of indices array, that belong to this node Sometimes points are in 2 intervals, then the first and last value for the second one are returned in third and fourth parameter, otherwise first2 is set to 0 and last2 is set to -1 To iterate over all the points of the node #inode, one can do, for example: Index *indices = kdtree->GetPointsIndexes(); Int_t first1, last1, first2, last2; kdtree->GetPointsIndexes(inode, first1, last1, first2, last2); for (Int_t ipoint=first1; ipoint<=last1; ipoint++){ point = indices[ipoint]; //do something with point; } for (Int_t ipoint=first2; ipoint<=last2; ipoint++){ point = indices[ipoint]; //do something with point; }.

Definition at line 841 of file TKDTree.cxx.

◆ GetNodeValue()

template<typename Index , typename Value >
Value TKDTree< Index, Value >::GetNodeValue ( Int_t  id) const
inline

Definition at line 32 of file TKDTree.h.

◆ GetNPoints()

template<typename Index , typename Value >
Index TKDTree< Index, Value >::GetNPoints ( )
inline

Definition at line 39 of file TKDTree.h.

◆ GetNPointsNode()

template<typename Index , typename Value >
Index TKDTree< Index, Value >::GetNPointsNode ( Int_t  node) const

Get number of points in this node for all the terminal nodes except last, the size is fBucketSize for the last node it's fOffsetfBucketSize, or if fOffsetfBucketSize==0, it's also fBucketSize.

Definition at line 895 of file TKDTree.cxx.

◆ GetOffset()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetOffset ( )
inline

cross node

Definition at line 46 of file TKDTree.h.

◆ GetParent()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetParent ( Int_t  inode) const
inline

Definition at line 26 of file TKDTree.h.

◆ GetPointsIndexes()

template<typename Index , typename Value >
Index * TKDTree< Index, Value >::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

Definition at line 812 of file TKDTree.cxx.

◆ GetRight()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetRight ( Int_t  inode) const
inline

Definition at line 25 of file TKDTree.h.

◆ GetRowT0()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetRowT0 ( )
inline

Definition at line 44 of file TKDTree.h.

◆ GetTotalNodes()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::GetTotalNodes ( ) const
inline

Definition at line 34 of file TKDTree.h.

◆ IsA()

template<typename Index , typename Value >
TClass * TKDTree< Index, Value >::IsA ( ) const
inlineoverridevirtual
Returns
TClass describing current object

Reimplemented from TObject.

Definition at line 100 of file TKDTree.h.

◆ IsOwner()

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::IsOwner ( )
inline

Definition at line 57 of file TKDTree.h.

◆ IsTerminal()

template<typename Index , typename Value >
Bool_t TKDTree< Index, Value >::IsTerminal ( Index  inode) const
inline

Definition at line 56 of file TKDTree.h.

◆ KOrdStat()

template<typename Index , typename Value >
Value TKDTree< Index, Value >::KOrdStat ( Index  ntotal,
Value a,
Index  k,
Index *  index 
) const

copy of the TMath::KOrdStat because I need an Index work array

Definition at line 980 of file TKDTree.cxx.

◆ MakeBoundaries()

template<typename Index , typename Value >
void TKDTree< Index, Value >::MakeBoundaries ( Value range = nullptr)

Build boundaries for each node.

Note, that the boundaries here are built based on the splitting planes of the kd-tree, and don't necessarily pass through the points of the original dataset. For the latter functionality see function MakeBoundariesExact() Boundaries can be retrieved by calling GetBoundary(inode) function that would return an array of boundaries for the specified node, or GetBoundaries() function that would return the complete array.

Definition at line 1034 of file TKDTree.cxx.

◆ MakeBoundariesExact()

template<typename Index , typename Value >
void TKDTree< Index, Value >::MakeBoundariesExact

Build boundaries for each node.

Unlike MakeBoundaries() function the boundaries built here always pass through a point of the original dataset So, for example, for a terminal node with just one point minimum and maximum for each dimension are the same. Boundaries can be retrieved by calling GetBoundaryExact(inode) function that would return an array of boundaries for the specified node, or GetBoundaries() function that would return the complete array.

Definition at line 1114 of file TKDTree.cxx.

◆ operator=()

template<typename Index , typename Value >
TKDTree< Index, Value > & TKDTree< Index, Value >::operator= ( const TKDTree< Index, Value > &  )
private

◆ SetData() [1/2]

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::SetData ( Index  idim,
Value data 
)

Set the coordinate #ndim of all points (the column #ndim of the data matrix) After setting all the data columns, proceed by calling Build() function Note, that calling this function after Build() is not possible Note also, that no checks on the array sizes is performed anywhere.

Definition at line 943 of file TKDTree.cxx.

◆ SetData() [2/2]

template<typename Index , typename Value >
void TKDTree< Index, Value >::SetData ( Index  npoints,
Index  ndim,
UInt_t  bsize,
Value **  data 
)

Set the data array. See the constructor function comments for details.

Definition at line 918 of file TKDTree.cxx.

◆ SetOwner()

template<typename Index , typename Value >
void TKDTree< Index, Value >::SetOwner ( Int_t  owner)
inline

Definition at line 65 of file TKDTree.h.

◆ Spread()

template<typename Index , typename Value >
void TKDTree< Index, Value >::Spread ( Index  ntotal,
Value a,
Index *  index,
Value min,
Value max 
) const

Calculate spread of the array a.

Definition at line 963 of file TKDTree.cxx.

◆ Streamer()

template<typename Index , typename Value >
void TKDTree< Index, Value >::Streamer ( TBuffer R__b)
overridevirtual

Stream an object of class TObject.

Reimplemented from TObject.

◆ StreamerNVirtual()

template<typename Index , typename Value >
void TKDTree< Index, Value >::StreamerNVirtual ( TBuffer ClassDef_StreamerNVirtual_b)
inline

Definition at line 100 of file TKDTree.h.

◆ UpdateNearestNeighbors()

template<typename Index , typename Value >
void TKDTree< Index, Value >::UpdateNearestNeighbors ( Index  inode,
const Value point,
Int_t  kNN,
Index *  ind,
Value dist 
)
private

Update the nearest neighbors values by examining the node inode.

Definition at line 563 of file TKDTree.cxx.

◆ UpdateRange()

template<typename Index , typename Value >
void TKDTree< Index, Value >::UpdateRange ( Index  inode,
Value point,
Value  range,
std::vector< Index > &  res 
)
private

Internal recursive function with the implementation of range searches.

Definition at line 759 of file TKDTree.cxx.

Member Data Documentation

◆ fAxis

template<typename Index , typename Value >
UChar_t* TKDTree< Index, Value >::fAxis
protected

[fNNodes] nodes cutting axis

Definition at line 84 of file TKDTree.h.

◆ fBoundaries

template<typename Index , typename Value >
Value* TKDTree< Index, Value >::fBoundaries
protected

! nodes boundaries

Definition at line 89 of file TKDTree.h.

◆ fBucketSize

template<typename Index , typename Value >
Index TKDTree< Index, Value >::fBucketSize
protected

size of the terminal nodes

Definition at line 83 of file TKDTree.h.

◆ fCrossNode

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fCrossNode
protected

! cross node - node that begins the last row (with terminal nodes only)

Definition at line 94 of file TKDTree.h.

◆ fData

template<typename Index , typename Value >
Value** TKDTree< Index, Value >::fData
protected

! data points

Definition at line 88 of file TKDTree.h.

◆ fDataOwner

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fDataOwner
protected

! 0 - not owner, 2 - owner of the pointer array, 1 - owner of the whole 2-d array

Definition at line 77 of file TKDTree.h.

◆ fIndPoints

template<typename Index , typename Value >
Index* TKDTree< Index, Value >::fIndPoints
protected

! array of points indexes

Definition at line 92 of file TKDTree.h.

◆ fNDim

template<typename Index , typename Value >
Index TKDTree< Index, Value >::fNDim
protected

number of dimensions

Definition at line 80 of file TKDTree.h.

◆ fNDimm

template<typename Index , typename Value >
Index TKDTree< Index, Value >::fNDimm
protected

dummy 2*fNDim

Definition at line 81 of file TKDTree.h.

◆ fNNodes

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fNNodes
protected

size of node array

Definition at line 78 of file TKDTree.h.

◆ fNPoints

template<typename Index , typename Value >
Index TKDTree< Index, Value >::fNPoints
protected

number of multidimensional points

Definition at line 82 of file TKDTree.h.

◆ fOffset

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fOffset
protected

! offset in fIndPoints - if there are 2 rows, that contain terminal nodes fOffset returns the index in the fIndPoints array of the first point that belongs to the first node on the second row.

Definition at line 95 of file TKDTree.h.

◆ fRange

template<typename Index , typename Value >
Value* TKDTree< Index, Value >::fRange
protected

[fNDimm] range of data for each dimension

Definition at line 87 of file TKDTree.h.

◆ fRowT0

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fRowT0
protected

! smallest terminal row - first row that contains terminal nodes

Definition at line 93 of file TKDTree.h.

◆ fTotalNodes

template<typename Index , typename Value >
Int_t TKDTree< Index, Value >::fTotalNodes
protected

total number of nodes (fNNodes + terminal nodes)

Definition at line 79 of file TKDTree.h.

◆ fValue

template<typename Index , typename Value >
Value* TKDTree< Index, Value >::fValue
protected

[fNNodes] nodes cutting value

Definition at line 85 of file TKDTree.h.

  • math/mathcore/inc/TKDTree.h
  • math/mathcore/src/TKDTree.cxx