| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Embedded MATLAB |
| Contents | Index |
Variable-size data is data whose size may change at run time. By contrast, fixed-size data is data whose size is known and locked at compile time, and therefore cannot change at run time.
For example, in the following MATLAB function nway, B is a variable-size array. It grows in size as it adds new values in the for-loop.
function B = nway(A,n)
% Compute average of every N elements of A and put them in B.
if ((mod(numel(A),n) == 0) && (n>=1 && n<=numel(A)))
B = ones(1,numel(A)/n);
k = 1;
for i = 1 : numel(A)/n
B(i) = mean(A(k + (0:n-1)));
k = k + n;
end
else
error('n <= 0 or does not divide number of elements evenly');
endIn the MATLAB language, all data can vary in size. By contrast, the Embedded MATLAB subset imposes restrictions on data:
Constrains the class, complexity, and shape of every expression,
variable, and structure field.
Requires variable-size matrices and arrays to have fixed upper
bounds.
Support for variable-size data is a configuration parameter. It is enabled by default for MEX and C code generation.
Configuring Variable-Size Support for MEX Code Generation with emlmex
Configuring Variable-Size Support for Code Generation with emlc
Configuring Variable-Size Support for Embedded MATLAB Function Blocks
Define the MEX compiler configuration object in the MATLAB workspace. For example:
comp_cfg = emlcoder.CompilerOptions
Modify the variable sizing parameter:
To disable variable sizing:
comp_cfg.EnableVariableSizing = false
To enable variable sizing:
comp_cfg.EnableVariableSizing = true
You can also modify this parameter using the Compiler Options dialog box. SeeSetting C-MEX Compilation Options.
Invoke emlmex with the -s option and specify the configuration object as its argument. For example:
emlmex -s comp_cfg myMfile
For complete details about this command and its options, see the emlmex reference page.
emlc requires a Real-Time Workshop license.
Define a compiler configuration object for the desired code generation target in the MATLAB workspace. For example:
| For: | Define: |
|---|---|
| Generating MEX code | codegencfg = emlcoder.MEXConfig |
| Generating embeddable C code for a GRT-based target | codegencfg = emlcoder.RTWConfig('grt') |
| Generating embeddable C code for an ERT-based target | codegencfg = emlcoder.RTWConfig('ert') |
Modify the variable sizing parameter:
To disable variable sizing:
codegencfg.EnableVariableSizing = false
To enable variable sizing:
codegencfg.EnableVariableSizing = true
You can also modify this parameter using dialog boxes. See Configuring Your Environment for Code Generation in the Real-Time Workshop documentation.
Invoke emlc with the -s option and specify the configuration object as its argument. For example:
emlc -s codegencfg myMfile
For complete details about this command and its options, see the emlc reference page in the Real-Time Workshop documentation.
See Enabling Support for Variable-Size Data in the Simulink user guide documentation.
Follow these steps:
To walk through these steps with a simple example, see Tutorial: Generate Code for a MATLAB Function that Expands a Vector in a Loop
Add the compilation directive %#eml at the top of your MATLAB function. For example:
function y = copyN(N, P) %#eml
X = zeros(1, 0);
for i = 1:N
X = [X P(i)];
end
y = X;In this example, %#eml declares the function copyN to be Embedded MATLAB compliant. When you add this directive, M-Lint alerts you about use of variable-size data for the Embedded MATLAB subset. See Analyzing Your Code for Variable-Size Data.
After declaring your MATLAB function to be compliant with the Embedded MATLAB subset, check your code for intentional occurrences of variable-size data. M-Lint and emlmex compilation reports detect variables and structure fields that change size after they are defined. To allow this behavior, modify your code to use the appropriate Embedded MATLAB constructs, as described in Declaring Variable-Size Data in Embedded MATLAB Code.
At design time, M-Lint alerts you when it detects data that may change in size after it is defined. Here is an example, which flags matrix X as variable-size data:

