Unable to Determine That Every Element of Cell Array Is Assigned
Issue
You see one of these messages:
Unable to determine that every element of 'y' is assigned before this line.
Unable to determine that every element of 'y' is assigned before exiting the function.
Unable to determine that every element of 'y' is assigned before exiting the recursively called function.
Cause
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.
The code generator analyzes your code to determine whether all elements are assigned before the first use of the cell array. The code generator detects that all elements are assigned when the code follows this pattern:
function z = CellVarSize1D(n, j) %#codegen 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 = CellAssign3D(m,n,p) %#codegen 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
If the code generator detects that some elements are not assigned, code generation fails. Sometimes, even though your code assigns all elements of the cell array, code generation fails because the analysis does not detect that all elements are assigned.
Here are examples where the code generator is unable to detect that elements are assigned:
Elements are assigned in different loops
... x = cell(1,n) for i = 1:5 x{i} = 5; end for i = 6:n x{i} = 7; end ...
The variable that defines the loop end value is not the same as the variable that defines the cell dimension.
... x = cell(1,n); m = n; for i = 1:m x{i} = 2; end ...
For more information, see Definition of Variable-Size Cell Array by Using cell.
Solution
Try one of these solutions:
Use recognized pattern for assigning elements
If possible, rewrite your code to follow this pattern:
... x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; ...
Use repmat
Sometimes, you can use repmat
to define the variable-size
cell array.
Consider this code that defines a variable-size cell array. It assigns the value 1 to odd elements and the value 2 to even elements.
function z = repDefine(n, j) %#codegen c =cell(1,n); for i = 1:2:n-1 c{i} = 1; end for i = 2:2:n c{i} = 2; end z = c{j};
Code generation does not allow this code because:
More than one loop assigns the elements.
The loop counter does not increment by 1.
Rewrite the code to first use cell
to create a 1-by-2 cell
array whose first element is 1 and whose second element is 2. Then, use
repmat
to create a variable-size cell array whose element
values alternate between 1 and 2.
function z = repVarSize(n, j) %#codegen c = cell(1,2); c{1} = 1; c{2} = 2; c1= repmat(c,1,n); z = c1{j}; end
You can pass an initially empty, variable-size cell array into or out of a
function by using repmat
. Use the following pattern:
function x = emptyVarSizeCellArray x = repmat({'abc'},0,0); coder.varsize('x'); end
This code indicates that x
is an empty, variable-size cell
array of 1x3
characters that can be passed into or out of
functions.
Use coder.nullcopy
As a last resort, you can use coder.nullcopy
to indicate that
the code generator can allocate the memory for your cell array without initializing
the memory. For example:
function z = nulcpyCell(n, j) %#codegen c =cell(1,n); c1 = coder.nullcopy(c); for i = 1:4 c1{i} = 1; end for i = 5:n c1{i} = 2; end z = c1{j}; end
Use coder.nullcopy
with caution. If you access uninitialized
memory, results are unpredictable.
See Also
cell
| repmat
| coder.nullcopy