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.

116 lines
2.7 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 some 2D points and place into a dataset
s.reboot;
(
~points = 100.collect{ [ 1.0.linrand,1.0.linrand] };
~dataset= FluidDataSet(s,\kdtree_help_rand2d);
~tmpbuf = Buffer.alloc(s,2);
fork{
s.bind{
~dataset.ready.wait;
~points.do{|x,i|
(""++(i+1)++"/100").postln;
~tmpbuf.setn(0,x);
~dataset.addPoint(i,~tmpbuf);
s.sync
};
"Data loaded".postln;
}
}
)
//Make a new tree, and fit it to the dataset
(
fork{
~tree = FluidKDTree(s);
~tree.ready.wait;
s.sync;
~tree.fit(~dataset);
}
)
//Dims of tree should match dataset
~tree.cols
//Return labels of k nearest points to new data
(
~testpoint = [ 1.0.linrand,1.0.linrand ];
("\n\nTest point:" + ~testpoint).postln;
~tmpbuf.setn(0,~testpoint);
fork{
~tree.kNearest(~tmpbuf,5, { |a|
("Labels of nearest points" + a).postln;
"Nearest points".postln;
a.do{|l|
~dataset.getPoint(l,~tmpbuf,action:{
~tmpbuf.loadToFloatArray(action:{ |point|
point.postln;
})
});
s.sync;
}
});
}
)
//or the distances
~tree.kNearestDist(~tmpbuf,5, { |a| a.postln });
::