exponenta event banner

Определение данных переменного размера для создания кода

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

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

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

Использование конструктора матрицы с непостоянными размерами
Перед использованием (считыванием) переменной назначьте ей несколько постоянных размеров.Назначение нескольких размеров одной и той же переменной
Определите все экземпляры переменной с переменным размером.Явное определение данных переменного размера с помощью 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);

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

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

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

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

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 как двумерный массив переменного размера, где каждый размер имеет верхнюю границу 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. Размеры одиночки фиксируются по размеру при:

  • Задается размер с верхней границей 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 должен быть переменного размера.

См. также

|

Связанные темы