Main Content

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 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
To avoid this error, initialize the cell array by using a temporary variable. Then, assign the initialized cell array to the structure field or object property. You can then modify the elements of the cell array by accessing the structure field or object property directly.
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 function growMatrixError because ca 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 for growArraySubscriptError fails because {end + 1} appears next to ca{2}, not next to ca.

    function out = growArraySubscriptError(x) %#codegen
    ca = {'a' { 1 2 3 }};
    ca{2}{end+1} = x;
    out = ca{2}{4};
    end
    To resolve this issue, set the element of the cell array that you want to modify equal to a temporary variable. Then, use {end + 1} to grow the temporary variable. Use coder.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 function growHeterogeneousError because cell array ca contains elements of type string and type double.

    function out = growHeterogeneousError(n) %#codegen
    ca = {1  2 "a"};
    for i = 1:n
        ca{end+1} = 3+i;
    end
    out = ca;
    end
    To learn more about how the code generator handles homogenous and heterogeneous cell arrays, see Code Generation for Cell Arrays.

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. If a cell array is an input argument to coder.ceval, redefine the cell array as an ordinary array or a structure.

Related Topics