主要内容

coder.varsize

解决大小不兼容性错误并声明上界

说明

coder.varsize(varName1,...,varNameN) 指示代码生成器允许变量 varName1,...,varNameN 的维度在运行时改变大小。代码生成器尝试确定每个变量的每个维度的上界。大小为 1 的维度,也称为单一维度,保持固定大小。要指示代码生成器允许单一维度改变大小,您必须使用 upperBoundsvariableSize 参量指定可变大小上界。有关在 MATLAB® 代码中定义可变大小数据以进行代码生成的详细信息,请参阅为代码生成定义可变大小数据

示例

coder.varsize(varName1,...,varNameN,upperBounds) 为变量 varName1,...,varNameN 的每个维度指定上界。单一维度保持固定大小。

示例

coder.varsize(varName1,...,varNameN,upperBounds,variableSize) 为在 upperBounds 中指定的每个上界指定该上界是固定大小还是可变大小。要指示代码生成器允许单一维度改变大小,请显式指定可变大小上界。

示例

示例

全部折叠

当代码生成器无法识别变量是否改变大小时,可能会生成大小不兼容性错误。要解决这些类型的错误,请使用 coder.varsize 来指定变量的大小可变。

例如,此函数将变量 x 定义为 3×3 数组,通过将变量 x 传递给另一个函数来使用它,然后根据运行时输入更改 x 的大小。

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

如果您为此函数生成代码,代码生成器会生成大小不兼容性错误。要解决此错误,请在定义该变量后、但在使用它之前添加 coder.varsize 指令。

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
coder.varsize("x");
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

在执行二元(两个数组)运算(如加法或乘法)时,代码生成器也可能生成大小不兼容性错误。请参阅解决错误:数组大小不兼容 (MATLAB Coder)

创建一个将 A 定义为标量的函数,然后使用 coder.varsize 指定 A 是可变大小的行向量,最大长度为 20。为此函数生成代码,并检查代码生成报告。A 定义为 1x:20 数组。当您不提供 variableSize 参量时,非单一维度定义为可变大小,而单一维度保持固定大小。

function varSizeUpperBounds() %#codegen
A = 0;
coder.varsize("A",[1 20]);
end

创建一个将 A 定义为 1×1×1 数组的函数,然后使用 coder.varsize 指定 A 的第一个维度是可变大小,最大值为 1;第二个维度是固定大小,值为 3;第三个维度是可变大小,最大值为 20。为此函数生成代码,并检查代码生成报告。A 定义为 :1x3x:20 数组。代码生成器将单一维度定义为可变大小,因为您使用 upperboundvariableSize 参量显式指定可变大小上界。

function fcn2() %#codegen
A = [0 0 0];
coder.varsize("A",[1 3 20],[true false true]);
end

您可以使用 coder.varsize 来指示代码生成器允许结构体字段改变大小。

例如,创建一个函数,该函数定义一个包含以下字段的结构体:observations1observations2values。使用 coder.varsizeobservations1observations2 定义为具有固定大小的第一个维度和无界的第二个维度。再次使用 coder.varsizevalues 定义为可变大小的行向量,最大长度为 10。为此函数生成代码,并检查代码生成报告。代码生成器能够确定 observation1observations2 的无界维度的最大大小。代码生成器将 observations1observations2values 分别定义为大小为 2x:102x:151x:10 的数组。

function out = varSizeFields(n) %#codegen
s = struct("observations1",zeros(2,2),"observations2",zeros(2,2), ...
    "values",zeros(1,1));
coder.varsize("s.observations1","s.observations2",[2 Inf],[false true]);
coder.varsize("s.values",[1 10]);
if n <= 10
    s.observations1 = [1:n;rand(1,n)];
    s.values = randi(100,1,n);
end
if n > 0
    s.observations2 = [1:15;zeros(1,15)];
end
out = s;
end

您可以将 coder.varsize 指令应用于所有元胞数组元素或特定元胞数组元素。

例如,创建一个定义两个 1×3 元胞数组的函数,每个元胞数组包含三个 1×2 双精度数组。使用 coder.varsize 指定元胞数组 ca1 的所有元素均为最大长度为 5 的可变大小行向量。再次使用 coder.varsize 指令指定 ca2 的第二个元素是大小可变的矩阵,两个维度的最大大小均为 2。为此函数生成代码,并检查代码生成报告。ca1 的元素定义为可变大小的 1x:5 数组。ca2 的第一个和第三个元素定义为固定大小的 1x2 数组,而第二个元素定义为可变大小的 :2x:2 矩阵。

function varSizeElement %#codegen
ca1 = {[1 2] [3 4] [5 6]};
ca2 = {[1 2] [3 4] [5 6]};
coder.varsize("ca1{:}",[1 5]);
coder.varsize("ca2{2}",[2 2]);
ca1{1} = 1;
ca1{2} = 1:5;
ca1{3} = 1:3;
ca2{1} = [5 6];
ca2{2} = [1 2;3 4];
ca2{3} = [7 8];
end

