Main Content

Diagnose and Fix Variable-Size Data Errors

Diagnosing and Fixing Size Mismatch Errors

Issue: Assigning Variable-Size Matrices to Fixed-Size Matrices

You cannot assign variable-size matrices to fixed-size matrices in generated code. Consider this example:

function Y = example_mismatch1(n) %#codegen
assert(n < 10);
B = ones(n,n);
A = magic(3);
A(1) = mean(A(:));
if (n == 3)
    A = B;
end
Y = A;

Compiling this function produces this error:

??? Dimension 1 is fixed on the left-hand side 
but varies on the right ...

There are several ways to fix this error:

  • Allow matrix A to grow by adding the coder.varsize construct:

    function Y = example_mismatch1_fix1(n) %#codegen
    coder.varsize('A');
    assert(n < 10);
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B;
    end
    Y = A;

  • Explicitly restrict the size of matrix B to 3-by-3 by modifying the assert statement:

    function Y = example_mismatch1_fix2(n) %#codegen
    coder.varsize('A');
    assert(n == 3)
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B;
    end
    Y = A;
  • Use explicit indexing to make B the same size as A:

    function Y = example_mismatch1_fix3(n) %#codegen
    assert(n < 10);
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B(1:3, 1:3);
    end
    Y = A;

Issue: Empty Matrix Reshaped to Match Variable-Size Specification

If you assign an empty matrix [] to variable-size data, MATLAB® might silently reshape the data in generated code to match a coder.varsize specification. For example:

function Y = test(u) %#codegen
Y = [];
coder.varsize('Y', [1 10]);
if u < 0
    Y = [Y u];
end

In this example, coder.varsize defines Y as a column vector of up to 10 elements, so its first dimension is fixed at size 1. The statement Y = [] designates the first dimension of Y as 0, creating a mismatch. The right hand side of the assignment is an empty matrix and the left hand side is a variable-size vector. In this case, MATLAB reshapes the empty matrix Y = [] in generated code to Y = zeros(1,0) so it matches the coder.varsize specification.

Issue: Assigning Implicitly Expanded Outputs to Fixed-Size Variable

If you assign the implicitly expanded output of a binary operation or function to a variable of different size, the code generator might produce an error. For example:

function out = test(n) %#codegen
x = ones(n,1);
if mod(n,2) == 1
	y = ones(n,n);
	x = y + x;
end 
out = out + x(2);
end

In this example, x is an unbounded vector. Due to implicit expansion, the plus operation on x and y results in an unbounded matrix (Inf-by-Inf). Assigning an unbounded matrix to x, which is an unbounded vector, results in an error.

If you want to use the implicitly expanded output, assign the output to a new variable with the same size as the output.

If you want x to retain its size and not apply implicit expansion in the generated code, use coder.sameSizeBinaryOp to apply the operation. You can also call coder.noImplicitExpansionInFunction in your function body to disable implicit expansion in the code generated for that function.

Implicit expansion automatically expands the operands to apply binary operations on arrays of compatible sizes. See Generate Code With Implicit Expansion Enabled, Optimize Implicit Expansion in Generated Code, and Compatible Array Sizes for Basic Operations.

Diagnosing and Fixing Errors in Detecting Upper Bounds

Issue: Using Nonconstant Dimensions in a Matrix Constructor

If you enable dynamic memory allocation, you can define variable-size data by assigning a variable to a matrix with nonconstant dimensions. For example:

function y = dims_vary(u) %#codegen
if (u > 0)
    y = ones(3,u);
else
    y = zeros(3,1);
end

By default, dynamic memory allocation is enabled for variable-size arrays whose size is greater than or equal to a configurable threshold. See Generate Code for Variable-Size Data.

If you disable dynamic memory allocation, code generation for this function errors. If you do not want to use dynamic memory allocation, you can define a variable-size array with a fixed upper bound by using an assert statement. For example:

function y = dims_vary_fix(u) %#codegen
assert (u < 20);
if (u > 0)
    y = ones(3,u);
else
    y = zeros(3,1);
end