Когда вы используете массивы ячеек в коде MATLAB®, который предназначается для генерации кода, необходимо придерживаться этих ограничений:
Необходимо присвоить элемент массива ячеек на всех путях к выполнению, прежде чем вы будете использовать его. Например:
function z = foo(n) %#codegen c = cell(1,3); if n < 1 c{2} = 1; else c{2} = n; end z = c{2}; end
Генератор кода рассматривает передачу массива ячеек к функции или возврату его от функции как использование всех элементов массива ячеек. Поэтому, прежде чем вы передаете массив ячеек функции или возвращаете его в функцию, необходимо присвоить все ее элементы. Например, следующий код не позволен, потому что он не присваивает значение c{2}
, и c
является функциональный вывод.
function c = foo() %#codegen c = cell(1,3); c{1} = 1; c{3} = 3; end
Присвоение значений к элементам должно быть сопоставимым на всех путях к выполнению. Следующий код не позволен, потому что y{2}
двойной на одном пути к выполнению и char на другом пути к выполнению.
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
cell
Для генерации кода, прежде чем вы будете использовать элемент массива ячеек, необходимо присвоить значение ему. Когда вы используете cell
, чтобы создать массив ячеек переменного размера, например, cell(1,n)
, MATLAB присваивает пустую матрицу каждому элементу. Однако для генерации кода, элементы являются неприсвоенными. Для генерации кода, после того, как вы будете использовать cell
, чтобы создать массив ячеек переменного размера, необходимо присвоить все элементы массива ячеек перед любым использованием массива ячеек. Например:
function z = mycell(n, j) %#codegen x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Генератор кода анализирует ваш код, чтобы определить, присвоены ли все элементы перед первым использованием массива ячеек. Если генератор кода обнаруживает, что некоторые элементы не присвоены, сбои генерации кода с сообщением как это сообщение:
Unable to determine that every element of 'y' is assigned before this line.
Иногда, даже при том, что ваш код присваивает все элементы массива ячеек, генератор кода сообщает об этом сообщении, потому что анализ не обнаруживает, что все элементы присвоены. Смотрите Не могущий Решить, Что Каждый Элемент Массива ячеек Присвоен.
Чтобы избежать этой ошибки, следуйте этим инструкциям:
Когда вы используете cell
, чтобы задать массив ячеек переменного размера, запишите код, который следует за этим шаблоном:
function z = mycell(n, j) %#codegen x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Вот шаблон для многомерного массива ячеек:
function z = mycell(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
Постепенно увеличьте или постепенно уменьшите счетчик цикла 1
.
Задайте массив ячеек в одном цикле или одном наборе вложенных циклов. Например, этот код не позволен:
function z = mycell(n, j) x = cell(1,n); for i = 1:5 x{i} = 5; end for i = 6:n x{i} = 5; end z = x{j}; end
Используйте те же переменные для размерностей ячейки и начальной буквы цикла и значений конца. Например, генерация кода перестала работать для следующего кода, потому что создание ячейки использует n
, и значение конца цикла использует m
:
function z = mycell(n, j) x = cell(1,n); m = n; for i = 1:m x{i} = 2; end z = x{j}; end
Перепишите код, чтобы использовать n
для создания ячейки и значения конца цикла:
function z = mycell(n, j) x = cell(1,n); for i = 1:n x{i} = 2; end z = x{j}; end
Создайте массив ячеек с этим шаблоном:
x = cell(1,n)
Не присваивайте массив ячеек полю структуры или свойству объекта. Например, этот код не позволен:
myobj.prop = cell(1,n) for i = 1:n ... end
Не используйте функцию cell
в конструкторе массива ячеек {}
. Например, этот код не позволен:
x = {cell(1,n)};
Создание массива ячеек и цикл, который присваивает значения элементам массива ячеек, должны быть вместе в уникальном пути к выполнению. Например, следующий код не позволен.
function z = mycell(n) 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
Чтобы зафиксировать этот код, переместите цикл присвоения в блоке кода, который создает массив ячеек.
function z = cellerr(n) 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
Вы не можете индексировать массивы ячеек при помощи сглаженного parentheses()
. Полагайте, что массивы ячеек индексации при помощи изогнутого braces{}
получают доступ к содержимому ячейки.
Необходимо индексировать в неоднородные массивы ячеек при помощи постоянных индексов или при помощи for
- циклы с постоянными границами.
Например, следующий код не позволен.
x = {1, 'mytext'};
disp(x{randi});
Можно индексировать в неоднородный массив ячеек в for
- цикл с постоянными границами, потому что генератор кода разворачивает цикл. Разворачивание создает отдельную копию тела цикла для каждой итерации цикла, которая делает индекс в каждой итерации цикла постоянным. Однако, если for
- цикл имеет большое тело, или это имеет много итераций, разворачивание может увеличить время компиляции и сгенерировать неэффективный код.
Если A
и B
являются постоянными, следующий код показывает индексацию в неоднородный массив ячеек в for
- цикл с постоянными границами.
x = {1, 'mytext'}; for i = A:B disp(x{i}); end
Чтобы вырастить массив ячеек X
, можно использовать X{end + 1}
. Например:
... X = {1 2}; X{end + 1} = 'a'; ...
Когда вы используете {end + 1}
, чтобы вырастить массив ячеек, следовать за этими ограничениями:
Используйте только {end + 1}
. Не используйте {end + 2}
, {end + 3}
, и так далее.
Используйте {end + 1}
с векторами только. Например, следующий код не позволен, потому что X
является матрицей, не вектором:
... X = {1 2; 3 4}; X{end + 1} = 5; ...
Используйте {end + 1}
только с переменной. В следующем коде {end + 1}
не заставляет {1 2 3}
, растут. В этом случае генератор кода обрабатывает {end + 1}
как за пределы индекс в X{2}
.
... X = {'a' { 1 2 3 }}; X{2}{end + 1} = 4; ...
Когда {end + 1}
выращивает массив ячеек в цикле, массив ячеек должен быть переменным размером. Поэтому массив ячеек должен быть гомогенным.
Этот код позволен, потому что X
гомогенный.
... X = {1 2}; for i=1:n X{end + 1} = 3; end ...
Этот код не позволен, потому что X
неоднороден.
... X = {1 'a' 2 'b'}; for i=1:n X{end + 1} = 3; end ...
Неоднородные массивы ячеек не могут быть переменным размером. Смотрите Управление, Является ли Массив ячеек Переменным Размером.
При использовании coder.varsize
, чтобы сделать массив ячеек переменного размера, задайте массив ячеек с фигурными скобками. Например:
... c = {1 [2 3]}; coder.varsize('c') ...
Не используйте функцию cell
. Например, этот код не позволен:
... c = cell(1,3); coder.varsize('c') ...
Массивы ячеек не могут содержать mxarrays
. В массиве ячеек вы не можете сохранить значение, которое возвращает внешняя функция.
Вы не можете передать массив ячеек coder.ceval
. Если переменная является входным параметром к coder.ceval
, задайте переменную как массив или структуру вместо как массив ячеек.