Main Content

Code Generation for Nearest Neighbor Searcher

The object functions knnsearch and rangesearch of the nearest neighbor searcher objects, ExhaustiveSearcher and KDTreeSearcher, support code generation. This example shows how to generate code for finding the nearest neighbor using an exhaustive searcher object at the command line. The example shows two different ways to generate code, depending on the way you use the object: load the object by using loadLearnerForCoder in an entry-point function, and pass a compile-time constant object to the generated code.

Train Exhaustive Nearest Neighbor Searcher

Load Fisher's iris data set.

load fisheriris

Remove five irises randomly from the predictor data to use as a query set.

rng('default');             % For reproducibility
n = size(meas,1);           % Sample size
qIdx = randsample(n,5);     % Indices of query data
X = meas(~ismember(1:n,qIdx),:);
Y = meas(qIdx,:);

Prepare an exhaustive nearest neighbor searcher using the training data. Specify the 'Distance' and 'P' name-value pair arguments to use the Minkowski distance with an exponent of 1 for finding the nearest neighbor.

Mdl = ExhaustiveSearcher(X,'Distance','minkowski','P',1);

Find the index of the training data (X) that is the nearest neighbor of each point in the query data (Y).

Idx = knnsearch(Mdl,Y);

Generate Code Using saveLearnerForCoder and loadLearnerForCoder

Generate code that loads an exhaustive searcher, takes query data as an input argument, and then finds the nearest neighbor.

Save the exhaustive searcher to a file using saveLearnerForCoder.

saveLearnerForCoder(Mdl,'searcherModel')

saveLearnerForCoder saves the model to the MATLAB® binary file searcherModel.mat as a structure array in the current folder.

Define the entry-point function myknnsearch1 that takes query data as an input argument. Within the function, load the searcher object by using loadLearnerForCoder, and then pass the loaded model to knnsearch.

type myknnsearch1.m % Display contents of myknnsearch1.m file
function idx = myknnsearch1(Y) %#codegen
Mdl = loadLearnerForCoder('searcherModel');
idx = knnsearch(Mdl,Y);
end

Note: If you click the button located in the upper-right section of this page and open this example in MATLAB, then MATLAB opens the example folder. This folder includes the entry-point function files, myknnsearch1.m, myknnsearch2.m, and myknnsearch3.m.

Generate code for myknnsearch1 by using codegen (MATLAB Coder). Specify the data type and dimension of the input argument by using coder.typeof (MATLAB Coder) so that the generated code accepts a variable-size array.

codegen myknnsearch1 -args {coder.typeof(Y,[Inf,4],[1,0])}
Code generation successful.

For a more detailed code generation example that uses saveLearnerForCoder and loadLearnerForCoder, see Code Generation for Prediction of Machine Learning Model at Command Line. For more details about specifying variable-size arguments, see Specify Variable-Size Arguments for Code Generation.

Pass the query data (Y) to verify that myknnsearch1 and the MEX file return the same indices.

myIdx1 = myknnsearch1(Y);
myIdx1_mex = myknnsearch1_mex(Y);

Compare myIdx1 and myIdx1_mex by using isequal.

verifyMEX1 = isequal(Idx,myIdx1,myIdx1_mex)
verifyMEX1 = logical
   1

isequal returns logical 1 (true) if all the inputs are equal. This comparison confirms that myknnsearch1 and the MEX file return the same results.

Generate Code with Constant Folded Model Object

Nearest neighbor searcher objects can be an input argument of a function you define for code generation. The -args option of codegen (MATLAB Coder) accept a compile-time constant searcher object.

Define the entry-point function myknnsearch2 that takes both an exhaustive searcher model and query data as input arguments instead of loading the model in the function.

type myknnsearch2.m % Display contents of myknnsearch2.m file
function idx = myknnsearch2(Mdl,Y) %#codegen
idx = knnsearch(Mdl,Y);
end

To generate code that takes the model object as well as the query data, designate the model object as a compile-time constant by using coder.Constant (MATLAB Coder) and include the constant folded model object in the -args value of codegen.

codegen myknnsearch2 -args {coder.Constant(Mdl),coder.typeof(Y,[Inf,4],[1,0])}
Code generation successful.

The code generation workflow with a constant folded model object follows general code generation workflow. For details, see General Code Generation Workflow.

Verify that myknnsearch2 and the MEX file return the same results.

myIdx2 = myknnsearch2(Mdl,Y);
myIdx2_mex = myknnsearch2_mex(Mdl,Y);
verifyMEX2 = isequal(Idx,myIdx2,myIdx2_mex)
verifyMEX2 = logical
   1

Generate Code with Name-Value Pair Arguments

Define the entry-point function myknnsearch3 that takes a model object, query data, and name-value pair arguments. You can allow for optional name-value arguments by specifying varargin as an input argument. For details, see Code Generation for Variable Length Argument Lists (MATLAB Coder).

type myknnsearch3.m % Display contents of myknnsearch3.m file
function idx = myknnsearch3(Mdl,Y,varargin) %#codegen
idx = knnsearch(Mdl,Y,varargin{:});
end

To generate code that allows a user-defined exponent for the Minkowski distance, include {coder.Constant('P'),0} in the -args value of codegen. Use coder.Constant (MATLAB Coder) because the name of a name-value pair argument must be a compile-time constant.

codegen myknnsearch3 -args {coder.Constant(Mdl),coder.typeof(Y,[Inf,4],[1,0]),coder.Constant('P'),0}
Code generation successful.

Verify that myknnsearch3 and the MEX file return the same results.

newIdx = knnsearch(Mdl,Y,'P',2);
myIdx3 = myknnsearch3(Mdl,Y,'P',2);
myIdx3_mex = myknnsearch3_mex(Mdl,Y,'P',2);
verifyMEX3 = isequal(newIdx,myIdx3,myIdx3_mex)
verifyMEX3 = logical
   1

See Also

(MATLAB Coder) | | | | | |

Related Topics