Ограничения массива ячеек для генерации кода

Когда вы используете массивы ячеек в коде 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

Определение массива ячеек Переменного Размера при помощи 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

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

Unable to determine that every element of 'y' 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

Индексация массива ячеек

  • Вы не можете индексировать массивы ячеек при помощи сглаженного parentheses(). Полагайте, что массивы ячеек индексации при помощи изогнутого braces{} получают доступ к содержимому ячейки.

  • Необходимо индексировать в неоднородные массивы ячеек при помощи постоянных индексов или при помощи for - циклы с постоянными границами.

    Например, следующий код не позволен.

    x = {1, 'mytext'};
    disp(x{randi});

    Можно индексировать в неоднородный массив ячеек в for - цикл с постоянными границами, потому что генератор кода разворачивает цикл. Разворачивание создает отдельную копию тела цикла для каждой итерации цикла, которая делает индекс в каждой итерации цикла постоянным. Однако, если for - цикл имеет большое тело, или это имеет много итераций, разворачивание может увеличить время компиляции и сгенерировать неэффективный код.

    Если A и B являются постоянными, следующий код показывает индексацию в неоднородный массив ячеек в for - цикл с постоянными границами.

    x = {1, 'mytext'};
    for i = A:B
    	 disp(x{i});
    end

Рост массива ячеек при помощи {заканчивается + 1}

Чтобы вырастить массив ячеек 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
    ...

Переменный размер Массивы ячеек

  • Неоднородные массивы ячеек не могут быть переменным размером.

  • При использовании coder.varsize, чтобы сделать массив ячеек переменного размера, задайте массив ячеек с фигурными скобками. Например:

    ...
    c = {1 [2 3]};
    coder.varsize('c')
    ...

    Не используйте функцию cell. Например, этот код не позволен:

    ...
    c = cell(1,3);
    coder.varsize('c')
    ...

Содержимое массива ячеек

Массивы ячеек не могут содержать mxarrays. В массиве ячеек вы не можете сохранить значение, которое возвращает внешняя функция.

Передающие Массивы ячеек к Внешним Функциям C/C++

Вы не можете передать массив ячеек coder.ceval. Если переменная является входным параметром к coder.ceval, задайте переменную как массив или структуру вместо как массив ячеек.

Используйте в блоке MATLAB function

Вы не можете использовать массивы ячеек для сигналов Simulink®, параметров или памяти хранилища данных.

Похожие темы

Была ли эта тема полезной?