Quantcast

Documentation Center

  • Trial Software
  • Product Updates

Define Variable-Size Data for Code Generation

When to Define Variable-Size Data Explicitly

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:

MethodSee
Assign the data from a variable-size matrix constructor such asUsing 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 sizedDefining Variable-Size Data Explicitly Using coder.varsize

Using a Matrix Constructor with Nonconstant Dimensions

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

Inferring Variable Size from Multiple Assignments

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.

Inferring Upper Bounds from Multiple Definitions with Different Shapes

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:

Defining Variable-Size Data Explicitly Using coder.varsize

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.

Specifying Which Dimensions Vary

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.

Allowing a Variable to Grow After Defining Fixed Dimensions

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.

Defining Variable-Size Matrices with Singleton Dimensions

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.

Defining Variable-Size Structure Fields

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.

Was this topic helpful?