主要内容

不兼容的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 x00 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 x00 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:10j = 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{我}]