Вы видите одно из этих сообщений:
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 = 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
Если генератор кода обнаруживает, что некоторые элементы не присвоены, сбои генерации кода. Иногда, даже при том, что ваш код присваивает все элементы массива ячеек, сбои генерации кода, потому что анализ не обнаруживает, что все элементы присвоены.
Вот примеры, где генератор кода не может обнаружить, что элементы присвоены:
Элементы присвоены в различных циклах
... 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 = mycell2(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 = mycell2(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
coder.nullcopy
Как последнее прибежище можно использовать coder.nullcopy
, чтобы указать, что генератор кода может выделить память для массива ячеек, не инициализируя память. Например:
function z = mycell3(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