生成使用n维索引的代码
默认情况下,代码生成器对数组使用一维索引。代码生成器在C/ c++代码中为MATLAB中的n维数组创建一维数组®代码。您可以使用n维索引来提高可读性,并使接口适应生成的代码。
此表显示了使用和不使用n维索引生成的代码之间的差异。
MATLAB代码 |
生成的C代码(默认) |
生成C代码,启用N-D索引 |
---|---|---|
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);为行= 1:大小(A,1)为(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
代码生成生成带有显式二维数组索引的代码:
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(双A[4][2],双B[4][2],双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”);
然后生成的代码包含结构定义:
类型定义结构{双f1[2][3];} myStruct1;Typedef struct {double f2[6];} myStruct2;
避免对n维数组进行线性索引。例如,当你使用冒号操作符时,会发生线性索引:
(:)
要应用线性索引,代码生成器必须将n维数组转换为一维数组。强制转换操作使代码生成器分析起来更加复杂。这种增加的复杂性会阻碍代码生成器优化性能的能力。
最后,请注意以下几点:
可以对任何数据类型的数组使用n维索引。
只有固定大小的数组,而不是可变大小的数组,可以使用n维索引。