If you intend the flagged data to vary in size, ignore this warning. If you do not want the flagged data to vary in size, click on the warning message and follow the instructions.
Optionally, you can suppress the M-Lint warning:
Right-click the highlighted variable.
Select Suppress this instance of ....
M-Lint adds the directive %#ok<AGROW> to the end of the line and removes the warning:

Generate a report by compiling your Embedded MATLAB compliant function with emlmex and the -report option. (You can also use emlc if you have a Real-Time Workshop license.)
You may get the following types of compilation errors related to use of variable-size data in Embedded MATLAB code:
| Error | Occurs when Embedded MATLAB technology | How to fix |
|---|---|---|
| Size mismatch | Assumes you are trying to change the size of fixed-size data after an assignment locks its value | SeeDiagnosing and Fixing Size Mismatch Errors |
| Computed maximum size is not bounded | Cannot compute an upper bound for variable-size data | See Diagnosing and Fixing Errors in Detecting Upper Bounds |
Embedded MATLAB compilation reports:
Differentiate fixed-size from variable-size data
Identify variable-size data with unknown upper bounds

For more information, see Working with Compilation Reports.
You can represent variables and structure fields as variable-sized data in Embedded MATLAB code.
Use the function eml.varsize to declare one or more variables or structure fields as variable-size data. Optionally, you can also specify which dimensions vary along with their upper bounds (see Specifying Which Dimensions Vary). For example:
Declare B as a variable-size 2-by-2 matrix, where each dimension has an upper bound of 64:
eml.varsize('B', [64 64]);Declare B as a variable-size matrix:
eml.varsize('B');When you supply only the first argument, eml.varsize assumes all dimensions of B can vary.
For more information, see the eml.varsize reference page.
Example: Allow variable to grow after defining fixed dimensions. Function var_by_if defines matrix Y with fixed 2-by-2 dimensions before first use (where it is read in the statement Y = Y + u). However, eml.varsize declares Y as a variable-size matrix, allowing it to change size based on decision logic in the else clause:
function Y = var_by_if(u) %#eml
if (u > 0)
Y = zeros(2,2);
eml.varsize('Y');
Y = Y + u;
else
Y = zeros(5,5);
endWithout eml.varsize, Embedded MATLAB technology infers Y to be a fixed-size, 2-by-2 matrix and generates a size mismatch error:

Use the function eml.varsize to specify which dimensions vary. For example, the following statement declares B as a row vector whose first dimension is fixed at 2, but whose second dimension can grow to an upper bound of 16:
eml.varsize('B', [2, 16], [0 1])The third argument specifies which dimensions vary. It must be a logical vector or a double vector containing only zeros and ones. Dimensions that correspond to zeros or false have fixed size; dimensions that correspond to ones or true vary in size.eml.varsize usually treats dimensions of size 1 as fixed (see Declaring Variable-Size Matrices with Singleton Dimensions).
For more information about the syntax, see the eml.varsize reference page.
Using a Matrix Constructor with Non-Constant Dimensions. You can declare a variable-size matrix by using a constructor with non-constant dimensions. However, you must also use an assert statement to provide upper bounds for the dimensions. For example:
function y = var_by_assign(u) %#eml assert (u < 20); if (u > 0) y = ones(3,u); else y = zeros(3,1); end
This Embedded MATLAB function infers that y is a variable-size matrix with an upper bound of 20. However, if you do not include the assert statement, you get this compiler error:
??? Computed maximum size is not bounded. Static memory allocation requires all sizes to be bounded. The computed size is [3 x :?]
You can declare variable-size data by assigning multiple, constant sizes to the same variable before you use (read) the variable in your code. Embedded MATLAB infers the upper bounds from the largest size specified for each dimension. When you assign the same size to a given dimension across all assignments, Embedded MATLAB assumes the dimension is fixed at that size. The assignments can specify different shapes as well as sizes.
Example: Infer upper bounds from multiple definitions with different shapes.
function y = var_by_multiassign(u) %#eml if (u > 0) y = ones(3,4,5); else y = zeros(3,1); end
This Embedded MATLAB function infers that y is a matrix with three dimensions, where:
First dimension is fixed at size 3
Second dimension is variable with an upper bound of 4
Third dimension is variable with an upper bound of 5
The compilation report represents the size of matrix y like this:

A singleton dimension is any dimension for which size(A,dim) = 1. Singleton dimensions are fixed in size when:
You specify a dimension with an upper bound of 1 in eml.varsize expressions
For example, in this function, Y behaves like a vector with one variable-size dimension:
function Y = dim_singleton(u) %#eml
Y = [1 2];
eml.varsize('Y', [1 10]);
if (u > 0)
Y = [Y 3];
else
Y = [Y u];
endYou initialize variable-size data with singleton dimensions using matrix constructor expressions or matrix functions
For example, in this function, both X and Y behave like vectors where only their second dimensions are variable sized:
function [X,Y] = dim_singleton_vects(u) %#eml
Y = ones(1,3);
X = [1 4];
eml.varsize('Y','X');
if (u > 0)
Y = [Y u];
else
X = [X u];
endYou can override this behavior by using eml.varsize to specify explicitly that singleton dimensions vary. For example:
function Y = dim_singleton_vary(u) %#eml
Y = [1 2];
eml.varsize('Y', [1 10], [1 1]);
if (u > 0)
Y = [Y Y+u];
else
Y = [Y Y*u];
end
In this example, the third argument of eml.varsize is a vector of ones, indicating that each dimension of Y varies in size. For more information, see the eml.varsize reference page.
To declare structure fields as variable-size arrays, use colon (:) as the index expression. The colon (:) indicates that all elements of the array are variable sized. For example:
function y=struct_example() %#eml
d = struct('values', zeros(1,0), 'color', 0);
data = repmat(d, [3 3]);
eml.varsize('data(:).values');
for i = 1:numel(data)
data(i).color = rand-0.5;
data(i).values = 1:i;
end
y = 0;
for i = 1:numel(data)
if data(i).color > 0
y = y + sum(data(i).values);
end;
endThe expression eml.varsize('data(:).values') declares that the field values inside each element of matrix data is variable sized.
Here are other examples:
eml.varsize('data.A(:).B')
In this example, data is a scalar variable that contains matrix A. Each element of matrix A contains a variable-size field B.
eml.varsize('data(:).A(:).B')
This expression declares that field B inside each element of matrix A inside each element of matrix data is variable sized.
Embedded MATLAB technology must be able to determine upper bounds for variable-size data. You must specify the upper bounds explicitly for variable-size data from external sources, such as inputs and outputs. For local data, Embedded MATLAB uses a sophisticated analysis to calculate the upper bounds at compile time. However, when the analysis fails to detect an upper bound or calculates an upper bound that is not precise enough for your application, you must specify upper bounds explicitly for local variables, too.
Use the declaration emlcoder.egs with the -eg option on the emlmex or emlc command line. For example:
emlmex foo -eg {emlcoder.egs(double(0),[3 100])}This command specifies that the input to function foo is a matrix with two variable dimensions. The upper bound for the first dimension is 3; the upper bound for the second dimension is 100. For a detailed explanation of emlcoder.egs syntax, see Specifying Variable-Size Inputs.
Constraining the value of a variable that specifies dimensions of variable-size data
Specifying the upper bounds for all instances of a local variable
Constraining the value of a variable that specifies dimensions of variable-size data. Use the assert function with relational operators to constrain the value of variables that specify the dimensions of variable-size data. For example:
function y = dim_need_bound(n) %#eml assert (n <= 5); L= ones(n,n); M = zeros(n,n); M = [L; M]; y = M;
This assert statement constrains input n to a maximum size of 5, thereby defining L and M as variable-sized matrices with upper bounds of 5 for each dimension.
Specifying the upper bounds for all instances of a local variable. Use the eml.varsize function to specify the upper bounds for all instances of a local variable in a function. For example:
function Y = example_bounds1(u) %#eml
Y = [1 2 3 4 5];
eml.varsize('Y', [1 10]);
if (u > 0)
Y = [Y Y+u];
else
Y = [Y Y*u];
endThe second argument of eml.varsize specifies the upper bound for each instance of the variable specified in the first argument. In this example, the argument [1 10] indicates that for every instance of Y, the first dimension is fixed at size 1 and the second dimension can grow to an upper bound of 10. (By default, eml.varsize assumes dimensions of 1 are fixed size.) For more information, see the eml.varsize reference page.
To generate MEX code, use the emlmex function. To generate C executable or library code, use the emlc function (requires a Real-Time Workshop license).
To specify variable-size inputs to the emlmex or emlc commands, use the emlcoder.egs construct with the -eg option, as described in Specifying Variable-Size Inputs. For example:
emlmex myFcn -eg {emlcoder.egs(0,[2 4])}This command specifies that there is one variable-size input for function myFcn. The input is a matrix of real doubles with two variable-size dimensions. The upper bound is 2 for the first dimension and 4 for the second dimension.
Step 1: Make MATLAB code compliant with the Embedded MATLAB subset
Step 3: Declare B as a variable-size vector using Embedded MATLAB extensions
The function uniquetol returns in vector B a version of input vector A, where the elements are unique to within tolerance tol of each other. In vector B, abs(B(i) - B(j)) > tol for all i and j. Input vector A can store up to 100 elements.
function B = uniquetol(A, tol)
A = sort(A);
B = A(i);
k = i;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endIn the MATLAB Editor, add the compilation directive %#eml:
function B = uniquetol(A, tol) %#eml
A = sort(A);
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endCheck for M-Lint messages. M-Lint detects that variable B may change size in the for-loop. It issues this warning:

