Для генерации кода, перед использованием переменных в операциях или возврате их как выходные параметры, необходимо присвоить их определенный класс, размер и сложность. Обычно после начального присвоения, вы не можете повторно присвоить переменные свойства. Поэтому после присвоения фиксированного размера к переменной или полю структуры, попытки вырастить переменную или поле структуры могут вызвать ошибку компиляции. В этих случаях необходимо явным образом задать данные как переменный размер при помощи одного из этих методов.
Метод | Смотрите |
---|---|
Присвойте данные от матричного конструктора переменного размера, такого как: | Используйте матричного конструктора с непостоянными размерностями |
Присвойте несколько, постоянные размеры к той же переменной перед использованием (чтения) переменной. | Присвойте несколько размеров той же переменной |
Задайте все экземпляры переменной, чтобы быть переменным размером. | Задайте Данные Переменного Размера Явным образом при помощи 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
. Опционально, можно также задать, какие размерности варьируются наряду со своими верхними границами. Например:
Задайте 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, как зафиксировано. Смотрите Задают Матрицы Переменного Размера с Размерностями Singleton.
Функциональный 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
быть переменным размером.