MATLAB Examples

Specify Variable-Sized Arguments for Code Generation

This example shows how to generate code from a prediction function that has variable-sized input arguments. Specifically, the example creates a function that predicts labels based on a trained classification tree. At compile time, the number of observations to label and the number of subtrees are unknown.

Load Fisher's iris data set. Convert the labels to a character matrix.

load fisheriris
species = char(species);

Train a classification tree using the entire data set.

Mdl = fitctree(meas,species);

Mdl is a ClassificationTree model.

Save the trained classification tree to a file called ClassTreeIris.mat in your current folder.

MdlName = 'ClassTreeIris';
saveCompactModel(Mdl,MdlName);

In your current folder, declare a function called mypredictTree.m that:

  • Accepts measurements with columns corresponding to meas and accepts valid name-value pair arguments
  • Loads a trained classification tree
  • Predicts labels and corresponding scores, node numbers, and class numbers from the loaded classification tree
function [label,score,node,cnum] = mypredictTree(x,savedmdl,varargin) %#codegen
%MYPREDICTTREE Predict iris species using classification tree
%   MYPREDICTTREE predicts iris species for the n observations in the
%   n-by-4 matrix x using the classification tree stored in the MAT-file
%   whose name is in savedmdl, and then returns the predictions in the
%   array label. Each row of x contains the lengths and widths of the petal
%   and sepal of an iris (see the fisheriris data set).  For other output
%   argument descriptions, see the predict reference page.
CompactMdl = loadCompactModel(savedmdl);
[label,score,node,cnum] = predict(CompactMdl,x,varargin{:});
end


Declare code generation variables for the predictor data and subtrees from which to predict labels using coder.typeof. Specify that the predictor data variable is double-precision with the same number of columns as the predictor data used in training the model, but that the number of observations (rows) is arbitrary. Specify that the number of subtrees from which to predict labels is a double-precision row vector with an arbitrary number of columns.

p = numel(Mdl.PredictorNames);
x = coder.typeof(0,[Inf,p],[1,0]);
subtrees = coder.typeof(0,[1,Inf],[0,1]);

Generate a MEX function from mypredictTree.m. Because C uses static typing, codegen must determine the properties of all variables in MATLAB® files at compile time. To designate arguments as compile-time constants, use coder.Constant.

codegen mypredictTree.m -config:mex -args {x,coder.Constant(MdlName),coder.Constant('Subtrees'),subtrees}

codegen generates the MEX file mypredictTree_mex.mexw64 in your current folder. The file extension depends on your platform. Although predict accepts single-precision values, double-precision values, and 'all' for 'SubTrees', you can specify only double-precision values when you use the MEX function for prediction.

Predict labels for a random selection of 15 values from the training data using the generated MEX function and the subtree at pruning level 1. Compare the labels from the MEX function with those predicted by predict.

rng(1); % For reproducibility
Xnew = datasample(meas,15);
labelsMEX = mypredictTree_mex(Xnew,MdlName,'Subtrees',1)
labelsPREDICT = predict(Mdl,Xnew,'Subtrees',1)
labelsMEX =

  15x1 cell array

    {'versicolor'}
    {'virginica' }
    {'setosa'    }
    {'setosa'    }
    {'setosa'    }
    {'setosa'    }
    {'setosa'    }
    {'versicolor'}
    {'versicolor'}
    {'versicolor'}
    {'versicolor'}
    {'virginica' }
    {'setosa'    }
    {'virginica' }
    {'setosa'    }


labelsPREDICT =

  15x10 char array

    'versicolor'
    'virginica '
    'setosa    '
    'setosa    '
    'setosa    '
    'setosa    '
    'setosa    '
    'versicolor'
    'versicolor'
    'versicolor'
    'versicolor'
    'virginica '
    'setosa    '
    'virginica '
    'setosa    '

The predicted labels are the same as the MEX function labels except for the data type. When the 'Subtrees' value is an arbitrary double at compile time and the response is a character array, codegen must cast the predicted labels as a cell array of character vectors.