Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use - MATLAB & Simulink (original) (raw)
Issue
Unlike MATLABĀ®, which is a dynamically typed language, C and C++ are statically typed. This means that the code generator must be able to determine the types of all variables in your MATLAB code so that it can define variables in the generated code. When you use the cell function to create a 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 cell arrays created using thecell
function.
If the code generator is unable to determine the types of all elements of all cell arrays in your MATLAB code, you see an error message containing this sentence:
For code generation, all cell array elements must be fully defined before use.
Even though your MATLAB code assigns values to all elements of a cell array, code generation can fail for certain coding patterns because the code generator is unable to recognize that all cell array elements are assigned. These coding patterns include:
- You assign initial values to cell array elements in different loops. For example, consider the function
cellArrayAssignmentError1
. MATLAB populates cell arrayca
for all values ofn
. However, code generation forcellArrayAssignmentError1
fails because the code generator is unable to determine that all cell array elements are defined for all values ofn
.
function out = cellArrayAssignmentError1(n) %#codegen
ca = cell(1,n);
for i = 1:5
ca{i} = 5;
end
for i = 6:n
ca{i} = i;
end
out = ca{n};
end - The variable that you use to construct the cell array using
cell
differs from the variable that you use to control thefor
-loop in which you assign initial values to the cell array elements. For example, consider the functioncellArrayAssignmentError2
. MATLAB populates cell arrayca
for all values ofn
. However, code generation forcellArrayAssignmentError2
fails because the code generator is unable to determine that all cell array elements are defined for all values ofn
.
function out = cellArrayAssignmentError2(n) %#codegen
ca = cell(1,n);
counter = n;
for i = 1:counter
ca{i} = 2*i;
end
out = ca{n};
end - In the
for
-loop you use to assign initial values to the cell array elements, you increment or decrement the loop counter by a number other than1
. For example, consider the functioncellArrayAssignmentError3
. MATLAB populates cell arrayca
for all values ofn
. However, code generation forcellArrayAssignmentError3
fails because the code generator is unable to determine that all elements ofca
have been defined for all values ofn
.
function out = cellArrayAssignmentError3(n) %#codegen
ca = cell(1,n2);
for i = 1:2:n2-1
ca{i} = 1;
ca{i+1} = 2;
end
out = ca{n};
end - You assign initial values to cell array elements using subscript or dot indexing. For example, consider the function
cellArrayAssignmentError4
. MATLAB populates cell arrayca
. However, code generation forcellArrayAssignmentError4
fails because the code generator is unable to subscript intoca
before all of the elements ofca
have been defined.
function out = cellArrayAssignmentError4 %#codegen
ca = cell(1,3);
for j = 1:3
ca{j}(1) = 10;
ca{j}(2) = 20;
ca{j}(3) = 30;
end
out = ca{2};
end
Possible Solutions
To resolve this issue, try one of these solutions.
Use a recognized coding pattern to assign cell array elements
Assign values to the elements of the cell array using a coding pattern that the code generator can recognize. If you use a for
-loop to assign initial values to the cell array elements and the cell array is variable-size, make sure that you:
- Assign initial values to all elements in the same loop.
- Use the same variable for the loop counter as you used in the
cell
function to create the cell array. - Increment or decrement the loop counter by
1
.
To assign a scalar value to each element of a 1-by-n
cell array, follow this pattern.
function out = codingPatternExample1(n) %#codegen
ca = cell(1,n);
for i = 1:n
ca{i} = sqrt(i);
end
out = ca{n};
end
To assign an array of values to each element of a 1-by-n
cell array, assign arrays of values to each element in a single statement. Do not use subscripted or dot assignments.
function out = codingPatternExample2(n) %#codegen
ca = cell(1,n);
for i = 1:n
ca{i} = [sqrt(i) i i^2];
end
out = ca{n};
end
To assign a value to each element of a multidimensional cell array, use nested loops. For example, use this coding pattern for a three-dimensional (m
-by-n
-by-p
) array.
function out = codingPatternExample3(m,n,p) %#codegen ca = cell(m,n,p); for i = 1:m for j =1:n for k = 1:p ca{i,j,k} = i+j+k; end end end out = ca{m,n,p}; end
Use the repmat
function
The repmat function takes an input array and replicates it a specified number of times in the row and column dimensions to construct an output array. In certain cases where your cell array contains repeating elements, you can rewrite your code to define the elements of a cell array by using repmat
. For example, consider the functionrepmatAssignmentError
, which creates a 1-by-(n*2)
cell array using the cell
function. repmatAssignmentError
assigns 1
to the odd elements of ca
and 0
to the even elements. Code generation fails for this function because initial values are assigned to the cell array elements in different for
-loops and because the loop counters increment by a value other than 1.
function out = repmatAssignmentError(n) %#codegen ca = cell(1,n2); for i = 1:2:n2 ca{i} = 1; end for i = 2:2:n*2 ca{i} = 0; end out = ca{n}; end
To resolve this issue, first use the cell
function to create a temporary 1-by-2 cell array whose first element is 1 and whose second element is 0. Then, use the repmat
function to create a 1-by-(n*2)
cell array whose element values alternate between 1 and 2.
function out = repmatAssignmentExample(n) %#codegen tmp = cell(1,2); tmp{1} = 1; tmp{2} = 0; ca = repmat(tmp,1,n); out = ca{n}; end
Use coder.nullcopy
You can use the coder.nullcopy function to preallocate memory for a homogenous cell array without specifically assigning values to the cell array elements. In general, homogenous cell arrays contain elements that are all of the same type, such asdouble
or string
. However, under certain circumstances, the code generator can classify the same cell array as homogenous in some contexts but as heterogeneous in other contexts. See Code Generation for Cell Arrays.
If you use coder.nullcopy
to define a homogenous cell array, you can generate code without having to adhere to the recognized coding patterns described above. For example, consider the functionnullcopyExample
. Because this function usescoder.nullcopy
to preallocate memory for homogenous cell array ca
, you can assign values to the cell array in two separate loops.
function out = nullcopyExample(n) %#codegen tmp = cell(1,n); ca = coder.nullcopy(tmp); for i = 1:4 ca{i} = 0; end for i = 5:n ca{i} = i; end out = ca{n}; end
Note
Use coder.nullcopy
with caution. You must make sure that you assign values to all elements in your cell array. If you access uninitialized cell array elements, the results can be unpredictable.
See Also
cell | repmat | coder.nullcopy