Building a sparse matrix from other smaller matrix values ​​displayed by a logical array mask (MATLAB)?

I have been working with large sparse matrices ( sparse ). I have a large sparse matrix of values ​​that should be included in a large sparse matrix. I have an array logicalsthat indicates which rows and columns should be filled with smaller matrix values. In this application, the smaller of the two matrices is a graph that is stored as an adjacency matrix, and logical notations indicate the position of the node id in the larger matrix.

A small toy example to demonstrate what I'm doing now:

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'

I see that column 2 ndzz is zeros and that row 2 nd is also zero. This is the desired result.

A warning appears in my program that this "sparse indexing is likely to be slow," and it is. Sometimes, when the matrices are very large, the program ends on this line.

How can I create this matrix ( zz) using the sparse method? I'm not sure how to create row column indexes from the logical element mask that I have, and how to convert the values rrto an array ordered appropriately for this new indexing.

** generally rrvery sparse, although the mask of logical addresses addresses the full matrix

+4
2

, . , :

%# 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 ( ), / . , "" 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!

. + .

+2

sparse, , , ...

, , .
, rr (rr(:) )

ind_locs = find(logical_inds);
ind = combvec(ind_locs,ind_locs);

zz = sparse(ind(1,:),ind(2,:),rr(:))
+2

Source: https://habr.com/ru/post/1547016/


All Articles