Main Content

诊断并修复可变大小数据错误

诊断并修复大小不匹配错误

问题:将可变大小矩阵赋给固定大小矩阵

在生成的代码中,不能将可变大小矩阵赋给固定大小矩阵。请参考如下示例:

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;

编译此函数会产生以下错误:

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

可通过几种方法修复此错误:

  • 通过添加 coder.varsize 构造,允许矩阵 A 增大:

    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;

  • 通过修改 assert 语句,将矩阵 B 的大小显式限制为 3×3:

    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;
  • 使用显式索引使 BA 大小相同:

    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;

问题:空矩阵经过重构以匹配可变大小设定

如果您将空矩阵 [] 赋给可变大小数据,MATLAB® 可能会在生成的代码中以静默方式重构数据以匹配 coder.varsize 设定。例如:

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

在此示例中,coder.varsizeY 定义为最多 10 个元素的列向量,因此其第一个维度大小固定为 1。语句 Y = []Y 的第一个维度指定为 0,从而导致不匹配。赋值的右侧是空矩阵,左侧是可变大小向量。在这种情况下,MATLAB 将生成的代码中的空矩阵 Y = [] 重构为 Y = zeros(1,0),以使其匹配 coder.varsize 设定。

问题:将隐式扩展的输出赋给固定大小变量

如果将二元运算或函数的隐式扩展输出赋给不同大小的变量,代码生成器可能会生成错误。例如:

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

在此示例中,x 是无界向量。由于隐式扩展,对 xy 的加法运算会产生无界矩阵 (Inf×Inf)。将无界矩阵赋给无界向量 x 会导致错误。

如果要使用隐式扩展的输出,请将输出赋给与输出大小相同的新变量。

如果您需要 x 保持其大小,并且不在生成的代码中应用隐式扩展,请使用 coder.sameSizeBinaryOp (MATLAB Coder) 来应用该运算。您还可以在函数体中调用 coder.noImplicitExpansionInFunction (MATLAB Coder),以禁用为该函数生成的代码中的隐式扩展。

隐式扩展自动扩展操作数,以便对兼容大小的数组应用二元运算。请参阅Generate Code With Implicit Expansion Enabled (MATLAB Coder)Optimize Implicit Expansion in Generated Code (MATLAB Coder)基本运算的兼容数组大小

诊断并修复上界检测中的错误

问题:在矩阵构造函数中使用非常量维度

您可以通过将变量赋给具有非常量维度的矩阵定义可变大小数据。例如:

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

但是,编译此函数会生成错误,因为您没有为 u 指定上界。

要修复此问题,请在第一次使用 u 之前添加一条 assert 语句:

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