Когда вы используете массивы ячеек в 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, использовать этот шаблон кода:
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 assert(n < 100); x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Генератор кода анализирует ваш код, чтобы определить, назначены ли все элементы перед первым использованием массива ячеек. Если генератор кода обнаруживает, что некоторые элементы не назначены, генерация кода прекращает работать с сообщением об ошибке. Например, измените верхнюю границу for
-цикл, чтобы j
.
function z = mycell(n, j) %#codegen assert(n < 100); 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 assert(n < 100); x = cell(1,n); for i = 1:n x{i} = i; end z = x{j}; end
Вот шаблон для многомерного массива ячеек:
function z = mycell(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
Увеличьте или уменьшите счетчик цикла на 1
.
Задайте массив ячеек в одном цикле или в одном наборе вложенных циклов. Для примера этот код не разрешен:
function z = mycell(n, j) assert(n < 50); assert(j < 50); 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) assert(n < 50); assert(j < 50); x = cell(1,n); m = n; for i = 1:m x{i} = 2; end z = x{j}; end
Перепишите код для использования n
для создания камеры и конечного значения цикла:
function z = mycell(n, j) assert(n < 50); assert(j < 50); 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) assert(n < 100); 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) assert(n < 100); 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
Вы не можете индексировать массивы ячеек с помощью сглаженных круглых скобок ()
. Рассмотрите индексацию массивов ячеек при помощи фигурных скобок {}
для доступа к содержимому камеры.
Вы должны индексировать в гетерогенные массивы ячеек с помощью постоянных индексов или с помощью for
- циклы с постоянными границами.
Для примера следующий код не разрешен.
x = {1, 'mytext'};
disp(x{randi});
Можно индексировать в гетерогенный массив ячеек в for
-loop с постоянными границами, потому что генератор кода разворачивает цикл. Unrolling создает отдельную копию тела цикла для каждой итерации цикла, что делает индекс в каждой итерации цикла постоянным. Однако, если 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}
чтобы вырастить массив ячеек, следуйте следующим ограничениям:
В блоке MATLAB Function не используйте {end + 1}
в for
-цикл.
Используйте только {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
, задайте переменную как массив или структуру, а не как массив ячеек.
Вы не можете использовать массивы ячеек для Simulink® сигналы, параметры или память хранилища данных.