如果您使用 coder.varsize 来设置变量的上界,并且变量的大小取决于运行时输入,则当运行时输入超出上界时,可能会遇到运行时溢出错误。

例如,创建一个函数,该函数使用 coder.varsize 将变量 x 声明为可变大小的二维数组,并将每个维度的上界设置为 5。

function out = boundedVarSize1(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
x = zeros(n,n);
out = x;
end

在命令行中为此函数生成 MEX 代码,并检查代码生成报告。代码生成器将 x 定义为一个 :5x:5 数组。

codegen boundedVarSize -args {0} -report
Code generation successful: View report

如果向生成的 MEX 函数传递大于 5 的值,会出现大小溢出错误。为了避免溢出错误,请确保运行时输入不超出 coder.varsize 定义的上界。或者,重写您的 MATLAB 代码以防止运行时大小溢出。

function out = boundedVarSize2(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
if n <= 5
    x = zeros(n,n);
else
    x = zeros(5,5);
end
out = x;
end

输入参数

全部折叠

要声明为可变大小的变量的名称,指定为以逗号分隔的字符向量或字符串标量列表。变量不能为字符串、输入参量、全局变量、MATLAB 类或 MATLAB 类属性。

示例: coder.varsize("x","y")

每个数组维度的上界,指定为双精度向量。上界必须为整数或 Inf。上界会应用于传递给 coder.varsize 的所有变量。作为上界传递的整数在代码生成时必须为常量。您必须为 varName1,...,varNameN 的每个维度指定上界。要指定没有上界的变量,请使用 Inf

示例: coder.varsize("x","y",[5 Inf])

每个上界是否为可变大小,指定为逻辑值向量。您使用 upperBounds 输入参量指定上界。variableSize 向量的长度必须与 upperBounds 向量的长度相同。

示例: coder.varsize("x","y",[10 10 10], [false true true])

限制

  • 代码生成不支持将 coder.varsize 与全局变量、MATLAB 类和 MATLAB 类属性结合使用。

  • 代码生成不支持将 coder.varsize 与字符串结合使用。请参阅解决错误:字符串不支持 coder.varsize (MATLAB Coder)

  • coder.varsize 指令指示代码生成器允许变量的大小发生变化。它不会更改变量的大小。以如下代码片段为例:

    ...
    x = 7;
    coder.varsize("x", [1 5]);
    disp(size(x));
    ...

    coder.varsize 指令后,x 仍是 1×1 数组。您不能为超出 x 的当前大小的元素赋值。例如,以下代码会产生运行时错误,因为索引 3 超出了 x 的维数。

    ...
    x = 7;
    coder.varsize("x", [1,5]);
    x(3) = 1;
    ...

  • 您无法对函数输入参量调用 coder.varsize。在这种情况下:

    • 如果函数是入口函数,请在命令行中使用 coder.typeof (MATLAB Coder) 指定输入参量具有可变大小。或者,通过使用 MATLAB Coder™定义输入类型步骤,指定入口函数输入参量具有可变大小。

    • 如果函数不是入口函数,请在主调函数中使用 coder.varsize,变量是被调函数的输入。

  • 对于稀疏矩阵,coder.varsize 将可变大小维度视为无界。

  • 要对一个元胞数组使用 coder.varsize,该元胞数组必须为同构元胞数组。请参阅代码生成的元胞数组限制

提示

  • 在许多情况下,代码生成器能够确定变量的大小可以在运行时改变。在这种情况下,您不需要使用 coder.varsize 指令。仅在代码生成器生成大小溢出错误或您要指定上界时才使用 coder.varize

  • 要在 MATLAB Function 模块中声明可变大小的输出变量,请使用符号窗格和属性检查器。如果您在 coder.varsize 声明中提供上界,则上界必须与属性检查器中的上界相匹配。请参阅声明可变大小的 MATLAB Function 模块变量

  • 如果您没有在 coder.varsize 声明中指定上界,并且代码生成器无法推断上界,则生成的代码将使用动态内存分配。动态内存分配可能会降低生成的代码的速度。在某些情况下,可以通过使用 upperBounds 参量指定上界来避免动态内存分配。

  • 如果使用 coder.varsize 指定一个维度的上界为 1,则默认情况下,该维度具有固定大小 1。要指定维度可以是 0 或 1,请将 variableSize 向量的对应元素设置为 true。例如,以下指令指定 x 的第一个维度具有固定大小 1,其他维度具有上界为 5 的可变大小。

    coder.varsize('x',[1 5 5])

    而以下代码指定 x 的第一个维度是可变大小,上界为 1。

    coder.varsize("x",[1 5 5],[true true true])

  • 当您使用外部函数的输出时,代码生成器无法确定在代码生成时此输出的大小。请使用 coder.varsize 指示代码生成器将用于存储此输出的变量视为可变大小。请参阅在运行时使用外部函数的可变大小输出

  • 在某些情况下,您可以通过使用 coder.varsize 强制元胞数组为同构元胞数组。请参阅Control Whether a Cell Array Is Variable-Size

版本历史记录

在 R2011a 中推出