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:
Cell Array Element Assignment
You must assign a cell array element on all execution paths before you use it. For example:
function z = foo(n) %#codegen c = cell(1,3); if n < 1 c{2} = 1; else c{2} = n; end z = c{2}; end
The code generator considers passing a cell array to a function
or returning it from a function as a use of all
elements of the cell array. Therefore, before you pass a cell array
to a function or return it from a function, you must assign all
of its elements. For example, the following code is not allowed because
it does not assign a value to c{2}
and c
is
a function output.
function c = foo() %#codegen c = cell(1,3); c{1} = 1; c{3} = 3; end
The assignment of values to elements must be consistent on all
execution paths. The following code is not allowed because y{2}
is
double on one execution path and char on the other execution path.
function y = foo(n) y = cell(1,3) if n > 1; y{1} = 1 y{2} = 2; y{3} = 3; else y{1} = 10; y{2} = 'a'; y{3} = 30; end
Variable-Size Cell Arrays
coder.varsize
is not supported for heterogeneous cell arrays.If you use the
cell
function to define a fixed-size cell array, you cannot usecoder.varsize
to specify that the cell array has a variable size. For example, this code causes a code generation error becausex = cell(1,3)
makesx
a fixed-size,1-by-3 cell array.... x = cell(1,3); coder.varsize('x',[1 5]) ...
You can use
coder.varsize
with a cell array that you define by using curly braces. For example:... x = {1 2 3}; coder.varsize('x',[1 5]) ...
To create a variable-size cell array by using the
cell
function, use this code pattern:function mycell(n) %#codegen x = cell(1,n); for i = 1:n x{i} = i; end end
See Definition of Variable-Size Cell Array by Using cell.
To specify upper bounds for the cell array, use
coder.varsize
.function mycell(n) %#codegen x = cell(1,n); for i = 1:n x{i} = i; coder.varsize('x',[1,20]); end end
Definition of Variable-Size Cell Array by Using cell
For code generation, before you use a cell array element, you
must assign a value to it. When you use cell
to
create a variable-size cell array, for example, cell(1,n)
, MATLAB assigns
an empty matrix to each element. However, for code generation, the
elements are unassigned. For code generation, after you use cell
to
create a variable-size cell array, you must assign all
elements of the cell array before any
use of the cell array. For example:
function z = mycell(n, j) %#codegen assert(n < 100); x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
The code generator analyzes your code to determine whether
all elements are assigned before the first use of
the cell array. If the code generator detects that
some elements are not assigned, code generation
fails with an error message. For example, modify the upper bound of the
for
-loop to j
.
function z = mycell(n, j) %#codegen assert(n < 100); x = cell(1,n); for i = 1:j %<- Modified here x{i} = i; end z = x{j}; end
With this modification and with inputs j
less than
n
, the function does not assign values to
all of the cell array elements. Code generation
produces the error:
Unable to determine that every element of 'x{:}' is assigned before this line.
Sometimes, even though your code assigns all elements of the cell array, the code generator reports this message because the analysis does not detect that all elements are assigned. See Unable to Determine That Every Element of Cell Array Is Assigned.
To avoid this error, follow these guidelines:
When you use
cell
to define a variable-size cell array, write code that follows this pattern:function z = mycell(n, j) %#codegen assert(n < 100); x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Here is the pattern for a multidimensional cell array:
function z = mycell(m,n,p) %#codegen assert(m < 100); assert(n < 100); assert(p < 100); x = cell(m,n,p); for i = 1:m for j =1:n for k = 1:p x{i,j,k} = i+j+k; end end end z = x{m,n,p}; end
Increment or decrement the loop counter by
1
.Define the cell array within one loop or one set of nested loops. For example, this code is not allowed:
function z = mycell(n, j) assert(n < 50); assert(j < 50); x = cell(1,n); for i = 1:5 x{i} = 5; end for i = 6:n x{i} = 5; end z = x{j}; end
Use the same variables for the cell dimensions and loop initial and end values. For example, code generation fails for the following code because the cell creation uses
n
and the loop end value usesm
:function z = mycell(n, j) assert(n < 50); assert(j < 50); x = cell(1,n); m = n; for i = 1:m x{i} = 2; end z = x{j}; end
Rewrite the code to use
n
for the cell creation and the loop end value:function z = mycell(n, j) assert(n < 50); assert(j < 50); x = cell(1,n); for i = 1:n x{i} = 2; end z = x{j}; end
Create the cell array with this pattern:
x = cell(1,n)
Assign the cell array to a field of a structure or a property of an object by initializing a temporary variable with the required cell. For example:
Do not assign a cell array to a field of a structure or a property of an object directly. For example, this code is not allowed:t = cell(1,n) for i = 1:n t{i} = i+1; end myObj.prop = t;
myObj.prop = cell(1,n); for i = 1:n myObj.prop{i} = i+1; end
Do not use the
cell
function inside the cell array constructor{}
. For example, this code is not allowed:x = {cell(1,n)};
The cell array creation and the loop that assigns values to the cell array elements must be together in a unique execution path. For example, the following code is not allowed.
function z = mycell(n) assert(n < 100); if n > 3 c = cell(1,n); else c = cell(n,1); end for i = 1:n c{i} = i; end z = c{n}; end
To fix this code, move the assignment loop inside the code block that creates the cell array.
function z = cellerr(n) assert(n < 100); if n > 3 c = cell( 1,n); for i = 1:n c{i} = i; end else c = cell(n,1); for i = 1:n c{i} = i; end end z = c{n}; end
Cell Array Indexing
You cannot index cell arrays by using smooth parentheses
()
. Consider indexing cell arrays by using curly braces{}
to access the contents of the cell.You must index into heterogeneous cell arrays by using constant indices or by using
for
-loops with constant bounds.For example, the following code is not allowed.
x = {1, 'mytext'}; disp(x{randi});
You can index into a heterogeneous cell array in a
for
-loop with constant bounds because the code generator unrolls the loop. Unrolling creates a separate copy of the loop body for each loop iteration, which makes the index in each loop iteration constant. However, if thefor
-loop has a large body or it has many iterations, the unrolling can increase compile time and generate inefficient code.If
A
andB
are constant, the following code shows indexing into a heterogeneous cell array in afor
-loop with constant bounds.x = {1, 'mytext'}; for i = A:B disp(x{i}); end
Growing a Cell Array by Using {end + 1}
To grow a cell array X
, you can use X{end
+ 1}
. For example:
... X = {1 2}; X{end + 1} = 'a'; ...
When you use {end + 1}
to grow a cell array,
follow these restrictions:
In a MATLAB Function block, do not use
{end + 1}
in afor
-loop.Use only
{end + 1}
. Do not use{end + 2}
,{end + 3}
, and so on.Use
{end + 1}
with vectors only. For example, the following code is not allowed becauseX
is a matrix, not a vector:... X = {1 2; 3 4}; X{end + 1} = 5; ...
Use
{end + 1}
only with a variable. In the following code,{end + 1}
does not cause{1 2 3}
to grow. In this case, the code generator treats{end + 1}
as an out-of-bounds index intoX{2}
.... X = {'a' { 1 2 3 }}; X{2}{end + 1} = 4; ...
When
{end + 1}
grows a cell array in a loop, the cell array must be variable-size. Therefore, the cell array must be homogeneous.This code is allowed because
X
is homogeneous.... X = {1 2}; for i=1:n X{end + 1} = 3; end ...
This code is not allowed because
X
is heterogeneous.... X = {1 'a' 2 'b'}; for i=1:n X{end + 1} = 3; end ...
Cell Array Contents
Cell arrays cannot contain mxarrays
. In a
cell array, you cannot store a value that an extrinsic function returns.
Passing Cell Arrays to External C/C++ Functions
You cannot pass a cell array to coder.ceval
.
If a variable is an input argument to coder.ceval
,
define the variable as an array or structure instead of as a cell
array.
Use in MATLAB Function Block
You cannot use cell arrays for Simulink® signals, parameters, or data store memory.