Documentation |
On this page… |
---|
When to Define Variable-Size Data Explicitly Using a Matrix Constructor with Nonconstant Dimensions |
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 code in a MATLAB Function block, you must also add an 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.
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:
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])
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 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.