Define Variable-Size Data for Code Generation
For code generation, before using variables in operations or returning them as outputs, you must assign them a specific class, size, and complexity. Generally, after the initial assignment, you cannot reassign variable properties. Therefore, after assigning a fixed size to a variable or structure field, attempts to grow the variable or structure field might cause a compilation error. In these cases, you must explicitly define the data as variable-size by using one of these methods.
Assign the data from a variable-size matrix constructor such as:
|Use a Matrix Constructor with Nonconstant Dimensions|
|Assign multiple, constant sizes to the same variable before using (reading) the variable.||Assign Multiple Sizes to the Same Variable|
|Grow an array by using ||Growing an Array by Using (end + 1)|
|Define all instances of a variable to be variable-size.||Define Variable-Size Data Explicitly by Using coder.varsize|
Use a Matrix Constructor with Nonconstant Dimensions
You can define a variable-size matrix by using a constructor with nonconstant dimensions. For example:
function s = var_by_assign(u) %#codegen y = ones(3,u); s = numel(y);
If you are not using dynamic memory allocation, you must also add an
assert statement to provide upper bounds for the
function s = var_by_assign(u) %#codegen assert (u < 20); y = ones(3,u); s = numel(y);
Assign Multiple Sizes to the Same Variable
Before you use (read) a variable in your code, you can make it variable-size by assigning multiple, constant sizes to it. When the code generator uses static allocation on the stack, 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, the code generator assumes that the dimension is fixed at that size. The assignments can specify different shapes and sizes.
When the code generator uses dynamic memory allocation, it does not check for upper bounds. It assumes that the variable-size data is unbounded.
Inferring Upper Bounds from Multiple Definitions with Different Shapes
function s = var_by_multiassign(u) %#codegen if (u > 0) y = ones(3,4,5); else y = zeros(3,1); end s = numel(y);
When the code generator uses static allocation, it infers that
y is a matrix with three dimensions:
The first dimension is fixed at size 3
The second dimension is variable-size with an upper bound of 4
The third dimension is variable-size with an upper bound of 5
When the code generator uses dynamic allocation, it analyzes the dimensions of
The first dimension is fixed at size 3.
The second and third dimensions are unbounded.
Growing an Array by Using (end + 1)
To grow an array
X, you can assign a value to
1). If you make this assignment in your MATLAB® code, the code generator treats the dimension you grow as
For example, you can generate code for this code snippet:
... a = [1 2 3 4 5 6]; a(end + 1) = 7; b = [1 2]; for i = 3:10 b(end + 1) = i; end ...
When you use
(end + 1) to grow an array, follow these
(end + 1). Do not use
(end + 2),
(end + 3), and so on.
(end + 1)with vectors only. For example, the following code is not allowed because
Xis a matrix, not a vector.
... X = [1 2; 3 4]; X(end + 1) = 5; ...
You can grow empty arrays of size
(end + 1). Growing arrays of size
0x1is not supported. Growing an array of size
0x0is supported only if you create that array by using
Define Variable-Size Data Explicitly by Using coder.varsize
To explicitly define variable-size data, use the function
coder.varsize. Optionally, you can
also specify which dimensions vary along with their upper bounds. For example:
Bas a variable-size 2-dimensional array, where each dimension has an upper bound of 64.
coder.varsize('B', [64 64]);
Bas a variable-size array:
When you supply only the first argument,
coder.varsizeassumes that all dimensions of
Bcan vary and that the upper bound is
Specify Which Dimensions Vary
You can use the function
coder.varsize to specify which
dimensions vary. For example, the following statement defines
B as an array whose first dimension is fixed at 2, but
whose second dimension can grow to a size of
coder.varsize('B',[2, 16],[0 1])
The third argument specifies which dimensions vary. This argument 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.
coder.varsize usually treats dimensions of size 1 as
fixed. See Define Variable-Size Matrices with Singleton Dimensions.
Allow a Variable to Grow After Defining Fixed Dimensions
var_by_if defines matrix
fixed 2-by-2 dimensions before the first use (where the statement
Y = Y
+ u reads from
Y as a
variable-size matrix, allowing it to change size based on decision logic in the
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
coder.varsize, the code generator infers
Y to be a fixed-size, 2-by-2 matrix. It generates a size
Define Variable-Size Matrices with Singleton Dimensions
A singleton dimension is a dimension for which
= 1. Singleton dimensions are fixed in size when:
You specify a dimension with an upper bound of 1 in
For example, in this function,
Ybehaves 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 by using matrix constructor expressions or matrix functions.
For example, in this function,
Ybehave like vectors where only their second dimensions are variable-size.
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
specify explicitly that singleton dimensions vary. For
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
Define Variable-Size Structure Fields
To define structure fields as variable-size arrays, use a colon
:) as the index expression. The colon
:) indicates that all
elements of the array are variable-size. 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
coder.varsize('data(:).values') defines the
values inside each element of matrix
data to be variable-size.
Here are other examples:
In this example,
datais a scalar variable that contains matrix
A. Each element of matrix
Acontains a variable-size field
This expression defines field
Binside each element of matrix
Ainside each element of matrix
datato be variable-size.