При использовании массивов ячеек в коде 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} является двойным на одном пути выполнения и символом на другом пути выполнения.
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
Нельзя индексировать массивы ячеек с помощью гладких скобок(). Рассмотрите возможность индексирования массивов ячеек с помощью фигурных фигурных скобок{} для доступа к содержимому ячейки.
Необходимо индексировать в гетерогенные массивы ячеек с помощью константных индексов или с помощью for- контуры с постоянными границами.
Например, следующий код не разрешен.
x = {1, 'mytext'};
disp(x{randi});Можно индексировать в гетерогенный массив ячеек в for-закольцовывание с постоянными границами, поскольку генератор кода разворачивает цикл. При разворачивании создается отдельная копия тела цикла для каждой итерации цикла, что делает индекс в каждой итерации цикла постоянным. Однако, если for-loop имеет большое тело или имеет много итераций, разворачивание может увеличить время компиляции и создать неэффективный код.
Если 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 ...
Массивы ячеек не могут содержать mxarrays. В массиве ячеек нельзя сохранить значение, возвращаемое внешней функцией.
Невозможно передать массив ячеек в coder.ceval. Если переменная является входным аргументом для coder.cevalопределите переменную как массив или структуру, а не как массив ячеек.