Разреженные матрицы обеспечивают эффективное хранение данных в памяти для массивов с множеством нулевых элементов. Разреженные матрицы могут обеспечить улучшенную производительность и уменьшение использования памяти для сгенерированного кода. Время расчета на разреженных матрицах масштабируется только с количеством операций на ненулевых элементах.
Функции для создания и манипулирования разреженными матрицами перечислены в Sparse Matrices. Чтобы проверить, поддерживается ли функция для генерации кода, смотрите страницу с описанием функции. Генерация кода не поддерживает разреженные матричные входы для всех функций.
Если ваш целевой язык является C, генератор кода создает определение типа для разреженных матриц, называемых sparse
. В этом определении хранятся массивы индексов строк, индексов столбцов и соответствующих значений элементов для разреженной матрицы. The 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