MATLAB Examples

Code Generation Workflow for Exhaustive Searcher

This example shows how to generate code for finding the nearest neighbor using an exhaustive searcher object at the command line. This example shows two different methods depending on the way you use the object: load the object by using loadCompactModel in a function you declare, or pass a compile-time constant object to the generated code.

Contents

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 later.

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

Set Up C Compiler

To generate C code, you must have access to a C compiler, and the compiler must be configured properly. For more details, see Setting Up Your C Compiler. Set up the compiler for MEX-code generation.

mex -setup
MEX configured to use 'Xcode with Clang' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
	 variables with more than 2^32-1 elements. You will be required
	 to update your code to utilize the new API.
	 You can find more information about this at:
	 http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.

To choose a different language, execute one from the following:
 mex -setup C++ 
 mex -setup FORTRAN

Generate Code Using saveCompactModel and loadCompactModel

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 saveCompactModel.

saveCompactModel(Mdl,'searcherModel')

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

Declare a function myknnsearch1 that takes query data as an input argument. Within the function, load the searcher object by using loadCompactModel, and then pass the loaded model to knnsearch.

function idx = myknnsearch1(x) %#codegen
Mdl = loadCompactModel('searcherModel');
idx = knnsearch(Mdl,x);
end

Be sure to type the %#codegen compiler directive somewhere in the function.

Generate code for myknnsearch1 by using codegen. Specify the data type and dimension of the input argument by using coder.typeof.

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

Verify that myknnsearch1 and the MEX file return the expected indices by passing the query data (Y).

myIdx1 = myknnsearch1(Y);
myIdx1_mex = myknnsearch1_mex(Y);
verifyMEX1 = isequal(Idx,myIdx1,myIdx1_mex)
verifyMEX1 =

  logical

   1

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

Generate Code with Constant Folded Model Object

Declare a function myknnsearch2 that takes both an exhaustive searcher model and query data as input arguments instead of loading the model in the function.

function idx = myknnsearch2(Mdl,x) %#codegen
idx = knnsearch(Mdl,x);
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 and include the constant folded model object in the -args value of codegen.

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

Verify that myknnsearch2 and the MEX file return the expected 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

Declare a function that takes a model object, query data, and name-value pair arguments.

function idx = myknnsearch3(Mdl,x,varargin) %#codegen
idx = knnsearch(Mdl,x,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.

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

Verify that myknnsearch3 and the MEX file return the expected 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