Существует несколько команд, которые обеспечивают информацию высокого уровня о ненулевых элементах массива разреженной матрице:
Чтобы попробовать некоторые из них, загрузите предоставленную разреженную матрицу west0479, одна из наборов Harwell-Boeing.
load west0479
whosName Size Bytes Class Attributes west0479 479x479 34032 double sparse
Эта матрица моделирует восьмиступенчатый химический дистилляционный столбец.
Попробуйте эти команды.
nnz(west0479)
ans =
1887format short e west0479
west0479 =
(25,1) 1.0000e+00
(31,1) -3.7648e-02
(87,1) -3.4424e-01
(26,2) 1.0000e+00
(31,2) -2.4523e-02
(88,2) -3.7371e-01
(27,3) 1.0000e+00
(31,3) -3.6613e-02
(89,3) -8.3694e-01
(28,4) 1.3000e+02
.
.
.nonzeros(west0479)
ans =
1.0000e+00
-3.7648e-02
-3.4424e-01
1.0000e+00
-2.4523e-02
-3.7371e-01
1.0000e+00
-3.6613e-02
-8.3694e-01
1.3000e+02
.
.
.Примечание
Используйте Ctrl+C, чтобы остановить nonzeros листинг в любое время.
Обратите внимание, что первоначально nnz имеет то же значение что и nzmax по умолчанию. То есть количество ненулевых элементов эквивалентно количеству мест хранения, выделенных для ненули. Однако MATLAB® не освобождает память динамически, если вы обнулите дополнительные элементы массива. Изменение значения некоторых элементов матрицы на нуль изменяет значение nnz, но не из-за nzmax.
Однако можно добавить к матрице столько ненулевых элементов, сколько требуется. Вы не ограничены исходным значением nzmax.
Для любой матрицы, полной или разреженной, find функция возвращает индексы и значения ненулевых элементов. Его синтаксис:
[i,j,s] = find(S);
find возвращает индексы строк ненулевых значений в векторе i, индексы столбцов в векторных j, и самих ненулевых значений в векторе s. В приведенном ниже примере используются find для определения местоположения индексов и значений nonzeros в разреженной матрице. sparse функция использует find выход вместе с размером матрицы для воссоздания матрицы.
S1 = west0479; [i,j,s] = find(S1); [m,n] = size(S1); S2 = sparse(i,j,s,m,n);
Поскольку разреженные матрицы хранятся в сжатом разреженном формате столбца, существуют другие затраты, связанные с индексацией в разреженную матрицу, чем с индексацией в полную матрицу. Такие затраты незначительны, когда вам нужно изменить только несколько элементов в разреженной матрице, поэтому в этих случаях нормально использовать регулярную индексацию массива для переназначения значений:
B = speye(4); [i,j,s] = find(B); [i,j,s]
ans =
1 1 1
2 2 1
3 3 1
4 4 1B(3,1) = 42; [i,j,s] = find(B); [i,j,s]
ans =
1 1 1
3 1 42
2 2 1
3 3 1
4 4 142 при (3,1)MATLAB вставляет дополнительную строку в ненулевые векторы значений и нижние индексы, затем сдвигает все матричные значения после (3,1).Использование линейной индексации для доступа или назначения элемента в большой разреженной матрице не удастся, если линейный индекс превысит 2^48-1, которая является текущей верхней границей для количества элементов, разрешенных в матрице.
S = spalloc(2^30,2^30,2); S(end) = 1
Maximum variable size allowed by the program is exceeded.
Для доступа к элементу, линейный индекс которого больше intmax, используйте индексацию массива:
S(2^30,2^30) = 1
S =
(1073741824,1073741824) 1Хотя стоимость индексации в разреженную матрицу для изменения одного элемента незначительна, она сложена в контексте цикла и может стать довольно медленной для больших матриц. По этой причине в случаях, когда нужно изменить много разреженных матричных элементов, лучше векторизировать операцию вместо использования цикла. Для примера рассмотрим разреженную матрицу тождеств:
n = 10000; A = 4*speye(n);
A в цикле принимает медленнее, чем аналогичная векторизованная операция:tic A(1:n-1,n) = -1; A(n,1:n-1) = -1; toc
Elapsed time is 0.003344 seconds.
tic for k = 1:n-1 C(k,n) = -1; C(n,k) = -1; end toc
Elapsed time is 0.448069 seconds.
A во время каждого прохода через цикл.Предварительное выделение памяти для разреженной матрицы и последующее заполнение ее поэлементным способом аналогично вызывает значительное количество накладных расходов при индексации в разреженный массив:
S1 = spalloc(1000,1000,100000); tic; for n = 1:100000 i = ceil(1000*rand(1,1)); j = ceil(1000*rand(1,1)); S1(i,j) = rand(1,1); end toc
Elapsed time is 2.577527 seconds.
Построение векторов индексов и значений устраняет необходимость индексирования в разреженный массив и, таким образом, значительно быстрее:
i = ceil(1000*rand(100000,1)); j = ceil(1000*rand(100000,1)); v = zeros(size(i)); for n = 1:100000 v(n) = rand(1,1); end tic; S2 = sparse(i,j,v,1000,1000); toc
Elapsed time is 0.017676 seconds.
По этой причине лучше всего создавать разреженные матрицы все сразу с помощью функции конструкции, такой как sparse или spdiags функций.
Например, предположим, что вам нужна разреженная форма матрицы координат C:
Создайте матрицу из пяти столбцов непосредственно с sparse функция, использующая пары триплетов для индексов строк, индексов столбцов и значений:
i = [1 5 2 5 3 5 4 5 1 2 3 4 5]'; j = [1 1 2 2 3 3 4 4 5 5 5 5 5]'; s = [4 1 4 1 4 1 4 1 -1 -1 -1 -1 4]'; C = sparse(i,j,s)
C = (1,1) 4 (5,1) 1 (2,2) 4 (5,2) 1 (3,3) 4 (5,3) 1 (4,4) 4 (5,4) 1 (1,5) -1 (2,5) -1 (3,5) -1 (4,5) -1 (5,5) 4
Часто полезно использовать графический формат, чтобы просмотреть распределение ненулевых элементов в разреженной матрице. Система MATLAB spy функция создает представление шаблона структуры разреженности, где каждая точка графика представляет расположение ненулевого элемента массива.
Для примера:
Загрузите предоставленную разреженную матрицу west0479, одна из наборов Harwell-Boeing.
load west0479Просмотрите структуру разреженности.
spy(west0479)
