[英]How to convert logical sparse matrix into integer sparse matrix in MATLAB?
[英]Building a sparse matrix from another smaller matrix's values mapped by a logical array mask (MATLAB)?
我正在使用大型稀疏矩陣( 稀疏 )。 我有一個大的稀疏值矩陣,需要包含在一個更大的稀疏矩陣中。 我有一個logicals
數組,指示哪些行和列將用較小的矩陣值填充。 在該應用中,兩個矩陣中較小的一個是存儲為鄰接矩陣的圖,邏輯表示較大矩陣中的節點id位置。
一個小玩具示例,用於演示我目前正在做的事情:
zz = sparse(4,4); %create a sparse matrix of the final size desired
rr = rand(3,3); %a matrix of values
logical_inds = logical([1 0 1 1]); %a logical array to index with the dimension size of zz
zz(logical_inds,logical_inds) = rr(:,:) %'rr' values are mapped into the subset of 'zz'
我看到zz
第二列是零, 第二行也是零值。 這是所需的輸出。
在我的程序中得到一個警告,這個“稀疏索引可能會很慢”,而且確實如此。 有時,當矩陣非常大時,程序終止於此行。
如何使用稀疏方法創建此矩陣( zz
)? 我不確定如何從我擁有的邏輯掩碼創建行列索引,以及如何將rr
的值轉換為適合此新索引的數組。
**一般來說rr
非常稀疏,盡管邏輯掩碼解決了整個矩陣
要使用sparse
函數創建此矩陣,邏輯索引將需要轉換為行索引和列索引, 因此最終可能會變慢...
這里找到邏輯向量中的1的位置,然后創建包含稀疏矩陣中非零的行和列索引的矩陣。
最后,稀疏函數用於在這些位置創建具有rr
元素的稀疏矩陣( rr(:)
用於將其轉換為列向量)
ind_locs = find(logical_inds);
ind = combvec(ind_locs,ind_locs);
zz = sparse(ind(1,:),ind(2,:),rr(:))
我認為問題主要是由於分配期間隱式調整大小。 這就是為什么我認為:
%# test parameters
N = 5000; %# Size of 1 dimension of the square sparse
L = rand(1,N) > 0.95; %# 5% of rows/cols will be non-zero values
M = sum(L);
rr = rand(M); %# the "data" to fill the sparse with
%# Method 1: direct logical indexing
%# (your original method)
zz1 = sparse(N,N);
tic
zz1(L,L) = rr;
toc
%# Method 2: test whether the conversion to logical col/row indices matters
zz2 = sparse(N,N);
inds = zz1~=0;
tic
zz2(inds) = rr;
toc
%# Method 3: test whether the conversion to linear indices matters
zz3 = sparse(N,N);
inds = find(inds);
tic
zz3(inds) = rr;
toc
%# Method 4: test whether implicit resizing matters
zz4 = spalloc(N,N, M*M);
tic
zz4(inds) = rr;
toc
結果:
Elapsed time is 3.988558 seconds. %# meh M1 (original)
Elapsed time is 3.916462 seconds. %# meh M2 (expanded logicals)
Elapsed time is 4.003222 seconds. %# meh M3 (converted row/col indices)
Elapsed time is 0.139986 seconds. %# WOW! M4 (pre-allocated memory)
顯然(並且令人驚訝地),似乎MATLAB在分配之前不會增加現有的稀疏(正如您所期望的那樣),但實際上循環遍歷行/ col索引並在迭代期間增加稀疏。 因此,似乎必須“幫助”MATLAB:
%# Create initial sparse
zz1 = sparse(N,N);
%# ...
%# Do any further operations until you can create rr:
%# ...
rr = rand(M); %# the "data" to fill the sparse with
%# Now that the size of the data is known, re-allocate space for the sparse:
tic
[i,j] = find(zz1); %# indices
[m,n] = size(zz1); %# Sparse size (you can also use N of course)
zz1 = sparse(i,j,nonzeros(zz1), m,n, M*M);
zz1(L,L) = rr; %# logical or integer indices, doesn't really matter
toc
結果(對於相同的N
, L
和rr
):
Elapsed time is 0.034950 seconds. %# order of magnitude faster than even M4!
另見這個問題+答案 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.