Существует несколько команд, которые предоставляют высокоуровневую информацию о ненулевых элементах разреженной матрицы:
Чтобы попробовать некоторые из них, загрузите предоставленную разреженную матрицу west0479
, один из набора Харуэлла-Boeing.
load west0479
whos
Name Size Bytes Class Attributes west0479 479x479 34032 double sparse
Это матричные модели восьмиэтапный химический столбец дистилляции.
Попробуйте эти команды.
nnz(west0479)
ans = 1887
format 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
по умолчанию. Таким образом, количество ненулевых элементов эквивалентно количеству мест хранения, выделенных для ненулей. However, MATLAB® динамически не выпускает память, если вы обнуляете дополнительные элементы массива. Изменение значения некоторых элементов матрицы, чтобы обнулить изменяет значение nnz
, но не тот из nzmax
.
Однако можно добавить столько ненулевых элементов в матрицу сколько желаемый. Вы не ограничиваетесь исходным значением nzmax
.
Для любой матрицы, полной или разреженной, find
функция возвращает индексы и значения ненулевых элементов. Его синтаксис
[i,j,s] = find(S);
find
возвращает индексы строки ненулевых значений в векторном i
, индексы столбца в векторном j
, и сами ненулевые значения в векторном s
. Пример ниже использует find
определять местоположение индексов и значений ненулей в разреженной матрице. 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 1
B(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 1
42
в (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
Часто полезно использовать графический формат, чтобы просмотреть распределение ненулевых элементов в разреженной матрице. spy
MATLAB функция производит представление шаблона структуры разреженности, где каждая точка на графике представляет местоположение ненулевого элемента массива.
Например:
Загрузите предоставленную разреженную матрицу west0479
, один из набора Харуэлла-Boeing.
load west0479
Просмотрите структуру разреженности.
spy(west0479)