In this tutorial, you will learn how to:
Automatically generate a MEX function from your MATLAB® code.
Define function input properties at the command line.
Specify the upper bounds of variable-size data.
Specify variable-size inputs.
Generate a code generation report that you can use to debug your MATLAB code and verify that it is suitable for code generation.
To complete this tutorial, you should have basic familiarity with MATLAB software.
To complete this tutorial, you must install the following products:
MATLAB
MATLAB Coder™
C compiler
For most platforms, a default compiler is supplied with MATLAB.
MATLAB Coder automatically locates and uses a supported installed compiler. For the current list of supported compilers, see Supported and Compatible Compilers on the MathWorks® website.
You can use mex -setup
to change the default
compiler. See Change Default Compiler.
For instructions on installing MathWorks products,
refer to the installation documentation. If you have installed MATLAB and
want to check which other MathWorks products are
installed, enter ver
in the MATLAB Command
Window.
The Euclidean distance between points p and q is the length of the line segment . In Cartesian coordinates, if and are two points in Euclidean n-space, then the distance from p to q is given by:
In one dimension, the distance between two points, x1 and x2, on a line is simply the absolute value of the difference between the two points:
In two dimensions, the distance between and is:
The example for this tutorial computes the minimum Euclidean distance between a column vector x and a collection of column vectors in the codebook matrix cb. The function has three output variables:
y, the vector in cb with the minimum distance to x
idx, the index of the column vector in cb corresponding to the closest vector
distance, the distance between x and y
This algorithm computes the minimum Euclidean distance between a column vector x and a collection of column vectors in the codebook matrix cb. The algorithm computes the minimum distance to x and finds the column vector in cb that is closest to x. It outputs this column vector, y, its index, idx, in cb, and distance, the distance between x and y.
The function signature for the algorithm is:
function [y,idx,distance] = euclidean(x,cb)
The minimum distance is initially set to the first element of cb.
idx=1; distance=norm(x-cb(:,1));
The minimum distance calculation is performed in the for
-loop.
for index=2:size(cb,2) d=norm(x-cb(:,index)); if d < distance distance=d; idx=index; end end
The output y is set to the minimum distance vector.
y=cb(:,idx);
The tutorial uses the following files:
Example MATLAB code files for each step of the tutorial.
Throughout this tutorial, you work with MATLAB files that contain a simple Euclidean distance algorithm.
Build scripts that you use to compile your function code.
Test files that:
Perform the preprocessing functions, for example, setting up input data.
Call the specified Euclidean function.
Perform the post-processing functions, for example, plotting the distances.
A MAT-file that contains example input data.
The tutorial files are available in the following folder: docroot\toolbox\coder\examples\euclidean
.
To run the tutorial, you must copy these files to a local folder.
For instructions, see Copying Files Locally.
Type | Name | Description |
---|---|---|
Function code | euclidean01.m | Baseline MATLAB implementation of Euclidean minimum distance algorithm including plot functions. |
euclidean02.m | Version of the original algorithm with the %#codegen directive. | |
euclidean03.m | Version of the original algorithm without plotting functions. | |
euclidean04.m | Modified algorithm that uses assert to
specify the upper bounds of variable N . | |
Build script | build01.m | Build script for euclidean03.m . |
build02.m | Build script for euclidean03.m specifying
two-dimensional inputs. | |
build03.m | Build script for euclidean03.m specifying
variable-size inputs. | |
build04.m | Build script for euclidean04.m . | |
Test script | test01.m | Initial version of test script, includes plot functions. Tests euclidean03 MEX
function. |
test02.m | Tests the three-dimensional euclidean03 MEX
function with two-dimensional inputs. | |
test03.m | Tests the two-dimensional euclidean04 MEX
function with two-dimensional inputs. | |
test04.m | Tests euclidean03_varsize MEX function with
two-dimensional and three-dimensional inputs. | |
test05.m | Tests euclidean04 MEX function specifying
how many elements of each input to process. | |
MAT-file | euclidean.mat | Contains the input data used by the algorithm. |
Copy the tutorial files to a local solutions folder and create a local working folder:
Create a local solutions
folder,
for example, c:\coder\euclidean\solutions
.
Change to the docroot\toolbox\coder\examples
folder.
At the MATLAB command prompt, enter:
cd(fullfile(docroot, 'toolbox', 'coder', 'examples'))
Copy the contents of the euclidean
subfolder
to your local solutions
folder, specifying
the full pathname of the solutions
folder:
copyfile('euclidean', 'solutions')
solutions
folder
now contains a complete set of solutions for the tutorial. If you
do not want to perform the steps for each task in the tutorial, you
can view the solutions to see how the code should look.Create a local work
folder,
for example, c:\coder\euclidean\work
.
Copy the following files from your solutions
folder
to your work
folder.
euclidean01.m
euclidean.mat
Build files build01.m
through build04.m
Test scripts test01.m
through test05.m
Your work
folder now contains the
files that you need to get started with the tutorial.
In this tutorial, you work with a MATLAB function that implements the Euclidean distance minimizing algorithm. You make the MATLAB version of this algorithm suitable for code generation and test the resulting MEX function to validate the functionality of the modified code. As you work through the tutorial, you refine the design of the algorithm to accept variable-size inputs.
Before generating a MEX function, run the original MATLAB function to see how the Euclidean distance minimizing algorithm works.
Set your MATLAB current folder to the work folder that contains your files for this tutorial.
cd work
Load the euclidean.mat
file into
your MATLAB workspace.
load euclidean.mat
A matrix x
containing 40000
three-dimensional
vectors.
A matrix cb
containing 216
three-dimensional
vectors.
The Euclidean algorithm minimizes the distance between
a column vector, x1
, taken from matrix x
,
and the column vectors in the codebook matrix cb
.
It outputs the column vector in cb
that is closest
to x1
.
Create a single input vector x1
from
the matrix x
.
x1=x(:,1)
The result is the first vector from x
:
x1 = 0.8568 0.7455 0.3835
Use the Euclidean algorithm to find the vector in
codebook matrix cb
that is closest to x1
.
At the MATLAB command prompt, enter:
[y, idx, distance]=euclidean01(x1,cb)
The Euclidean algorithm runs and plots the lines from x1
to
each vector in cb
.
After completing
the algorithm, it outputs the coordinates of the point y
,
which is the vector in cb
closest to x1
,
together with the index idx
of x1
in cb
,
and the distance, distance
, between y
and x1
.
y = 0.8000 0.8000 0.4000 idx = 171 distance = 0.0804
The algorithm computes that the point y=0.8000, 0.8000,
0.4000
, the 171st vector in cb
,
is closest to point x1
. The distance between y
and x1
is 0.0804
.
Where to Go Next. Before continuing with the tutorial, you must set up your C compiler as detailed in Setting Up Your C Compiler.
MATLAB Coder automatically locates and uses a supported installed compiler. For the current list of supported compilers, see Supported and Compatible Compilers on the MathWorks website.
You can use mex -setup
to change the default
compiler. See Change Default Compiler.
Designing for Code Generation. Before generating code, you must prepare your MATLAB code for code generation. The first step is to eliminate unsupported constructs.
Checking for Issues at Design Time. There are two tools that help you detect code generation issues at design time: the code analyzer and the code generation readiness tool.
You use the code analyzer in the MATLAB Editor to check for code issues at design time, minimizing compilation errors. The code analyzer continuously checks your code as you enter it. It reports problems and recommends modifications to maximize performance and maintainability.
To use the code analyzer to identify warnings and errors specific
to MATLAB for code generation, you must add the %#codegen
directive
(or pragma) to your MATLAB file. A complete list of MATLAB for
Code Generation code analyzer messages is available in the MATLAB Code
Analyzer preferences. See Running the Code Analyzer Report for more details.
Note: The code analyzer might not detect all MATLAB for code generation issues. After eliminating errors or warnings that the code analyzer detects, compile your code with MATLAB Coder to determine if the code has other compliance issues. |
The code generation readiness tool screens MATLAB code for features and functions that are not supported for code generation. The tool provides a report that lists the source files that contain unsupported features and functions and an indication of how much work is required to make the MATLAB code suitable for code generation.
You can access the code generation readiness tool in the following ways:
In the current folder browser — by right-clicking a MATLAB file
At the command line — by using the coder.screener
function.
In a project — when you add a MATLAB file to a project, if MATLAB Coder detects code generation issues, it provides a link to the code generation readiness report.
Checking for Issues at Code Generation Time. You can use codegen
to
check for issues at code generation time. codegen
checks
that your MATLAB code is suitable for code generation.
When codegen
detects errors or warnings,
it automatically generates an error report that describes the issues
and provides links to the offending MATLAB code. For more information,
see Code Generation Reports.
After code generation, codegen
generates
a MEX function that you can use to test your implementation in MATLAB.
Checking for Issues at Run Time. You can use codegen
to generate a MEX function
and check for issues at run time. In simulation, the code generated
for your MATLAB functions includes the run-time checks. Disabling
run-time checks and extrinsic calls usually results in streamlined
generated code and faster simulation. You control run-time checks
using the MEX configuration object, coder.MexCodeConfig
.
For more information, see Control Run-Time Checks.
If you encounter run-time errors in your MATLAB functions, a run-time stack appears automatically in the MATLAB Command Window. See Debug Run-Time Errors.
Where to Go Next. The next section of the tutorial, Making Your Code Suitable for Code Generation, shows you
how to use the MATLAB code analyzer and codegen
to
make your code suitable for code generation.
Making Your Code Suitable for Code Generation. To begin the process of making your MATLAB code suitable
for code generation, you work with the euclidean01.m
file.
This file is a MATLAB version of a three-dimensional Euclidean
example that plots the distances between an input vector x
and
each of the vectors in the codebook matrix cb
.
It determines which vector in cb
is closest to x
,
and outputs this vector, its position in cb
, and
the distance to y
.
In your work folder, open euclidean01.m
in
the MATLAB Editor.
edit euclidean01.m
The file opens. The code analyzer message indicator in the top right corner of the MATLAB Editor is green, which indicates that the code analyzer has not detected errors, warnings, or opportunities for improvement in the code.
Turn on code generation error checking by adding the %#codegen
compilation
directive after the function declaration.
function [ y, idx, distance ] = ...
euclidean01( x, cb ) %#codegen
For more information on using the code analyzer, see Running the Code Analyzer Report.
Change the function name to euclidean02
and
save the file as euclidean02.m
in the current folder.
You are now ready to compile your code using codegen
,
which checks that your code is suitable for code generation. After
code generation, codegen
generates a MEX function
that you can test in MATLAB.
About codegen. You generate MEX functions using codegen
,
a function that compiles MATLAB code to a MEX function. codegen
also
checks that your MATLAB code is suitable for code generation.
Using codegen. Because C uses static typing, codegen
must
determine the properties of all variables
in the MATLAB files at compile time. Therefore, you must specify
the properties of all function inputs
at the same time as you compile the file with codegen
.
To compile euclidean02.m
, you must specify the
size of the input vector x
and the codebook matrix cb
.
Compile the euclidean02.m
file.
codegen -report euclidean02.m -args {x(:,1), cb}
By default, codegen
generates
a MEX function named euclidean02_mex
in the current
folder. You can compare the results of running the MEX function with
the results of running the original MATLAB code.
The -args
option instructs codegen
to
compile the file euclidean02.m
by using the sample
input parameters x(:,1)
and cb
.
The -report
option instructs codegen
to
produce a code generation report.
At the MATLAB command prompt, click the link
to the code generation report. View the MATLAB code for the plot_distances
function.
MATLAB Coder treats common MATLAB visualization functions
as extrinsic. It does not generate code for these functions. Instead,
for a MEX function, it generates code to run the function in MATLAB.
These functions include line
, grid
, clf
, axis
,
and pause
. The report highlights extrinsic functions.
If a function is not supported for code generation, and is not treated
as extrinsic, you must explicitly declare that the function is extrinsic
by using coder.extrinsic
. See Extrinsic Functions.
You are ready to begin the next task in this tutorial, Validating the MEX Function.
Test the MEX function that you generated in Generating a MEX Function Using codegen to verify that it provides the same functionality as the original MATLAB code. You run the MEX function with the same inputs that you used in Running the Original MATLAB Code.
Running the Generated MEX Function
Create a single input vector x1
from
the matrix x
.
x1=x(:,1)
The result is the first vector in x
:
x1 = 0.8568 0.7455 0.3835
Use the MEX function euclidean02_mex
to
find the vector in codebook matrix cb
that is closest
to x1
.
[y, idx, distance] = euclidean02_mex(x1,cb)
The MEX function runs and plots the lines from x1
to
each vector in cb
. After completing the algorithm,
it outputs the coordinates of the point y
, which
is the vector in cb
closest to x1
,
together with the index idx
of y
in cb
,
and the distance, distance
, between y
and x1
.
y = 0.8000 0.8000 0.4000 idx = 171 distance = 0.0804
The plots and outputs are identical to those generated with
the original MATLAB function. The MEX function euclidean02_mex
is
functionally equivalent to the original MATLAB code in euclidean01.m
.
In Check for Run-Time Issues, you generated
a MEX function for your MATLAB code by calling codegen
from
the MATLAB command line. In this part of the tutorial, you use
a build script to generate your MEX function and a test script to
test it. The first step is to modify the code in euclidean02.m
to
move the plotting function to a separate test script.
Modifying the Code to Remove the Plot Function. In the file euclidean02.m
:
Delete the call to plot_distances
.
Delete the local function plot_distances
.
Change the function name to euclidean03
and
save the file as euclidean03.m
in the current folder.
Using the Build Script build01.m. Next you use the build script build01.m
that
compiles euclidean03.m
using codegen
.
Use the -report
option, which instructs codegen
to
generate a code generation report that you can use to debug your MATLAB code
and verify that it is suitable for code generation.
Best Practice — Generating a Code Generation Report
Contents of Build File build01.m
At the MATLAB command prompt, enter:
build01
codegen
runs
and generates a MEX function euclidean03_mex
in
the current folder. You are ready to test the MEX function euclidean03_mex
.
Using the Test Script test01.m. You use the test script test01.m
to test
the MEX function euclidean03_mex
.
The test script:
Loads the test data from the file euclidean.mat
.
Runs the original MATLAB file euclidean03.m
and
plots the distances.
Runs the MEX function euclidean03_mex
and
plots the distances.
Contents of Test Script test01.m
Running the Test Script. At the MATLAB command prompt, enter:
test01
The test file runs, plots the lines from x1
to
each vector in cb
, and outputs:
Running MATLAB function euclidean03 y = 0.8 0.8 0.4 idx = 171 distance = 0.080374 Running MEX function euclidean03_mex y = 0.8 0.8 0.4 idx = 171 distance = 0.080374
You are now ready to begin the next task in this tutorial, Modifying the Algorithm to Accept Variable-Size Inputs.
Why Modify the Algorithm?. The algorithm you have used so far in this tutorial is suitable
only to process inputs whose dimensions match the dimensions of the
example inputs provided using the -args
option.
In this part of the tutorial, you run euclidean03_mex
to
see that it does not accept two-dimensional inputs. You then recompile
your code using two-dimensional example inputs and test the resulting
MEX function with the two-dimensional inputs.
About the Build and Test Scripts
Running the Build and Test Scripts
Run the test script test02.m
to
test euclidean03x
with two-dimensional inputs.
test02
MATLAB reports an error indicating that the MEX function
does not accept two-dimensional variables for the input cb
.
MATLAB expression 'x' is not of the correct size: expected [3x1] found [2x1]. Error in ==> euclidean03
To process two-dimensional inputs, you must recompile your code providing two-dimensional example inputs.
Run the build file build02.m
to
recompile euclidean03.m
with two-dimensional inputs.
build02
codegen
compiles
the file and generates a MEX function euclidean03_2d
in
the current folder.Run the test file test03.m
to run
the resulting MEX function euclidean03_2d
with
two-dimensional inputs.
At the MATLAB command prompt, enter:
test03
y
in
matrix cb
that is closest to x2d
in
two dimensions.Running new 2-D version of MEX function y = 0 0.4 idx = 3 distance = 0.053094
This part of the tutorial demonstrates how to create MEX functions to handle inputs with different dimensions. Using this approach, you would need a library of MEX functions, each one suitable only for inputs with specified data types, dimensions, and complexity. Alternatively, you can modify your code to accept variable-size inputs. To learn how, see Specifying Variable-Size Inputs.
Specifying Variable-Size Inputs. The original MATLAB function is suitable for many different
size inputs. To provide this same flexibility in your generated C
code, use coder.typeof
with the codegen
-args
command-line
option.
coder.typeof(a,b,1)
specifies a variable-size
input with the same class and complexity as a
and
same size and upper bounds as the size vector b
.
For more information, see Specify Variable-Size Inputs at the Command Line.
Compile this code using the build file build03.m
.
This build file uses coder.typeof
to specify variable-size
inputs to the euclidean03
function.
build03
codegen
compiles the file without warnings
or errors and generates a MEX function euclidean03_varsizex
in
the current folder.
Run the resulting MEX function with two-dimensional
and then three-dimensional inputs using the test file test04.m
.
At the MATLAB command prompt, enter:
test04
The test file runs and outputs:
Running euclidean03_varsizex with 2-D inputs y = 0 0.4 idx = 3 distance = 0.053094 Running euclidean04_varsizex with 3-D inputs y = 0.6 0.8 0.2 idx = 134 distance = 0.053631
In this part of the tutorial, you modify the algorithm to compute
only the distance between the first N
elements
of a given vector x
and the first N
elements
of every column vector in the matrix cb
.
To modify the Euclidean minimum distance algorithm, euclidean03.m
,
to accommodate changes in dimensions over which to compute the distances:
Provide a new input parameter, N
,
to specify the number of elements to consider. The new function signature
is:
function [y,idx,distance] = euclidean03(x,cb,N)
Specify an upper bound for the variable N
using assert
.
Add this line after the function declaration.
assert(N<=3);
The value of the upper bound must correspond to the maximum
number of dimensions of matrix cb
. If you do not
specify an upper bound, an array bounds error occurs if you run the
MEX function with a value for N
that exceeds the
number of dimensions of matrix cb
. For more information,
see Specifying Upper Bounds for Variable-Size Data.
Modify the line of code that calculates the initial
distance to use N
. Replace the line:
distance=norm(x-cb(:,1));
distance=norm(x(1:N)-cb(1:N,1));
Modify the line of code that calculates each successive
distance to use N
. Replace the line:
d=norm(x-cb(:,index));
d=norm(x(1:N)-cb(1:N,index));
Change the function name to euclidean04
and
save the file as euclidean04.m
in the current folder.
Compile this code using the build file build04.m
.
At the MATLAB command prompt, enter:
build04
codegen
compiles the file without warnings
or errors and generates a MEX function euclidean04x
in
the current folder.
Run the resulting MEX function to process the first
two elements of the inputs x
and cb
,
then to process all three elements
of these inputs. Use the test file test05.m
.
At the MATLAB command prompt, enter:
test05
The test file runs and outputs:
Running euclidean04_mex for first two elements of inputs x and cb y = 0.8 0.8 0 idx = 169 distance = 0.078672 Running eucidean04_mex for three elements of inputs x and cb y = 0.8 0.8 0.4 idx = 171 distance = 0.080374
Back up your MATLAB code before you modify it.
Decide on a naming convention for your files and save interim versions frequently. For example, this tutorial uses a two-digit suffix to differentiate the various versions of the filter algorithm.
Use build scripts to build your files.
Use test scripts to separate the pre- and post-processing from the core algorithm.
Use the -args
option to specify
input parameters at the command line.
Use the MATLAB assert
function
to specify the upper bounds of variable-size data.
Use the -report
option to create
a code generation report.
Use coder.typeof(a,b,1)
to specify
variable-size inputs.
To... | See... |
---|---|
Learn how to generate C code from your MATLAB code | |
Learn how to integrate your MATLAB code with Simulink® models | |
Learn more about using code generation from MATLAB | |
Use variable-size data | |
Speed up fixed-point MATLAB code | |
Integrate custom C code into MATLAB code and generate embeddable code | |
Integrate custom C code into a MATLAB function | |
Generate HDL from MATLAB code |
MathWorks product documentation is available online from the Help menu on the MATLAB desktop.
For additional information and support, visit the MATLAB Coder page on the MathWorks website at: