For code generation, you must assign variables to have a specific class, size, and complexity before using them in operations or returning them as outputs. Generally, you cannot reassign variable properties after the initial assignment. Therefore, attempts to grow a variable or structure field after assigning it a fixed size might cause a compilation error. In these cases, you must explicitly define the data as variable sized using one of these methods:
Method | See |
---|---|
Assign the data from a variable-size matrix constructor such as | Using a Matrix Constructor with Nonconstant Dimensions |
Assign multiple, constant sizes to the same variable before using (reading) the variable. | Inferring Variable Size from Multiple Assignments |
Define all instances of a variable to be variable sized | Defining Variable-Size Data Explicitly Using coder.varsize |
You can define a variable-size matrix by using a constructor with nonconstant dimensions. For example:
function y = var_by_assign(u) %#codegen if (u > 0) y = ones(3,u); else y = zeros(3,1); end
assert
statement to provide
upper bounds for the dimensions. For example:function y = var_by_assign(u) %#codegen assert (u < 20); if (u > 0) y = ones(3,u); else y = zeros(3,1); end
You can define variable-size data by assigning multiple, constant sizes to the same variable before you use (read) the variable in your code. When MATLAB® uses static allocation on the stack for code generation, it 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, MATLAB assumes that the dimension is fixed at that size. The assignments can specify different shapes as well as sizes.
When dynamic memory allocation is used, MATLAB does not check for upper bounds; it assumes variable-size data is unbounded.
function y = var_by_multiassign(u) %#codegen if (u > 0) y = ones(3,4,5); else y = zeros(3,1); end
When static allocation is used, this 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 code generation report represents the size of matrix y
like
this:
When dynamic allocation is used,
the function analyzes the dimensions of y
differently:
First dimension is fixed at size 3
Second and third dimensions are unbounded
In this case, the code generation report represents
the size of matrix y
like this:
Use the function coder.varsize
to define
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:
Define B
as a variable-size 2-by-2
matrix, where each dimension has an upper bound of 64:
coder.varsize('B', [64 64]);
Define B
as a variable-size matrix:
coder.varsize('B');
When you supply only the first argument, coder.varsize
assumes
all dimensions of B
can
vary and that the upper bound is size(B)
.
For more information, see the coder.varsize
reference
page.
You can use the function coder.varsize
to
specify which dimensions vary. For example, the following statement
defines B
as a row vector whose first dimension
is fixed at 2, but whose second dimension can grow to an upper bound
of 16:
coder.varsize('B',[2, 16],[0 1])
false
have
fixed size; dimensions that correspond to ones or true
vary
in size. coder.varsize
usually treats dimensions
of size 1 as fixed (see Defining Variable-Size Matrices with Singleton Dimensions). For more information about the syntax, see the coder.varsize
reference
page.
Function var_by_if
defines matrix Y
with
fixed 2-by-2 dimensions before first use (where the statement Y
= Y + u
reads from Y
). However, coder.varsize
defines 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) %#codegen if (u > 0) Y = zeros(2,2); coder.varsize('Y'); if (u < 10) Y = Y + u; end else Y = zeros(5,5); end
Without coder.varsize
, MATLAB infers Y
to
be a fixed-size, 2-by-2 matrix and generates a size mismatch error
during code generation.
A singleton dimension is a 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 coder.varsize
expressions.
For example, in this function, Y
behaves
like a vector with one variable-size dimension:
function Y = dim_singleton(u) %#codegen Y = [1 2]; coder.varsize('Y', [1 10]); if (u > 0) Y = [Y 3]; else Y = [Y u]; end
You 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) %#codegen Y = ones(1,3); X = [1 4]; coder.varsize('Y','X'); if (u > 0) Y = [Y u]; else X = [X u]; end
You can override this behavior by using coder.varsize
to
specify explicitly that singleton dimensions vary. For example:
function Y = dim_singleton_vary(u) %#codegen Y = [1 2]; coder.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 coder.varsize
is
a vector of ones, indicating that each dimension of Y
varies
in size. For more information, see the coder.varsize
reference
page.
To define 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() %#codegen d = struct('values', zeros(1,0), 'color', 0); data = repmat(d, [3 3]); coder.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; end
The expression coder.varsize('data(:).values')
defines
the field values
inside each element of matrix data
to
be variable sized.
Here are other examples:
coder.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
.
coder.varsize('data(:).A(:).B')
This expression defines field B
inside each
element of matrix A
inside each element of matrix data
to
be variable sized.