Не мог решить, что каждый элемент массива ячеек присвоен

Проблема

Вы видите одно из этих сообщений:

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 = CellVarSize1D(n, j)
%#codegen
assert(n < 100);
x = cell(1,n);   
for i = 1:n
    x{i} = i;
end
z = x{j};
end

Вот шаблон для многомерного массива ячеек:

function z = CellAssign3D(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 = repDefine(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 = repVarSize(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

Можно передать первоначально пустой, массив ячеек переменного размера в или из функции при помощи repmat. Используйте следующий шаблон:

function x = emptyVarSizeCellArray
x = repmat({'abc'},0,0);
coder.varsize('x');
end

Этот код указывает на тот x пустой, массив ячеек переменного размера 1x3 символы, которые могут быть переданы в или из функций.

Использование coder.nullcopy

Как последнее прибежище можно использовать coder.nullcopy указать, что генератор кода может выделить память для вашего массива ячеек, не инициализируя память. Например:

function z = nulcpyCell(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 с осторожностью. Если вы получаете доступ к неинициализированной памяти, результаты непредсказуемы.

Смотрите также

| |

Похожие темы