Чтобы ограничить размер массива для массивов переменного размера, выполните одно из следующих действий.
Ограничение размера массива с помощью инструкций Assert
Если переменная, определяющая размер массива, не является константой времени компиляции, используйте assert оператор с реляционными операторами для ограничения переменной. Это помогает генератору кода определить максимальный размер массива.
Следующие примеры ограничивают размер массива с помощью assert утверждения:
Когда размер массива определяется входными переменными
Определение функции array_init который инициализирует массив y с входной переменной N:
function y = array_init (N) assert(N <= 25); % Generates exception if N > 25 y = zeros(1,N);
assert оператор ограничивает ввод N до максимального размера 25. В отсутствие assert заявление, y назначается указатель на массив в сгенерированном коде, что позволяет динамически распределять память.
Когда размер массива получается из вычислений с использованием входных переменных
Определите функцию, array_init_from_prod, которая принимает две входные переменные, M и Nи использует их продукт для указания максимального размера массива, y.
function y = array_init_from_prod (M,N) size=M*N; assert(size <= 25); % Generates exception if size > 25 y=zeros(1,size);
assert оператор ограничивает произведение M и N максимум до 25.
Кроме того, при ограничении M и N индивидуально, это приводит к динамическому выделению памяти:
function y = array_init_from_prod (M,N)
assert(M <= 5);
assert(N <= 5);
size=M*N;
y=zeros(1,size);Этот код вызывает динамическое выделение памяти, поскольку M и N могут иметь неограниченные отрицательные значения. Поэтому их продукт может быть неограниченным и положительным, хотя по отдельности их положительные значения ограничены.
Совет
Поместите инструкцию assert на переменную непосредственно перед ее использованием для задания размера массива.
Совет
Вы можете использовать assert для ограничения размеров массивов в большинстве случаев. При расширении массива внутри цикла эта стратегия не работает, если количество запусков цикла известно только во время выполнения.
Ограничение конкатенаций в цикле с помощью coder.varsize с верхними границами
Можно расширить массивы за пределы их начального размера путем конкатенации. При объединении дополнительных элементов внутри цикла существуют два синтаксических правила для расширения массивов.
Размер массива во время инициализации не является константой времени компиляции
Если размер массива во время инициализации не является константой времени компиляции, его можно расширить путем объединения дополнительных элементов:
function out=ExpandArray(in) % Expand an array by five elements out = zeros(1,in); for i=1:5 out = [out 0]; end
Размер массива во время инициализации является константой времени компиляции
Перед конкатенацией элементов необходимо объявить массив как переменный размер с помощью coder.varsize:
function out=ExpandArray() % Expand an array by five elements out = zeros(1,5); coder.varsize('out'); for i=1:5 out = [out 0]; end
Любой случай приводит к динамическому выделению памяти. Чтобы предотвратить динамическое выделение памяти в таких случаях, используйте coder.varsize с явными верхними границами. В этом примере показано, как использовать coder.varsize с явными верхними границами:
Определите функцию, RunningAverage, которая вычисляет среднее значение N- подмножество элементов массива:
function avg=RunningAverage(N) % Array whose elements are to be averaged NumArray=[1 6 8 2 5 3]; % Initialize average: % These will also be the first two elements of the function output avg=[0 0]; % Place a bound on the argument coder.varsize('avg',[1 8]); % Loop to calculate running average for i=1:N s=0; s=s+sum(NumArray(1:i)); avg=[avg s/i]; % Increase the size of avg as required by concatenation end
Выходные данные, avg, является массивом, который можно расширить по мере необходимости для согласования средних значений выполнения. При вычислении нового рабочего среднего значения оно добавляется в массив avg посредством конкатенации, тем самым расширяя массив.
Поскольку максимальное количество средних значений выполнения равно количеству элементов в NumArray, можно указать явную верхнюю границу для avg в coder.varsize заявление. В этом примере верхняя граница равна 8 (два начальных элемента плюс шесть элементов NumArray).
Создать код для RunningAverage с входным аргументом типа double:
codegen -config:lib -report RunningAverage -args 2
В созданном коде avg назначается массив размера 8 (статическое выделение памяти). Определение функции для RunningAverage появляется следующим образом (с использованием встроенных типов C):
void RunningAverage (double N, double avg_data[8], int avg_size[2])
Напротив, если удалить явную верхнюю границу, созданный код динамически распределяет avg.
Заменить инструкцию
coder.varsize('avg',[1 8]);
с:
coder.varsize('avg');Создать код для RunningAverage с входным аргументом типа double:
codegen -config:lib -report RunningAverage -args 2
В созданном коде avg назначается указатель на массив, что позволяет динамически распределять память. Определение функции для RunningAverage появляется следующим образом (с использованием встроенных типов C):
void Test(double N, emxArray_real_T *avg)
Примечание
Динамическое выделение памяти также происходит, если предшествовать coder.varsize('avg') со следующим утверждением:
assert(N < 6);
assert оператор не ограничивает число конкатенаций в цикле.
Ограничение размера массива при перегруппировке матрицы
Заявление out = reshape(in,m,n,...) принимает массив, in, в качестве аргумента и возвращает массив, out, имеющие те же элементы, что и in, но изменен как mоколо-nоколо-... матрица. Если одна из переменных размера m,n,.... не является постоянной времени компиляции, то динамическое выделение памяти out имеет место.
Чтобы избежать динамического выделения памяти, используйте assert заявление перед reshape оператор для ограничения переменных размера m,n,... кому numel(in). В этом примере показано, как использовать assert утверждение перед reshape заявление:
Определите функцию, ReshapeMatrix, которая принимает входную переменную, Nи изменяет форму матрицы, mat, чтобы иметь N строки:
function [out1,out2] = ReshapeMatrix(N) mat = [1 2 3 4 5; 4 5 6 7 8] % Since mat has 10 elements, N must be a factor of 10 % to pass as argument to reshape out1 = reshape(mat,N,[]); % N is not restricted assert(N < numel(mat)); % N is restricted to number of elements in mat out2 = reshape(mat,N,[]);
Создать код для ReshapeArray с использованием codegen (входной аргумент не должен быть коэффициентом 10):
codegen -config:lib -report ReshapeArray -args 3
В то время как out1 динамически назначается, out2 назначается массив с размером 100 (= 10 X 10) в сгенерированном коде.
Совет
Если ваша система имеет ограниченный объем памяти, не используйте assert утверждение таким образом. Для n- матрица элементов, assert оператор создает nоколо-n матрица, которая может быть большой.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.