In this function, vector B is supposed to expand in size as it adds values from vector A. Therefore, you can ignore this warning:
Check for compiler errors or warnings.
Generate a compilation report for function uniquetol using this command:
emlmex uniquetol -eg { emlcoder.egs(0,[1 100]), 0 } -report
What do these command-line options mean?
Executing this command generates a compiler error:
??? Size mismatch (size [1 x 1] ~= size [1 x 2]). The size to the left is the size of the left-hand side of the assignment. Error in ==> uniquetol Line: 10 Column: 9 C-MEX generation failed: Open error report. ??? Error using ==> emlmex
Open the error report.

The error indicates a size mismatch between the left hand side and right hand side of the assignment statement in line 10. The assignment B = A(1) in line 6 establishes the size of B as a fixed-size scalar (1 x 1). Therefore, the concatenation of [B A(i)] creates a 1 x 2 vector. To fix this error, declare B to be a variable-size vector. See Step 3: Declare B as a variable-size vector using Embedded MATLAB extensions.
Add this statement to the uniquetol function:
eml.varsize('B');It should appear before B is used (read). For example:
function B = uniquetol(A, tol) %#eml
A = sort(A);
eml.varsize('B');
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endThe function eml.varsize declares every instance of B in uniquetol to be variable sized.
Generate another compilation report using this command:
emlmex uniquetol -eg { emlcoder.egs(0,[1 100]), 0 } -reportThis time, the command generates a different compiler error:
??? CAT arguments dimensions are not consistent. The size of argument 1 is [:? x :?]. The size of argument 2 is [1 x 1]. Error in ==> uniquetol Line: 14 Column: 13 C-MEX generation failed: Open error report. ??? Error using ==> emlmex
Open the error report:

