Generate Code That Uses NDimensional Indexing
By default, the code generator uses onedimensional indexing for arrays. The code generator creates onedimensional arrays in C/C++ code for Ndimensional arrays in MATLAB^{®} code. You can use Ndimensional indexing to improve readability and adapt the interface to your generated code.
This table shows an example of the differences in the generated code with and without Ndimensional indexing.
MATLAB Code  Generated C Code (default)  Generated C Code with ND Indexing Enabled 

A = zeros(2,4,6) 
A[48] 

The order of the indices is reversed for Ndimensional indexing because MATLAB generates code that uses columnmajor array layout by default. To switch the order of the indices, you can enable rowmajor array layout.
Conversion of an Ndimensional array to one dimension is also called array flattening. In computer memory, all data is stored in terms of onedimensional arrays. The choice of indexing does not change computation results. However, if your code has inputs or outputs that are arrays, the interface to your generated code can change.
To enable Ndimensional indexing:
Use the
preservearraydims
option:codegen foo preservearraydims
Set the
PreserveArrayDimensions
property for your code generation configuration object totrue
. For example:cfg = coder.config('lib'); cfg.PreserveArrayDimensions = true; codegen foo config cfg
To enable Ndimensional indexing from the MATLAB Coder™ App:
Navigate to the Generate Code page in the code generation workflow.
Open the Generate dialog box by clicking the Generate arrow .
Click More Settings.
On the Memory tab, select the Preserve array dimensions check box.
Improve Readability with NDimensional Indexing and RowMajor Layout
Ndimensional indexing can make it easier for you to trace your generated C/C++ code back to your MATLAB code. The code generator preserves the dimensions of the original arrays, rather than converting arrays to one dimension. Furthermore, you can specify rowmajor layout to make the code appearance even more intuitive.
Consider the MATLAB function addMatrices
, which adds two matrices, element
by element:
function sum = addMatrices(A,B) %#codegen sum = coder.nullcopy(A); for row = 1:size(A,1) for col = 1:size(A,2) sum(row,col) = A(row,col) + B(row,col); end end
Generate code for addMatrices
so that it operates on 2by4 arrays.
Enable Ndimensional indexing and rowmajor array layout:
cfg = coder.config('lib'); cfg.PreserveArrayDimensions = true; cfg.RowMajor = true; codegen addMatrices args {ones(2,4),ones(2,4)} config cfg launchreport
Code generation produces code with explicit twodimensional array indexing:
/* Nd indexing on, rowmajor on */ void addMatrices(double A[2][4], double B[2][4], double sum[2][4]) { int row; int col; for (row = 0; row < 2; row++) { for (col = 0; col < 4; col++) { sum[row][col] = A[row][col] + B[row][col]; } } }
The generated code for addMatrices
uses the same twodimensional
indexing as the original MATLAB code. You can easily analyze the generated code in comparison with the
original algorithm. To understand how to use rowmajor layout, see Generate Code That Uses RowMajor Array Layout.
ColumnMajor Layout and NDimensional Indexing
The choice of array layout affects the appearance of Ndimensional indexing. For
example, generate code for the addMatrices
function using
columnmajor array layout:
cfg.RowMajor = false; codegen addMatrices args {ones(2,4),ones(2,4)} config cfg launchreport
Code generation produces this C code:
/* Nd indexing on, rowmajor off */ void addMatrices(double A[4][2], double B[4][2], double sum[4][2]) { int row; int col; for (row = 0; row < 2; row++) { for (col = 0; col < 4; col++) { sum[col][row] = A[col][row] + B[col][row]; } } }
The input and output matrices in the C code are transposes of the original MATLAB matrices. To understand why, consider how arrays are represented in computer memory. The MATLAB language uses columnmajor layout by default, where the elements from the first (leftmost) dimension or index are contiguous in memory. C uses rowmajor array layout by default, where elements from the last (rightmost) dimension or index are contiguous. To preserve the original element adjacency, the code generator must reverse the order of the array dimensions.
For example, in this case, if you define the MATLAB matrix A
as:
A=reshape(1:8,2,4)
or
A = 1 3 5 7 2 4 6 8
then, because MATLAB uses columnmajor layout, the data is internally stored in the order:
A(:)' = 1 2 3 4 5 6 7 8
In C code, you must transpose the original data, for this example, call it
AA
:
AA = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
to attain the list of data elements with the same internal storage order. In other
words, the C array must be 4by2. (You can obtain an equivalent storage order by
defining the array as a 2by4, with AA = {{1, 2, 3, 4}, {5, 6, 7,
8}}
. However, obtaining this order requires a manual reshape or
rearrangement of the data.)
The choice of array layout affects only internal data representation and does not change computational or algorithmic results. To preserve the intuitive appearance of MATLAB arrays in generated code, use Ndimensional indexing with rowmajor array layout. Note that rowmajor layout can affect the efficiency of your generated code. For more information, see Code Design for RowMajor Array Layout.
Other Code Generation Considerations
Consider other aspects of Ndimensional indexing. The code generator always produces onedimensional arrays for Ndimensional vectors, even when you specify Ndimensional indexing. For example, if you generate code for a MATLAB vector:
A = zeros(1,10)
or
A = zeros(1,10,1)
the resulting C/C++ arrays are stored as:
A[10]
Ndimensional indexing also applies to arrays and structures. For example, if you declare structures in your code as:
x = struct('f1', ones(2,3)); coder.cstructname(x,'myStruct1'); y = struct('f2', ones(1,6,1)); coder.cstructname(y,'myStruct2');
then the generated code contains the structure definitions:
typedef struct { double f1[2][3]; } myStruct1; typedef struct { double f2[6]; } myStruct2;
Avoid linear indexing on Ndimensional arrays. Linear indexing occurs, for example, when you use the colon operator:
A(:)
To apply linear indexing, the code generator must cast an Ndimensional array into a onedimensional array. Casting operations make your code more complex for the code generator to analyze. This increased complexity can hinder the ability of the code generator to optimize for performance.
Last, note the following:
You can use Ndimensional indexing for arrays of any data type.
Only fixedsize arrays, and not variablesize arrays, can use Ndimensional indexing.
See Also
codegen
 reshape
 coder.cstructname