簡體   English   中英

從邏輯數組掩碼(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

結果(對於相同的NLrr ):

Elapsed time is 0.034950 seconds.  %# order of magnitude faster than even M4!

另見這個問題+答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM