Вы видите одно из следующих сообщений:
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.
Для генерации кода, прежде чем вы используете элемент массива ячеек, вы должны назначить ему значение. Когда вы используете cell
чтобы создать массив ячеек переменного размера, например cell(1,n)
, MATLAB® присваивает пустую матрицу каждому элементу. Однако для генерации кода элементы не назначены. Для генерации кода, после того, как вы используете cell
чтобы создать массив ячеек переменного размера, необходимо назначить все элементы массива ячеек перед любым использованием массива ячеек.
Генератор кода анализирует ваш код, чтобы определить, назначены ли все элементы перед первым использованием массива ячеек. Генератор кода обнаруживает, что все элементы назначены, когда код следует этому шаблону:
function z = CellVarSize1D(n, j) %#codegen assert(n < 100); x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Вот шаблон для многомерного массива ячеек:
function z = CellAssign3D(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
Если генератор кода обнаруживает, что некоторые элементы не назначены, генерация кода прекращает работать. Иногда, даже если ваш код присваивает все элементы массива ячеек, генерация кода прекращает работать, поскольку анализ не обнаруживает, что все элементы назначены.
Вот примеры, где генератор кода не может обнаружить, что элементы назначены:
Элементы назначаются в разных циклах
... x = cell(1,n) for i = 1:5 x{i} = 5; end for i = 6:n x{i} = 7; end ...
Переменная, которая задает значение конца цикла, не совпадает с переменной, которая задает размерность камеры.
... x = cell(1,n); m = n; for i = 1:m x{i} = 2; end ...
Для получения дополнительной информации смотрите Определение массива ячеек переменного размера при помощи камеры.
Попробуйте одно из следующих решений:
Если возможно, перепишите код, чтобы следовать этому шаблону:
... x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; ...
repmat
Иногда можно использовать repmat
для определения массива ячеек переменного размера.
Рассмотрим этот код, который задает массив ячеек переменного размера. Значение 1 присваивается нечетным элементам, а значение 2 - четным элементам.
function z = repDefine(n, j) %#codegen assert(n < 100); 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};
Генерация кода не позволяет использовать этот код, поскольку:
Элементы присваиваются более чем одному циклу.
Счетчик цикла не увеличивается на 1.
Перепишите код для первого использования cell
создать массив ячеек 1 на 2, первый элемент которого равен 1, а второй элемент равен 2. Затем используйте repmat
чтобы создать массив ячеек переменного размера, значения элемента которого чередуются между 1 и 2.
function z = repVarSize(n, j) %#codegen assert(n < 100); c = cell(1,2); c{1} = 1; c{2} = 2; c1= repmat(c,1,n); z = c1{j}; end
Можно передать первоначально пустой массив ячеек переменного размера в функцию или из нее при помощи repmat
. Используйте следующий шаблон:
function x = emptyVarSizeCellArray x = repmat({'abc'},0,0); coder.varsize('x'); end
Этот код указывает, что x
- пустой массив ячеек переменного размера 1x3
символы, которые могут быть переданы в функции или из них.
coder.nullcopy
В крайнем случае можно использовать coder.nullcopy
чтобы указать, что генератор кода может выделить память для массива ячеек, не инициализируя память. Для примера:
function z = nulcpyCell(n, j) %#codegen assert(n < 100); 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
Использовать coder.nullcopy
с осторожностью. Если вы получаете доступ к неинициализированной памяти, результаты непредсказуемы.
cell
| coder.nullcopy
| repmat