Разреженные матрицы обеспечивают эффективное хранение в памяти массивов со множеством нулевых элементов. Разреженные матрицы могут обеспечить улучшенную производительность и уменьшенное использование памяти для генерируемого кода. Время вычисления на разреженных матрицах масштабируется только с числом операций над ненулевыми элементами.
Функции создания разреженных матриц и управления ими перечислены в разделе Разреженные матрицы. Чтобы проверить, поддерживается ли функция для генерации кода, см. страницу ссылки на функцию. Генерация кода не поддерживает разреженные матричные входы для всех функций.
Если целевым языком является C, генератор кода создает определение типа для разреженных матриц с именем sparse. Это определение хранит массивы индексов строк, индексов столбцов и соответствующих значений элементов для разреженной матрицы. sparse определение типа генерируется в файле myFunction_types.h, где myFunction ссылается на имя функции верхнего уровня.
Если целевым языком является C++, генератор кода создает класс sparse в файле sparse.h.
Количество ненулевых элементов в разреженной матрице может изменяться во время вычисления. По этой причине разреженные матрицы в сгенерированном коде используют массивы переменного размера и динамическое выделение памяти. Если целевым языком является C, созданный код реализует динамически распределенные переменные с помощью emxArray тип. Если целевым языком является C++, созданный код реализует динамически распределенные переменные с помощью coder::array шаблон класса.
Например, рассмотрим функцию myDiag:
function out = myDiag(n,k) % create diagonal sparse matrix %#codegen A = speye(n); out = A.*k; end
Создайте код для функции с помощью codegen команда:
codegen -config:lib myDiag -args {3, 5} -launchreport
Разреженный тип можно найти в файле myDiag_types.h.
Предположим, что у вас есть функция foo которая принимает разреженную матрицу в качестве входных данных. Эта функция умножает разреженную матрицу на единичную матрицу и выводит произведение:
function C = foo(ASparseInput) %#codegen B = speye(size(ASparseInput')); C = ASparseInput*B;
Предположим, что требуется создать автономный lib, dll, или exe для использования вне среды MATLAB ®. Произвестиlib код, введите:
codegen -config:lib foo -args {sparse(5,5)} -launchreport
Можно упростить автономный код, построив разреженную матрицу внутри функции точки входа, а не передавая разреженную матрицу в качестве входных данных. При выполнении этого указания построение разреженной матрицы можно отложить до генератора кода. Другой код, использующий созданный код, может передавать типы ввода, такие как массивы, а не специализированные разреженные типы.
Например, вместо создания кода непосредственно из foo, создать новую функцию точки входа fooMain для создания кода из. Замените разреженный входной сигнал триплетной формой разреженных данных.
function [ii,jj,out] = fooMain(i,j,v,m,n) %#codegen S = sparse(i,j,v,m,n); [ii,jj,out] = find(foo(S));
Предположим, что требуется создать код для разреженной матрицы 5 на 5 S с числом ненулевых элементов переменного размера. Для создания кода введите:
S = sparse(5,5); [m,n] = size(S); [i,j,v] = find(S); i = coder.typeof(i,[inf 1]); codegen -config:lib fooMain -args {i,i,i,m,n} -launchreport
Можно указать входные данные для fooMain с целочисленными типами массивов и типами массивов переменного размера. При создании кода непосредственно из foo, необходимо создать входные данные как sparse тип.
Если выбрана передача разреженной матрицы в качестве ввода функции точки входа, можно использовать coder.typeof для инициализации входных данных. Например, для функции foo, можно ввести:
t = coder.typeof(sparse(5,5)); codegen -config:lib foo -args {t} -launchreport
Для разреженных матриц генератор кода не отслеживает верхние границы для размеров переменного размера. Все размеры переменного размера рассматриваются как неограниченные.
При создании функции MEX для foo, входные и выходные данные должны быть преобразованы в sparse тип. Это преобразование может замедлить производительность для повторных вызовов функции MEX или больших входов и выходов.
Нельзя программно определять разреженные типы ввода с помощью assert заявления.
Инициализируйте матрицы, используя разреженные конструкторы, чтобы максимизировать эффективность кода. Например, чтобы построить единичную матрицу 3 на 3, используйте speye(3,3) вместо sparse(eye(3,3)).
Индексированное назначение в разреженные матрицы несет издержки по сравнению с индексированным назначением в полные матрицы. Например:
S = speye(10); S(7,7) = 42;
Как и в MATLAB, разреженные матрицы хранятся в сжатом формате разреженных столбцов. При вставке нового ненулевого элемента в разреженную матрицу все последующие ненулевые элементы должны быть сдвинуты вниз, столбец за столбцом. Эти дополнительные манипуляции могут замедлить производительность.
Для создания кода, использующего разреженные матрицы, необходимо включить динамическое выделение памяти. Для хранения изменяющегося числа ненулевых элементов и их значений разреженные матрицы используют массивы переменного размера в сгенерированном коде. Чтобы изменить параметры динамического выделения памяти, см. раздел Управление выделением памяти для массивов переменного размера. Поскольку разреженные матрицы используют массивы переменного размера для динамического выделения памяти, ограничения данных переменного размера также применяются к разреженным матрицам.
Нельзя назначить разреженные данные данным, которые не являются разреженными. Созданный код использует различные представления типа данных для разреженных и полных матриц. Для преобразования в разреженные данные и из них используйте явное sparse и full функции преобразования.
Нельзя определить разреженную матрицу с конкурирующими спецификациями размера. Генератор кода фиксирует размер разреженной матрицы, когда производит соответствующее определение типа данных в C/C + +. Например, функцияfoo вызывает ошибку при создании кода:
function y = foo(n) %#codegen if n > 0 y = sparse(3,2); else y = sparse(4,3); end
Логическое индексирование в разреженные матрицы не поддерживается для генерации кода. Например, этот синтаксис вызывает ошибку:
S = magic(3); S(S > 7) = 42;
Для разреженных матриц невозможно удалить элементы массива, назначив пустые массивы:
S(:,2) = [];
codegen | coder.typeof | full | magic | sparse | speye