![](/img/trans.png)
[英]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.