Задайте данные переменного размера для генерации кода

Для генерации кода, прежде чем использовать переменные в операциях или возвращать их в качестве выходов, необходимо назначить им определенный класс, размер и сложность. Как правило, после первоначального присвоения вы не можете переназначить свойства переменной. Поэтому после назначения фиксированного размера полю переменной или структуре попытка увеличить поле переменной или структуры может вызвать ошибку компиляции. В этих случаях необходимо явным образом определить данные как переменный размер с помощью одного из следующих методов.

МетодПосмотрите

Назначьте данные из матричного конструктора переменного размера, такого как:

Используйте матричный конструктор с неконстантными размерностями
Присвойте несколько постоянных размеров одной и той же переменной перед использованием (чтением) переменной.Присвоение нескольких размеров одной и той же переменной
Задайте, чтобы все образцы переменной были переменного размера.Явное определение данных переменного размера при помощи coder.varsize

Используйте матричный конструктор с неконстантными размерностями

Можно задать матрицу переменного размера при помощи конструктора с неконстантными размерностями. Для примера:

function s = var_by_assign(u) %#codegen
y = ones(3,u);
s = numel(y);

Если вы не используете динамическое выделение памяти, вы также должны добавить assert оператор для задания верхних границ для размерностей. Для примера:

function s = var_by_assign(u) %#codegen
assert (u < 20);
y = ones(3,u);
s = numel(y);

Присвоение нескольких размеров одной и той же переменной

Перед использованием (read) переменной в коде можно сделать ее переменным размером, присвоив ей несколько постоянных размеров. Когда генератор кода использует статическое распределение в стеке, он выводит верхние границы из наибольшего размера, заданного для каждой размерности. Когда вы присваиваете тот же размер данной размерности во всех назначениях, генератор кода принимает, что размерность фиксирована на этом размере. Назначения могут задавать различные формы и размеры.

Когда генератор кода использует динамическое выделение памяти, он не проверяет верхние границы. Он принимает, что данные переменного размера неограниченны.

Вывод верхних границ из нескольких определений с различными формами

function s = var_by_multiassign(u) %#codegen
if (u > 0)
    y = ones(3,4,5);
else
    y = zeros(3,1);
end
s = numel(y);

Когда генератор кода использует статическое распределение, это делает вывод, что y является матрицей с тремя размерностями:

  • Первая размерность фиксируется на размере 3

  • Второе измерение переменного размера с верхней границей 4

  • Третья размерность переменного размера с верхней границей 5

Когда генератор кода использует динамическое распределение, он анализирует размерности y по-разному:

  • Первая размерность фиксируется при размере 3.

  • Вторые и третьи размерности неограниченны.

Явное определение данных переменного размера при помощи coder.varsize

Чтобы явным образом задать данные переменного размера, используйте функцию coder.varsize. При необходимости можно также указать, какие размерности варьируются вместе с их верхними границами. Для примера:

  • Определите B как 2-мерный массив переменного размера, где каждая размерность имеет верхнюю границу 64.

    coder.varsize('B', [64 64]);

  • Определите B как массив переменного размера:

    coder.varsize('B');

    Когда вы поставляете только первый аргумент, coder.varsize принимает, что все размерности B может варьироваться, и что верхняя граница size(B).

Задайте, какие размерности варьируются

Вы можете использовать функцию coder.varsize чтобы указать, какие размерности варьируются. Для примера следующий оператор определяет B как массив, чья первая размерность фиксирован на 2, но чьё второе измерение может вырасти до размера 16:

coder.varsize('B',[2, 16],[0 1])
.

Третий аргумент определяет, какие размерности варьируются. Этот аргумент должен быть логическим вектором или двойным вектором, содержащим только нули и таковые. Размерности, которые соответствуют нулям или false имеют фиксированный размер. Размерности, которые соответствуют таковым или true варьируются в размере. coder.varsize обычно обрабатывает размерности размера 1 как фиксированные. См. «Определение матриц переменного размера с синглтонными размерностями».

Разрешить переменной расти после определения фиксированных размерностей

Функциональные var_by_if задает матрицу Y с фиксированными размерностями 2 на 2 перед первым использованием (где оператор Y = Y + u читает из Y). Однако, coder.varsize определяет Y как матрица переменного размера, позволяющая ей изменять размер на основе логики принятия решений в else пункт:

function Y = var_by_if(u) %#codegen
if (u > 0)
    Y = zeros(2,2);
    coder.varsize('Y');
    if (u < 10)
        Y = Y + u;
    end
else
    Y = zeros(5,5);
end

Без coder.varsizeГенератор кода выводит Y быть матрицей фиксированного размера 2 на 2. Это генерирует ошибку несоответствия размера.

Задайте матрицы переменного размера с синглтонными размерностями

Синглтонная размерность является размерностью, для которой size(A,dim) = 1. Размерности Singleton фиксируются в размере, когда:

  • Вы задаете размерность с верхней границей 1 дюйм coder.varsize выражения.

    Для примера в этой функции Y ведет себя как вектор с одной размерностью переменной:

    function Y = dim_singleton(u) %#codegen
    Y = [1 2];
    coder.varsize('Y', [1 10]);
    if (u > 0)
        Y = [Y 3];
    else
        Y = [Y u];
    end
    

  • Вы инициализируете данные переменного размера с синглтонными размерностями с помощью матричных выражений конструктора или матричных функций.

    Для примера в этой функции X и Y вести себя как векторы, где только их вторые измерения переменного размера.

    function [X,Y] = dim_singleton_vects(u) %#codegen
    Y = ones(1,3);
    X = [1 4];
    coder.varsize('Y','X');
    if (u > 0)
        Y = [Y u];
    else
        X = [X u];
    end

Вы можете переопределить это поведение при помощи coder.varsize чтобы явным образом указать, что одиночные размерности варьируются. Для примера:

function Y = dim_singleton_vary(u) %#codegen
Y = [1 2];
coder.varsize('Y', [1 10], [1 1]);
if (u > 0)
    Y = [Y Y+u];
else
    Y = [Y Y*u];
end

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

Задайте структурные поля переменного размера

Чтобы задать поля структуры как массивы переменного размера, используйте двоеточие (:) как индекс выражение. Двоеточие (:) указывает, что все элементы массива имеют переменный размер. Для примера:

function y=struct_example() %#codegen

d = struct('values', zeros(1,0), 'color', 0);
data = repmat(d, [3 3]);
coder.varsize('data(:).values');

for i = 1:numel(data)
    data(i).color = rand-0.5;
    data(i).values = 1:i;
end

y = 0;
for i = 1:numel(data)
    if data(i).color > 0
        y = y + sum(data(i).values);
    end
end

Выражение coder.varsize('data(:).values') определяет поле values внутри каждого элемента матрицы data чтобы иметь переменный размер.

Вот другие примеры:

  • coder.varsize('data.A(:).B')

    В этом примере data - переменный скаляр, содержащая матрицу A. Каждый элемент матрицы A содержит поле переменного размера B.

  • coder.varsize('data(:).A(:).B')

    Это выражение определяет поле B внутри каждого элемента матрицы A внутри каждого элемента матрицы data чтобы иметь переменный размер.

См. также

|

Похожие темы