生成使用n维索引的代码
默认情况下,代码生成器对数组使用一维索引。代码生成器在C/ c++代码中为MATLAB中的n维数组创建一维数组®代码。您可以使用n维索引来提高可读性,并根据生成的代码调整接口。
此表显示了使用n维索引和不使用n维索引时生成的代码之间的差异。
MATLAB代码 |
生成的C代码(默认) |
生成启用N-D索引的C代码 |
---|---|---|
A = 0 (2,4,6) |
一个[48] |
|
n维索引的索引顺序是颠倒的,因为MATLAB生成的代码默认使用列主数组布局。要切换索引的顺序,可以启用行主数组布局。
将n维数组转换为一维数组也称为数组压扁.在计算机存储器中,所有数据都以一维数组的形式存储。索引的选择不会改变计算结果。但是,如果代码的输入或输出是数组,则生成代码的接口可以更改。
启用n维索引:
使用
-preservearraydims
选择:codegen喷火-preservearraydims
设置
PreserveArrayDimensions
属性的代码生成配置对象真正的
.例如:CFG = code .config(“自由”);cfg。PreserveArrayDimensions = true;codegen喷火配置cfg
的n维索引MATLAB编码器™应用:
导航到生成代码页中的代码生成工作流。
打开生成对话框生成箭头.
点击更多的设置.
在内存选项卡,选择保留数组尺寸复选框。
使用n维索引和行主布局提高可读性
n维索引可以使您更容易地将生成的C/ c++代码追溯到MATLAB代码。代码生成器保留原始数组的维度,而不是将数组转换为一维。此外,可以指定行主布局,使代码外观更加直观。
考虑MATLAB函数addMatrices
,将两个矩阵逐个元素相加:
函数sum = addMatrices(A,B)% # codegensum = code .nullcopy(A);为row = 1:size(A,1)为size(A,2) sum(row,col) = A(row,col) + B(row,col);结束结束
生成以下代码addMatrices
它作用于2 × 4数组。启用n维索引和行主数组布局:
CFG = code .config(“自由”);cfg。PreserveArrayDimensions = true;cfg。RowMajor = true;codegenaddMatricesarg游戏{的(2、4)的(2、4)}配置cfg-launchreport
代码生成生成带有显式二维数组索引的代码:
/* N-d索引on, row-major on */ void addMatrices(double A[2][4], double B[2][4], double sum[2][4]) {int row;int上校;For (row = 0;行< 2;Row ++) {for (col = 0;Col < 4;坳+ +){总和(行)(col) =(行)(col) + B(行)(col);}}}
的生成代码addMatrices
使用与原始MATLAB代码相同的二维索引。您可以轻松地将生成的代码与原始算法进行比较。要了解如何使用行-主布局,请参见生成使用行-主数组布局的代码.
列主布局和n维索引
数组布局的选择影响n维索引的外观。例如,为addMatrices
函数使用列主数组布局:
cfg。RowMajor = false;codegenaddMatricesarg游戏{的(2、4)的(2、4)}配置cfg-launchreport
代码生成生成以下C代码:
/* N-d索引on, row-major off */ void addMatrices(double A[4][2], double B[4][2], double sum[4][2]) {int row;int上校;For (row = 0;行< 2;Row ++) {for (col = 0;Col < 4;坳+ +){总和(col)(行)= (col)(行)+ B (col)(行);}}}
C代码中的输入和输出矩阵是原始MATLAB矩阵的转置。要理解其中的原因,请考虑数组在计算机内存中是如何表示的。MATLAB语言默认使用列主布局,其中第一个(最左)维度或索引的元素在内存中是连续的。C默认使用行主数组布局,其中来自最后(最右边)维度或索引的元素是连续的。为了保持原始的元素邻接关系,代码生成器必须反转数组维度的顺序。
例如,在这种情况下,如果你定义MATLAB矩阵一个
为:
=重塑(1:8,2、4)
或
A = 1 3 5 7 2 4 6 8
然后,由于MATLAB使用列-主布局,数据在内部按顺序存储:
A(:)' = 1 2 3 4 5 6 7 8
在C代码中,您必须对原始数据进行转置,对于本例,调用它AA
:
Aa = {{1,2}, {3,4}, {5,6}, {7,8};
获取具有相同内部存储顺序的数据元素列表。换句话说,C数组必须是4 × 2的。(通过将数组定义为2 × 4的数组,可以获得等效的存储顺序Aa = {{1,2,3,4}, {5,6,7,8}}
.然而,获取这个顺序需要手动重塑或重新排列数据。)
数组布局的选择只影响内部数据表示,不会改变计算或算法结果。为了在生成的代码中保持MATLAB数组的直观外观,使用n维索引和行主数组布局。注意,行主布局会影响生成代码的效率。有关更多信息,请参见行-主阵列布局的代码设计.
其他代码生成注意事项
考虑n维索引的其他方面。代码生成器总是为n维向量生成一维数组,即使在指定n维索引时也是如此。例如,如果你为MATLAB矢量生成代码:
A = 0 (1,10)
或
A = 0 (1,10,1)
生成的C/ c++数组存储为:
一个[10]
n维索引也适用于数组和结构。例如,如果你在代码中声明结构为:
X = struct(“f1”的(2、3));coder.cstructname (x,“myStruct1”);Y = struct(“f2”的(6,1));coder.cstructname (y,“myStruct2”);
然后生成的代码包含结构定义:
Typedef结构{双f1[2][3];} myStruct1;Typedef结构{double f2[6];} myStruct2;
避免在n维数组上进行线性索引。例如,当你使用冒号操作符时,会发生线性索引:
(:)
要应用线性索引,代码生成器必须将n维数组转换为一维数组。强制转换操作使代码生成器分析起来更加复杂。这种增加的复杂性可能会阻碍代码生成器优化性能的能力。
最后,注意以下几点:
可以对任何数据类型的数组使用n维索引。
只有固定大小的数组,而不是可变大小的数组,可以使用n维索引。