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 }); ::