This error occurs because eml.varsize does not declare B as a vector. Instead, the compiler assumes B is a matrix with two varying dimensions ( :? x :?). When the uniquetol function attempts to concatenate the matrix B with the scalar A(i), the compiler issues the error.
To fix the problem, you must modify the eml.varsize statement to explicitly declare B as a vector with appropriate upper bounds. See Step 4: Specify B as a vector with upper bounds.
Add a second argument to eml.varsize:
eml.varsize('B', [1 100]);The argument [1 100] specifies that B is a vector with its first dimension fixed at size 1 and the second dimension variable to an upper bound of 100. The value of 100 matches the upper bound of variable-size vector A. Based on the algorithm, output B is at most as big as input A. By default, dimensions of 1 are fixed size.
Here is the modified code:
function B = uniquetol(A, tol) %#eml
A = sort(A);
eml.varsize('B', [1 100]);
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endGenerate another compilation report to be sure you have addressed all issues:
emlmex uniquetol -eg { emlcoder.egs(0,[1 100]), 0 } -reportThe code should compile without error. Now you are ready to generate code. See Step 5: Generate MEX or C Code for the uniquetol Function.
In prior steps, you used emlmex to generate compilation reports for flagging errors in representing variable-size data. Now that you have addressed these errors, you can generate MEX or C code from your Embedded MATLAB compliant uniquetol function.
To generate MEX code, use the emlmex command. Since input A is a variable-sized vector, be sure to use the emlcoder.egs construct with the -eg option. For example:
emlmex -o uniquetolx uniquetol -eg {emlcoder.egs(0,[1 100]),0} This command generates a MEX file with the root name uniquetolx in the current directory.
To generate C code, use the emlc command (requires a Real-Time Workshop license). For example, to generate C code for the uniquetol function. For example:
emlc -T rtw:lib -d ulib uniquetol -eg {emlcoder.egs(0,[1 100]),0}This command generates C library files in a custom folder ulib.
To make variable-size data persistent, declare them with the persistent statement and initialize them with the isempty clause, as described in Declaring Persistent Variables.
Check your code for these issues:
Assigning Variable-Size Matrices to Fixed-Size Matrices
Making Assignments Inconsistent with Variable-Size Specifications
Performing Binary Operations on Fixed and Variable-Size Operands
Check your code for these issues:
Using non-constant dimensions in a matrix constructor
Scalar expansion is a method of converting scalar data to match the dimensions of vector or matrix data. Embedded MATLAB applies the same scalar expansion rules as MATLAB code except when adding two variable-size expressions. In this case, Embedded MATLAB requires that both operands have the same size. It will not perform scalar expansion even if one of the variable-size expressions is scalar. Instead, it generates a size mismatch error at run time.
For example, the following Embedded MATLAB code applies the same scalar expansion rules as MATLAB:
function y = scalar_exp_test()%#eml
A = zeros(2,2);
eml.varsize('A');
B = 1;
y = A + B;It determines that B is scalar and adds it to the variable-size matrix A to produce this result:
ans =
1 1
1 1However, suppose B is also variable sized:
function y = scalar_exp_test_err1()%#eml
A = zeros(2,2);
eml.varsize('A','B');
B = 1;
y = A + B;In this case, the eml.varsize declaration obscures the fact that B is scalar. The function compiles without error using emlmex scalar_exp_test_err1 -report, but generates a run-time error:
??? Sizes mismatch: [2][2] ~= [1][1]
Workaround. To fix the problem, use indexing to force B to be a scalar value:
function y = scalar_exp_test_fix()%#eml
A = zeros(2,2);
eml.varsize('A','B');
B = 1;
y = A + B(1);For variable-size N-D arrays, the size function may return a different result in Embedded MATLAB than in MATLAB. In Embedded MATLAB, size(A) always returns a fixed-length output because it does not drop trailing singleton dimensions of variable-size N-D arrays. By contrast, size(A) in MATLAB returns a variable-length output because it drops trailing singleton dimensions.
For example, if the shape of array A is :?x:?x:? and size(A,3)==1, size(A) returns:
3-element vector in Embedded MATLAB code
2-element vector in MATLAB code
Workarounds. If your application requires Embedded MATLAB code to return the same size of variable-size N-D arrays as MATLAB code, consider one of these workarounds:
Use the two-argument form of size.
For example, size(A,n) always returns the same answer in Embedded MATLAB and MATLAB code.
Rewrite size(A):
B = size(A); X = B(1:ndims(A));
This version returns X with a variable-length output. However, you cannot pass a variable-size X to matrix constructors such as zeros which require a fixed-size argument.
In vector-vector indexing, you use one vector as an index into another vector. When either vector is variable sized, Embedded MATLAB may produce a run-time error in a specific situation. Consider the index expression A(B). The general rule for indexing is that size(A(B))== size(B) . However, when both A and B are vectors, MATLAB applies a special rule: use the orientation of A as the orientation of the output. For example, if size(A) == [1 5] and size(B) == [3 1] then size(A(B)) == [1 3].
In this situation, if Embedded MATLAB detects that both A and B are vectors at compile time, it applies the special rule and gives the same result as MATLAB. However, if either A or B is a variable-size matrix (has shape ?x?) at compile time, Embedded MATLAB applies only the general indexing rule. Then, if both A and B become vectors at run time, Embedded MATLAB reports a run-time error in simulation.
Workaround. Force your data to be a vector by using the colon operator for indexing: A(B(:)). For example, suppose your code intentionally toggles between vectors and regular matrices at run time. You can do an explicit check to provide deterministic behavior:
...
if isvector(A) && isvector(B)
C = A(:);
D = C(B(:));
else
D = A(B);
end
...The indexing in the first branch specifies that C and B(:) are compile-time vectors. As a result, Embedded MATLAB code will apply the MATLAB vector-vector indexing rule at run time.
The following types of restrictions apply to multiple Embedded MATLAB library functions:
Variable-length vector restriction. Inputs to the library function must be variable-length vectors or fixed-size vectors. A variable-length vector is a variable-size array that has the shape 1x:n or :nx1 (one dimension is variable sized and the other is fixed at size 1). Other shapes are not permitted, even if they are vectors at run time.
Automatic dimension restriction. When the function selects the working dimension automatically, it bases the selection on the upper bounds for the dimension sizes. In the case of the sum function, sum(X) selects its working dimension automatically, while sum(X, dim) uses dim as the explicit working dimension.
For example, if X is a variable-size matrix with dimensions 1x:3x:5, sum(x) behaves like sum(X,2) in Embedded MATLAB. In MATLAB, it behaves like sum(X,2) provided size(X,2) is not 1. In MATLAB, when size(X,2) is 1, sum(X) behaves like sum(X,3) . Consequently, you get a run-time error if an automatically selected working dimension assumes a length of 1 at run time.
To avoid the issue, specify the intended working dimension explicitly as a constant value.
Array-to-vector restriction. The function issues an error when a variable-size array that is not a variable-length vector assumes the shape of a vector at run time. To avoid the issue, specify the input explicitly as a variable-length vector instead of a variable-size array.
Array-to-scalar restriction. The function issues an error if a variable-size array assumes a scalar value at run time. To avoid this issue, specify all scalars as fixed size.
| Function | Restrictions with Variable-Size Data |
|---|---|
| all |
|
| any |
|
| bsxfun |
|
| cat |
|
| conv |
|
| cov |
|
| cross |
|
| deconv |
|
| detrend |
|
| diag | |
| diff |
|
| fft | |
| filter |
|
| hist |
|
| histc | |
| ifft | |
| ind2sub |
|
| interp1 |
|
| ipermute |
|
| issorted |
|
| magic |
|
| max | |
| mean |
|
| median |
|
| min | |
| mode |
|
| mtimes |
|
| nchoosek |
|
| permute |
|
| planerot |
|
| poly | |
| polyfit |
|
| prod |
|
| rand |
|
| randn |
|
| reshape |
|
| roots | |
| shiftdim |
|
| std |
|
| sub2ind |
|
| sum |
|
| trapz |
|
| typecast |
|
| var |
|
![]() | Calling Functions in the Embedded MATLAB Subset | Working with Enumerated Data | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |