Для генерации кода, прежде чем использовать переменные в операциях или возвращать их в качестве выходов, необходимо назначить им определенный класс, размер и сложность. Как правило, после первоначального присвоения вы не можете переназначить свойства переменной. Поэтому после назначения фиксированного размера полю переменной или структуре попытка увеличить поле переменной или структуры может вызвать ошибку компиляции. В этих случаях необходимо явным образом определить данные как переменный размер с помощью одного из следующих методов.
Метод | Посмотрите |
---|---|
Назначьте данные из матричного конструктора переменного размера, такого как: | Используйте матричный конструктор с неконстантными размерностями |
Присвойте несколько постоянных размеров одной и той же переменной перед использованием (чтением) переменной. | Присвоение нескольких размеров одной и той же переменной |
Задайте, чтобы все образцы переменной были переменного размера. | Явное определение данных переменного размера при помощи 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
. При необходимости можно также указать, какие размерности варьируются вместе с их верхними границами. Для примера:
Определите B
как 2-мерный массив переменного размера, где каждая размерность имеет верхнюю границу 64.
coder.varsize('B', [64 64]);
Определите B
как массив переменного размера:
coder.varsize('B');
Когда вы поставляете только первый аргумент, coder.varsize
принимает, что все размерности B
может варьироваться, и что верхняя граница size(B)
.
Если входной или выходной сигнал MATLAB Function блока имеет переменный размер, в Ports and Data Manager необходимо указать, что сигнал имеет переменный размер. Необходимо также указать верхние границы. Вы не должны использовать coder.varsize
с соответствующей входной или выходной переменной внутри блока MATLAB Function. Однако, если вы задаете верхние границы с coder.varsize
они должны совпадать с верхними границами в Диспетчере портов и данных.
Вы можете использовать функцию coder.varsize
чтобы указать, какие размерности варьируются. Для примера следующий оператор определяет B
как массив, чья первая размерность фиксирован на 2, но чьё второе измерение может вырасти до размера 16:
coder.varsize('B',[2, 16],[0 1])
Третий аргумент определяет, какие размерности варьируются. Этот аргумент должен быть логическим вектором или двойным вектором, содержащим только нули и таковые. Размерности, которые соответствуют нулям или false
имеют фиксированный размер. Размерности, которые соответствуют таковым или true
варьируются в размере. coder.varsize
обычно обрабатывает размерности размера 1 как фиксированные. См. «Определение матриц переменного размера с синглтонными размерностями».
Для входа или выхода сигнала, если вы задаете верхние границы с coder.varsize
внутри блока MATLAB Function они должны совпадать с верхними границами в Ports и Data Manager.
Функциональные 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
чтобы иметь переменный размер.