When you use cell arrays in MATLAB® code that is intended for code generation, you must adhere to these restrictions:
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
coder.varsize
is not supported for heterogeneous cell
arrays.
If you use the cell
function to define a
fixed-size cell array, you cannot use coder.varsize
to
specify that the cell array has a variable size. For example, this code
causes a code generation error because x = cell(1,3)
makes x
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
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 uses m
:
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)
Do not assign the cell array to a field of a structure or a property of an object. For example, this code is not allowed:
myobj.prop = cell(1,n) for i = 1:n ... 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
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
the for
-loop has a large body or it has many
iterations, the unrolling can increase compile time and generate inefficient
code.
If A
and B
are constant,
the following code shows indexing into a heterogeneous cell array
in a for
-loop with constant bounds.
x = {1, 'mytext'}; for i = A:B disp(x{i}); end
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 a for
-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 because X
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 into X{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 arrays cannot contain mxarrays
. In a
cell array, you cannot store a value that an extrinsic function returns.
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.
You cannot use cell arrays for Simulink® signals, parameters, or data store memory.