主要内容

解决错误:左侧是固定大小,而右侧是可变大小

问题

对于代码生成,变量或者为固定大小,或者为可变大小。如果代码生成器可以确定变量的大小不会更改,它会在生成的代码中固定该变量的大小。否则,它允许变量更改大小。如果将可变大小的值赋给代码生成器先前定义为固定大小的变量,代码生成器会生成以下错误之一:

Unable to make this assignment because dimension dimension is fixed size on the left side but variable size on the right(无法进行此赋值,因为维度 dimension 左侧是固定大小,而右侧是可变大小)

Unable to make this assignment because dimension dimension in element 'element' is fixed size on the left side but variable size on the right(无法进行此赋值,因为元素 'element' 中的维度 dimension 左侧是固定大小,而右侧是可变大小)

Unable to make this assignment because dimension dimension in field 'field' is fixed size on the left side but variable size on the right(无法进行此赋值,因为字段 'field' 中的维度 dimension 左侧是固定大小,而右侧是可变大小)

可能的解决方案

要解决此错误,请尝试以下解决办法之一。

通过使用显式索引强制变量具有相同大小

如果不需要右侧的变量是可变大小,您可以通过使用显式索引强制该变量为固定大小。例如,假设您有一个定义变量 AB 的函数。A 是可变大小的标量,B 是固定大小的标量。代码生成失败,因为该函数尝试将可变大小的变量 A 赋给固定大小的变量 B

function out = varsizeError2(n) %#codegen
coder.varsize("A",[1 1],[true true]);
A = ones(n,n);
B = 3;
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

要为此函数生成代码,请使用显式索引强制 A 为固定大小的标量。

function out = varsizeExample2(n) %#codegen
coder.varsize("A",[1 1],[true true]);
A = ones(n,n);
B = 3;
numel(B);
if (n == 3)
    B = A(1);
end
out = B;
end

通过使用 coder.varsize 允许左侧的变量变化

使用 coder.varsize (MATLAB Coder) 指示代码生成器将赋值左侧的变量视为可变大小。以如下函数为例:

function out = varsizeError1(n) %#codegen
A = ones(n,n);
B = magic(3);
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

代码生成器将数组 A 识别为可变大小,因为 A 的大小取决于输入值。代码生成器将 B 识别为固定大小,因为当代码通过将 B 传递给 numel 函数来使用它时,此数组的大小是恒定的。代码生成在进行赋值 B = A 时失败,因为 A 是可变大小,而 B 是固定大小。要解决此错误,请使用 coder.varsize 指示代码生成器允许 B 的大小变化。

function out = varsizeExample1(n) %#codegen
A = ones(n,n);
B = magic(3);
coder.varsize("B");
numel(B);
if (n == 3)
    B = A;
end
out = B;
end

防止隐式扩展

在对大小不同但兼容的数组执行二元运算时,代码生成器会隐式扩展数组,使它们具有相同的大小。如果将二元运算或函数的隐式扩展输出赋给不同大小的固定大小变量,代码生成器可能会生成错误。以如下函数为例:

function out = varsizeError3(n) %#codegen
A = ones(n,1);
B = ones(n,n);
if n == 1
    A = A+B;
end
out = A;
end

数组 A 的第二个维度是固定大小。要执行运算 A+B,代码生成器会隐式扩展 A 的第二个维度以匹配 B 的第二个维度。A+B 的结果是一个在两个维度上均为可变大小的数组。代码生成失败,因为代码生成器无法将第二个维度为可变大小的变量赋给第二个维度为固定大小的变量。在此示例中,运算 A+B 仅在两个数组均为 1×1 时执行。因此,您可以通过使用 coder.noImplicitExpansionInFunction (MATLAB Coder) 对此函数禁用隐式扩展,或通过使用 coder.sameSizeBinaryOp (MATLAB Coder) 对此运算禁用隐式扩展。例如:

function out = varsizeExample3(n) %#codegen
coder.noImplicitExpansionInFunction
A = ones(n,1);
B = ones(n,n);
if n == 1
    A = A+B;
end
out = A;
end

另请参阅

(MATLAB Coder) | (MATLAB Coder) | (MATLAB Coder)

主题