Когда вы используете массивы ячеек в коде 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
coder.varsize
не поддерживается для неоднородных массивов ячеек.
Если вы используете cell
функция, чтобы задать массив ячеек фиксированного размера, вы не можете использовать coder.varsize
указывать, что массив ячеек имеет переменный размер. Например, этот код вызывает ошибку генерации кода потому что x = cell(1,3)
делает x
фиксированный размер, 1 3 массив ячеек.
... x = cell(1,3); coder.varsize('x',[1 5]) ...
Можно использовать coder.varsize
с массивом ячеек, который вы задаете при помощи фигурных скобок. Например:
... x = {1 2 3}; coder.varsize('x',[1 5]) ...
Создать массив ячеек переменного размера при помощи cell
функция, используйте этот шаблон кода:
function mycell(n) %#codegen x = cell(1,n); for i = 1:n x{i} = i; end end
См. Определение Массива ячеек Переменного Размера при помощи ячейки.
Чтобы задать верхние границы для массива ячеек, использовать coder.varsize
.
function mycell(n) %#codegen x = cell(1,n); for i = 1:n x{i} = i; coder.varsize('x',[1,20]); end 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
Генератор кода анализирует ваш код, чтобы определить, присвоены ли все элементы перед первым использованием массива ячеек. Если генератор кода обнаруживает, что некоторые элементы не присвоены, сбои генерации кода с сообщением об ошибке. Например, измените верхнюю границу for
- цикл к j
.
function z = mycell(n, j) %#codegen x = cell(1,n); for i = 1:j %<- Modified here x{i} = i; end z = x{j}; end
С этой модификацией и с входными параметрами j
меньше, чем n
, функция не присваивает значения всем элементам массива ячеек. Генерация кода производит ошибку:
Unable to determine that every element of 'x{:}' 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});
Можно индексировать в неоднородный массив ячеек в a for
- цикл с постоянными границами, потому что генератор кода разворачивает цикл. Разворачивание создает отдельную копию тела цикла для каждой итерации цикла, которая делает индекс в каждой итерации цикла постоянным. Однако, если for
- цикл имеет большое тело, или он имеет много итераций, разворачивание может увеличить время компиляции и сгенерировать неэффективный код.
Если A
и B
являются постоянными, следующий код показывает индексацию в неоднородный массив ячеек в a 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 ...
Массивы ячеек не могут содержать mxarrays
. В массиве ячеек вы не можете сохранить значение, которое возвращает внешняя функция.
Вы не можете передать массив ячеек coder.ceval
. Если переменная является входным параметром к coder.ceval
, задайте переменную как массив или структуру вместо как массив ячеек.