不兼容的MATLAB代码生成的可变大小支持金宝app
不兼容,MATLAB对于标量展开
标量展开是一种转换标量数据以匹配向量或矩阵数据维数的方法。如果一个操作数是标量,而另一个不是,标量展开将标量应用于另一个操作数的每个元素。
在代码生成期间,标量展开规则将应用,除非操作两个可变大小的表达式。在这种情况下,两个操作数的大小必须相同。即使其中一个可变大小表达式在运行时是标量,生成的代码也不会执行标量展开。因此,当启用运行时错误检查时,就会发生运行时错误。
考虑这个函数:
函数Y = scalar_exp_test_err1(u)% # codegenY = ones(3);开关u情况下0 z = 0;情况下1 z = 1;否则Z = 0 (3);结束Y (:) = z;
当您为这个函数生成代码时,代码生成器将确定这一点z
变量大小的上限是3.
.
如果使用u
如果等于0或1,则生成的代码不会执行标量展开z
在运行时为标量。因此,当启用运行时错误检查时,就会发生运行时错误。
scalar_exp_test_err1_mex(0)下标赋值维度不匹配:[9]~=[1]。scalar_exp_test_err1(第11行)中的错误y(:) = z;
要避免此问题,请使用索引强制z
为标量值。
函数Y = scalar_exp_test_err1(u)% # codegenY = ones(3);开关u情况下0 z = 0;情况下1 z = 1;否则Z = 0 (3);结束Y (:) = z(1);
不兼容,MATLAB在确定可变大小N-D数组的大小
对于可变大小的N-D数组,大小
函数可以在生成的代码中返回与MATLAB中不同的结果®.在生成的代码中,大小(一个)
返回一个固定长度的输出,因为它不会删除可变大小N-D数组的尾单维度。相比之下,大小(一个)
在MATLAB中返回一个变长的输出,因为它去掉了尾随的单维度。
例如,如果数组的形状一个
是: x: x: ?
而且大小(3)= = 1
,大小(一个)
返回:
生成代码中的三元素向量
二元矢量的MATLAB代码
解决方法
如果您的应用程序要求生成的代码返回与MATLAB代码相同大小的可变N-D数组,请考虑以下解决方案之一:
使用的双参数形式
大小
.例如,
大小(n),
在生成的代码和MATLAB代码中返回相同的答案。重写
大小(一个)
:B =大小(A);X = B(1:ndims(A));
这个版本返回
X
具有可变长度输出。但是,您不能传递一个可变大小的参数X
到矩阵构造函数,如0
这需要一个固定大小的参数。
不兼容,MATLAB在确定空数组的大小
生成代码中的空数组的大小可能与MATLAB源代码中的大小不同。大小可能是1 x0
或0 x1
在生成代码中,但是0 x0
在MATLAB。因此,不应该编写依赖于空矩阵的特定大小的代码。
例如,考虑以下代码:
函数Y = foo(n)% # codegenX = [];I = 0;而(i < 10) x = [5 x];I = I + 1;结束如果N > 0 x = [];结束Y =大小(x);结束
连接要求其操作数匹配未连接的维度的大小。在前面的连接中,标量值具有大小1 x1
而且x
有大小0 x0
.为了支金宝app持这个用例,代码生成器决定了的大小x
作为[1 x:?]
.因为还有一个作业X = []
拼接后,大小x
在生成的代码中是1 x0
而不是0 x0
.
在确定空字符向量的大小时,此行为持续存在”
.例如,考虑以下代码:
函数Out = string_size”);结束
这里,的值出
可能是1 x0
或0 x1
在生成代码中,但是0 x0
在MATLAB。
有关与MATLAB在确定因删除数组元素而导致的空数组大小方面的不兼容性,请参见删除数组元素导致的空数组大小.
解决方案
如果你的应用程序检查一个矩阵是否为空,可以使用以下方法之一:
重写代码以使用
isempty
函数,而不是大小
函数。而不是使用
x = []
若要创建空数组,请使用0
.例如:函数Y = test_empty(n)% # codegenX = 0 (1,0);我= 0;而(i < 10) x = [5 x];I = I + 1;结束如果N > 0 x = 0 (1,0);结束y =大小(x);结束
不兼容,MATLAB在确定空数组的类中
生成代码中的空数组的类可以与MATLAB源代码中的类不同。因此,不要编写依赖于空矩阵类的代码。
例如,考虑以下代码:
函数Y = fun(n) x = [];如果N > 1 x = [“一个”x];结束y =类(x);结束
有趣的(0)
返回双
在MATLAB中,但是字符
在生成的代码中。当语句N > 1
为false, MATLAB不执行X = ['a' X]
.这类人x
是双
,空数组的类。但是,代码生成器会考虑所有的执行路径。它根据语句来确定X = ['a' X]
,类x
是字符
.
解决方案
而不是使用x = []
若要创建空数组,请创建特定类的空数组。例如,使用空白(0)
创建一个空字符数组。
函数Y = fun(n) x = blanks(0);如果N > 1 x = [“一个”x];结束y =类(x);结束
不兼容,MATLAB矩阵-矩阵索引
在矩阵-矩阵索引中,您使用一个矩阵索引到另一个矩阵。在MATLAB中,矩阵-矩阵索引的一般规则是结果的大小和方向与索引矩阵的大小和方向相匹配。例如,如果一个
而且B
矩阵,大小((B))
=大小(B)
.当一个
而且B
是向量,MATLAB应用了一个特殊的规则。特殊的向量-向量索引规则是结果的方向就是数据矩阵的方向。例如,i一个
是1乘5和B
是3乘1吗(B)
1×3。
代码生成器应用与MATLAB相同的矩阵-矩阵索引规则。如果一个
而且B
是可变大小的矩阵,为了应用矩阵-矩阵索引规则,代码生成器假设大小((B))
=大小(B)
.如果在运行时,一个
而且B
变成矢量并且有不同的方向,那么假设是不正确的。因此,当启用运行时错误检查时,就会发生错误。
为避免此问题,可以使用冒号操作符进行索引,强制将数据转换为向量。例如,假设您的代码在运行时有意在向量和规则矩阵之间切换。您可以显式地检查向量-向量索引。
...如果isvector(A) && isvector(B) C = A(:);D = c (b (:));其他的D = a (b);结束...
第一个分支中的索引指定了这一点C
而且B (:)
是编译时向量。因此,代码生成器应用索引规则将一个向量与另一个向量进行索引。结果的方向就是数据向量的方向,C
.
不兼容,MATLAB矢量-矢量索引
在MATLAB中,矢量-矢量索引的特殊规则是结果的方向是数据向量的方向。例如,如果一个
是1乘5和B
是3乘1吗(B)
1×3。但是,如果是数据向量一个
是标量,那么方向呢(B)
是指标向量的方向吗B
.
代码生成器应用与MATLAB相同的矢量-矢量索引规则。如果一个
而且B
是变大小的向量,要应用索引规则,代码生成器假定方向为B
匹配的方向一个
.在运行时,如果一个
标量和方向一个
而且B
不匹配,则假设是不正确的。因此,当启用运行时错误检查时,就会发生运行时错误。
为了避免这个问题,让向量的方向匹配。或者,通过指定行和列来索引单个元素。例如,(行、列)
.
不兼容,MATLAB在矩阵索引操作代码生成
以下限制适用于代码生成的矩阵索引操作:
初始化如下样式:
为i = 1:10 M(i) = 5;结束
在本例中,的大小
米
随着循环的执行而改变。代码生成不支持随时间增加数组的大小。金宝app对于代码生成,预分配
米
.M = 0 (1,10);为i = 1:10 M(i) = 5;结束
当禁用动态内存分配时,以下限制适用于代码生成的矩阵索引操作:
M (i, j)
在哪里我
而且j
循环中的变化在代码生成过程中,不会根据程序执行时变化的表达式大小动态分配内存。要实现此行为,请使用
对- - - - - -
循环如下所示:...M = ones(10,10);为i = 1:10为j = i:10 M(i,j) = 2*M(i,j);结束结束...
请注意
矩阵
米
必须在进入循环之前定义。
不兼容,MATLAB在连接可变大小的矩阵
对于代码生成,当连接可变大小数组时,未连接的维度必须完全匹配。
当连接内的可变大小单元格数组的卷括号索引不返回任何元素时的差异
假设:
c
是一个可变大小的单元格数组。的内容
c
通过使用花括号。例如,c {2:4}
.你可以将结果串联起来。例如,
[a c{2:4} b]
.c{我}
不返回任何元素。要么c
为空,或者花括号内的索引产生空结果。
对于这些条件,MATLAB省略了c{我}
从串联。例如,[a c{I} b]
就变成了[b]
.代码生成器处理c{我}
作为一个空数组[c{我}]
.串联就变成了[c{我}][……]
.然后,这种连接将省略该数组[c{我}]
.这就是它的性质[c{我}]
是否与级联兼容[c{我}][……]
的类、大小和复杂度[c{我}]
根据这些规则:
类和复杂度与单元格数组的基类型相同。
第二个维度的大小总是0。
对于其余的维度,的大小
倪
取决于基类型中对应的尺寸是固定大小还是可变大小。如果基类型中对应的维度为可变大小,则该维度在结果中的大小为0。
如果基类型中对应的维度是固定大小,则该维度在结果中具有该大小。
假设c
具有类的基类型int8
和大小: 10 x7x8x: ?
.的类在生成的代码中[c{我}]
是int8
.的大小[c{我}]
是0 x0x8x0
.第二个维度是0。第一个和最后一个维度为0,因为这些维度在基类型中是可变大小的。第三个维度是8,因为基类型的第三个维度的大小是固定的8。
在拼接中,如果对可变大小单元格数组的花括号索引不返回任何元素,则生成的代码可能与MATLAB有以下差异:
这类人
c{我}[……]
在生成的代码中可以不同于MATLAB中的类。当
c{我}
返回没有元素,MATLAB删除c{我}
从串联。因此,c{我}
不影响结果的类。MATLAB根据类的优先级,根据剩余数组的类确定结果的类。看到不同类的有效组合.的类在生成的代码中[c{我}]
影响整体连接结果的类[c{我}][……]
因为代码生成器处理c{我}
作为[c{我}]
.前面描述的规则确定的类[c{我}]
.在生成的代码中,的大小
[c{我}]
可以与MATLAB中的大小不同。在MATLAB中,串联
[c{我}]
是0x0 double。在生成的代码中,前面描述的规则确定的大小[c{我}]
.