You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.6 KiB
Plaintext

TITLE:: FluidKDTree
summary:: KD Tree on the server
categories:: FluidManipulation
related:: Classes/FluidDataSet
DESCRIPTION::
A server-side K-Dimensional tree for efficient neighbourhood searches of multi-dimensional data.
See https://scikit-learn.org/stable/modules/neighbors.html#nearest-neighbor-algorithms for more on KD Trees
CLASSMETHODS::
METHOD:: new
Make a new KDTree model for the given server.
ARGUMENT:: server
The server on which to make the model.
INSTANCEMETHODS::
METHOD:: fit
Build the tree by scanning the points of a LINK::Classes/FluidDataSet::
ARGUMENT:: dataset
The LINK::Classes/FluidDataSet:: of interest. This can either be a data set object itself, or the name of one.
ARGUMENT:: action
A function to run when indexing is complete.
METHOD:: kNearest
Returns the IDs of the CODE::k:: points nearest to the one passed.
ARGUMENT:: buffer
A LINK::Classes/Buffer:: containing a data point to match against. The number of frames in the buffer must match the dimensionality of the LINK::Classes/FluidDataSet:: the tree was fitted to.
ARGUMENT:: k
The number of neighbours to return.
ARGUMENT:: action
A function that will run when the query returns, whose argument is an array of point IDs from the tree's LINK::Classes/FluidDataSet::
METHOD:: kNearestDist
Get the distances of the K nearest neighbours to a point.
ARGUMENT:: buffer
A LINK::Classes/Buffer:: containing a data point to match against. The number of frames in the buffer must match the dimensionality of the LINK::Classes/FluidDataSet:: the tree was fitted to.
ARGUMENT:: k
The number of neighbours to search
ARGUMENT:: action
A function that will run when the query returns, whose argument is an array of distances.
EXAMPLES::
code::
// Make a dataset of random 23D points
s.boot;
(
fork{
~ds = FluidDataSet.new(s,\kdtree_help_rand2d);
d = Dictionary.with(
*[\cols -> 2,\data -> Dictionary.newFrom(
100.collect{|i| [i, [ 1.0.linrand,1.0.linrand]]}.flatten)]);
s.sync;
~ds.load(d, {~ds.print});
}
)
// Make a new tree, and fit it to the dataset
~tree = FluidKDTree(s);
//Fit it to the dataset
~tree.fit(~ds);
// Should be 100 points, 2 columns
~tree.size;
~tree.cols;
//Return labels of k nearest points to a new point
~p = [ 1.0.linrand,1.0.linrand ];
~tmpbuf = Buffer.loadCollection(s, ~p, 1, {
~tree.kNearest(~tmpbuf,5, { |a|~nearest = a;})
});
// Labels of nearest points
~nearest.postln;
// Values
fork{
~nearest.do{|n|
~ds.getPoint(n, ~tmpbuf, {~tmpbuf.getn(0, 2, {|x|x.postln})});
s.sync;
}
}
//Distances of the nearest points
~tree.kNearestDist(~tmpbuf, 5, { |a| a.postln });
::