为具有 end + 1 索引的增大数组和元胞数组生成代码
通过使用 end + 1 索引,代码生成支持在 MATLAB® 代码中增大数组或元胞数组。默认情况下,代码生成支持可变大小数组。要验证此功能是否启用,请使用以下方法之一:
在代码配置对象中,确保属性
EnableVariableSizing设置为true。在“代码生成设置”对话框中,确保启用可变大小复选框处于选中状态。
使用 (end + 1) 索引增大数组
要增大数组 X,可以为 X(end + 1) 赋值。如果您在 MATLAB 代码中进行这种赋值,代码生成器会将您增大的维度视为可变大小维度。
例如,您可以为以下代码片段生成代码:
... a = [1 2 3 4 5 6]; a(end + 1) = 7; b = [1 2]; for i = 3:10 b(end + 1) = i; end ...
使用 (end + 1) 增大数组时,请遵循以下限制:
仅使用
(end + 1)。不要使用(end + 2)、(end + 3)等。仅对向量使用
(end + 1)。例如,不允许使用以下代码,因为X是矩阵,而不是向量。... X = [1 2; 3 4]; X(end + 1) = 5; ...
您可以使用
(end + 1)增大大小为1x0的空数组。不支持增大大小为0x1的数组。仅当使用[]创建大小为0x0的数组时,才支持增大该数组。
增大在运行时初始化为标量的可变大小列数组
在 MATLAB 执行中,如果您使用 (end+1) 索引来增大标量数组,则数组将沿第二个维度增大并生成一个行向量。例如,定义函数 grow:
function z = grow(n, m) n(end+1) = m; z = n; end
使用示例输入调用 grow:
grow(2,3)
ans =
2 3相反,在代码生成中,假设:
您在编译时将数组指定为可变大小的列类型(例如,
:Inf x 1),并且在运行时将此数组初始化为标量。
在这种情况下,生成的代码尝试沿第一个维度增大标量,因此会产生运行时错误。例如,为 grow 生成 MEX 代码。将输入 n 指定为 :Inf x 1 双精度数组。将输入 m 指定为双精度标量。
codegen grow -args {coder.typeof(0, [Inf 1], [1 0]), 1}
Code generation successful.
使用与之前相同的输入运行生成的 MEX。
grow_mex(2,3)
Attempted to grow a scalar along the first dimension using end+1 indexing.This behavior differs from MATLAB execution which grows a scalar along the second dimension.(已尝试使用 end+1 索引沿第一个维度增大标量。此行为不同于 MATLAB 执行,后者会沿第二个维度增大标量。)
如何避免此错误. 要避免此错误并在生成的代码和 MATLAB 执行中沿列维度增大数组,请以如下方式之一重写 MATLAB 代码:
使用串联运算符(而不是使用
(end+1))增大数组。例如,将grow函数重写为:function z = growCat(n, m) n = [n;m]; z = n; end
在函数中,通过转置要增长的变量来创建一个临时变量。然后,使用
(end+1)索引增大此临时变量。最后,对此临时变量进行第二次转置。例如,将grow函数重写为:function z = growTransposed(n, m) temp = n'; temp(end+1) = m; z = temp'; end
使用 {end + 1} 索引增大元胞数组
要增大元胞数组 X,可以使用 X{end + 1}。例如:
... X = {1 2}; X{end + 1} = 'a'; ...
当您使用 {end + 1} 增大元胞数组时,请遵循以下限制:
在 MATLAB Function (Simulink) 模块中,不要在
for循环中使用{end + 1}。仅使用
{end + 1}。不要使用{end + 2}、{end + 3}等。仅对向量使用
{end + 1}。例如,不允许使用以下代码,因为X是矩阵,而不是向量:... X = {1 2; 3 4}; X{end + 1} = 5; ...
仅对变量使用
{end + 1}。在以下代码中,{end + 1}不会使{1 2 3}增大。在本例中,代码生成器将{end + 1}视为超出X{2}范围的索引。... X = {'a' { 1 2 3 }}; X{2}{end + 1} = 4; ...
当
{end + 1}在循环中增大元胞数组时,该元胞数组必须是可变大小的。因此,元胞数组必须是同构元胞数组。允许使用以下代码,因为
X是同构元胞数组。... X = {1 2}; for i=1:n X{end + 1} = 3; end ...
不允许使用以下代码,因为
X是异构元胞数组。... X = {1 'a' 2 'b'}; for i=1:n X{end + 1} = 3; end ...
有关导致生成的代码和 MATLAB 之间行为差异的编码模式,请参阅增大在运行时初始化为标量的可变大小列元胞数组。