Cell Array Limitations for Code Generation
When you use cell arrays in MATLAB® code that is intended for code generation, you must adhere to these restrictions.
Assign Consistent Element Types
The types of values assigned to cell array elements must be the same across
all execution paths. For example, consider the
function inconsistentTypeError
. Code generation for this function
fails because ca{2}
is a double
on one
execution path and a char
on another execution
path.
function out = inconsistentTypeError(n) %#codegen ca = cell(1,3); if n > 1 ca{1} = 1; ca{2} = 2; ca{3} = 3; else ca{1} = 10; ca{2} = 'a'; ca{3} = 30; end out = ca{1}; end
Variable-Size Cell Arrays Must Be Homogenous
When you generate code for MATLAB functions that contain cell arrays, the code generator classifies each cell array as homogeneous or heterogeneous. In general, the code generator classifies cell arrays that contain elements of the same type as homogenous and cell arrays that contain elements of different types as heterogeneous. To learn more about how the code generator handles homogenous and heterogeneous cell arrays, see Code Generation for Cell Arrays.
You can use coder.varsize
(MATLAB Coder) to define a homogenous
cell array as variable-size and to set upper bounds for a variable-size cell array.
For example, this code changes caX
and caY
from cell arrays with a fixed size of 1x3
to variable-size cell
arrays where the second dimension can vary up to size 5
(1x:5
).
... caX = {1 2 3}; caY = cell(1,3); coder.varsize('caX',[1 5]) coder.varsize('caY',[1 5]) ...
Assign Values to All Cell Array Elements
You must assign values to all cell array
elements on all execution paths before you use the
cell array. When you use the cell
function to create a variable-size cell array, the sizes and
types of the elements of the cell array are undefined in the generated code.
Therefore, in MATLAB code for code generation, you must make sure to assign initial values
to all elements of
all variable-size cell arrays created using the
cell
function. For example, consider the function
incompleteAssignmentError
. Code generation for this function
fails because the code generator detects that the element returned by the function,
ca{2}
, is not defined on the execution path where
n
is less than
5
.
function out = incompleteAssignmentError(n) %#codegen ca = cell(1,2); if n < 5 ca{1} = 0; else ca{2} = 3; end out = ca{2}; end
Sometimes, even though your MATLAB code assigns values to all elements
of a cell array, code generation can fail because the code generator is unable to
recognize that all cell array elements are
assigned. In general, use the coding pattern shown in
cellArrayPatternExample
to assign values to the elements of
variable-size cell arrays created using
cell
.
function out = cellArrayPatternExample(n) %#codegen ca = cell(1,n); for i = 1:n ca{i} = i; end out = ca{n}; end
For additional patterns that you can use to make sure that you define all cell array elements, see Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use.
Assign Initial Values on the Same Execution Path as the cell
Function
When you create a cell array by using the cell
function, you
must include the loop that assigns initial values to the cell array elements on the
same unique execution path as the cell
function that creates the
cell array. For example, code generation fails for function
cellLoopError
because the for
-loop that
assigns initial values to the elements of cell array ca
does not
appear on a unique execution path with the cell
function that
creates it.
function out = cellLoopError(n) %#codegen if n < 5 ca = cell(1,n); else ca = cell(n,1); end for i = 1:n ca{i} = i; end out = ca; end
To resolve this issue, assign initial values to the cell array elements inside the
code block that contains the cell
function that creates each cell
array.
function out = cellLoopExample(n) %#codegen if n < 5 ca = cell(1,n); for i = 1:n ca{i} = 0; end else ca = cell(n,1); for i = 1:n ca{i} = 0; end end for i = 1:n ca{i} = i; end out = ca{n}; end
To Assign Initial Values to Variable-Size Cell Arrays in Object Properties or Structure Fields, Use Temporary Variables
When you create a variable-size cell array by using the cell
function, you must assign initial values to all
elements of the cell array before you use it in an object property or structure
field. For example, code generation fails for function
fieldAssignmentError
because it directly assigns initial
values to the cell array elements in a structure
field.
function out = fieldAssignmentError(n) %#codegen s.field = cell(1,n); for i = 1:n s.field{i} = i+1; end out = s.field{n}; end
function out = fieldAssignmentExample(n) %#codegen ca = cell(1,n); for i = 1:n ca{i} = 0; end s.field = ca; for i = 1:n s.field{i} = i+1; end out = s.field{n}; end
To Index into Heterogeneous Arrays, Use Constant Indices or for
-loops with Constant Bounds
When you generate code for MATLAB functions that contain cell arrays, the code generator classifies each cell array as homogeneous or heterogeneous. In general, the code generator classifies cell arrays that contain elements of the same type as homogenous and cell arrays that contain elements of different types as heterogeneous. To learn more about how the code generator handles homogenous and heterogeneous cell arrays, see Code Generation for Cell Arrays.
You must index into heterogeneous cell arrays by using constant indices or by
using for
-loops with constant bounds. For example, code
generation fails for the function cellIndexingError
because the
index is not a
constant.
function cellIndexingError(n) %#codegen ca = {1 "a" 2 5:7 3 "c"}; disp(ca{n}); end
You can index into a heterogeneous cell array by using a
for
-loop with constant bounds because the code generator
unrolls the loop, which means that it creates a separate copy of the loop body for
each loop
iteration.
function cellIndexingExample(n) %#codegen ca = {1 "a" 2 5:7 3 "c"}; for i = 1:6 if i == n disp(ca{i}); end end end
Note
If the for
-loop has a large body or many iterations,
unrolling can increase compile time and generate inefficient code.
To Grow Cell Arrays by Using {end + 1}, Use Certain Coding Patterns
Code generation supports growing cell arrays by using {end + 1}
in MATLAB code for code generation. For example, you can generate code for
function growCellArray
, which uses {end + 1}
to grow array
ca
.
function out = growCellArrayExample(n) %#codegen ca = {1 2}; for i = 1:n ca{end+1} = 3+i; end out = ca{n}; end
When you use {end + 1}
to grow a cell array in MATLAB code for code generation, you must adhere to these restrictions:
You can grow a cell array only by assigning a value to the
{end + 1}
element. Assigning a value to subsequent elements, such as{end + 2}
, is not supported.You can only use
{end + 1}
to grow cell array vectors. For example, code generation fails for functiongrowMatrixError
becauseca
is a matrix, not a vector.function ca = growMatrixError %#codegen ca = {1 2; 3 4}; ca{1,end+1} = 5; end
{end + 1}
must appear immediately after a variable. For example, code generation forgrowArraySubscriptError
fails because{end + 1}
appears next toca{2}
, not next toca
.To resolve this issue, set the element of the cell array that you want to modify equal to a temporary variable. Then, usefunction out = growArraySubscriptError(x) %#codegen ca = {'a' { 1 2 3 }}; ca{2}{end+1} = x; out = ca{2}{4}; end
{end + 1}
to grow the temporary variable. Usecoder.varsize
to allow the size of the modified cell array element to change.function out = growArrayExampleA(x) %#codegen ca = {'a' {1 2 3}}; coder.varsize('ca{2}') temp = ca{2}; temp{end+1} = x; ca{2} = temp; out = ca{2}{4}; end
Alternatively, add the new element by using array concatenation instead of by using
{end + 1}
.function out = growArrayExampleB(x) %#codegen ca = {'a' {1 2 3}}; coder.varsize('ca{2}') ca{2} = [ca{2} {x}]; out = ca{2}{4}; end
If you use
{end + 1}
to grow a cell array in a loop, the cell array must be homogenous, which means that all cell array elements must be of the same type. For example, code generation fails for functiongrowHeterogeneousError
because cell arrayca
contains elements of typestring
and typedouble
.To learn more about how the code generator handles homogenous and heterogeneous cell arrays, see Code Generation for Cell Arrays.function out = growHeterogeneousError(n) %#codegen ca = {1 2 "a"}; for i = 1:n ca{end+1} = 3+i; end out = ca; end
To Iterate Over a Cell Array Directly, the First Dimension of the Cell Array Must Be 1
In MATLAB, you can directly iterate over a cell array with
any number of dimensions. For example, consider
the function directIterationError
, which iterates over a 3-by-4
cell array and displays the contents of each column. Code generation for this
function fails because the first dimension of array ca
is not
1
.
function directIterationError ca = {1 2 3 4; "five" "six" "seven" "eight"; 9 10 11 12}; for i = ca disp(i); end end
To iterate over a cell array where the first dimension is not 1
in MATLAB code for code generation, loop over the size of each cell array
dimension, rather than the cell array itself.
function iterationExample %#codegen ca = {1 2 3 4; "five" "six" "seven" "eight"; 9 10 11 12}; for i = 1:size(ca,1) for j = 1:size(ca,2) disp(ca{i,j}); end end end
Do Not Use Smooth Parentheses ()
to Index into Cell Arrays
In MATLAB code for code generation, you cannot index into cell arrays by using
smooth parentheses ()
. Use curly braces {}
to
access the contents of a cell.
Do Not Call the cell
Function Inside the Cell Array Constructor {}
Code generation does not support using the cell
function inside
the cell array constructor {}
. For this reason, code generation
fails for function
cellCellError
.
function out = cellCellError(n) %#codegen ca = {cell(1,n) cell(1,n)}; for i = 1:n ca{1}{i} = i+1; ca{2}{i} = i+2; end out = ca; end
To create a cell array containing other cell arrays, initialize all elements of each inner cell array before creating the outer array. You can then access the elements of the inner arrays directly.
function out = cellCellExample(n) %#codegen x = cell(1,n); y = cell(1,n); for i = 1:n x{i} = 0; y{i} = 0; end ca = {x y}; for i = 1:n ca{1}{i} = i+1; ca{2}{i} = i+2; end out = ca{1}{n}+ca{2}{n}; end
Do Not Store mxArray
Data in a Cell Array
In MATLAB code for code generation, you cannot store a MATLAB array, also known as an mxArray
, in a cell array.
When you call an extrinsic function by using coder.extrinsic
, the run-time output of the called function is an
mxArray
. Therefore, you cannot store the output of an
extrinsic function in a cell array without first converting the output to a known
type. See Working with mxArrays.
Do Not Pass a Cell Array to an External C/C++ Function by Using coder.ceval
Code generation does not support passing a cell array to an external C/C++ function by using
coder.ceval
(MATLAB Coder). If a cell array is an
input argument to coder.ceval
, redefine the cell array as an
ordinary array or a structure.