从稀疏矩阵中绘制随机非零元素

时间:2012-02-14 23:52:21

标签: matlab

我有一个稀疏的逻辑矩阵,它非常大。我想从中绘制随机的非零元素,而不将其所有非零元素存储在单独的向量中(例如,通过使用find命令)。有一个简单的方法吗?

目前我正在实施拒绝抽样,即抽取随机元素并检查是否为非零。但是当非零元素的比例很小时效率不高。

4 个答案:

答案 0 :(得分:1)

如果要选择随机位置,稀疏逻辑矩阵不是非常实用的数据表示。拒绝抽样和find是对我有意义的唯一两种方式。以下是如何有效地完成它们(假设您想要获得4个随机位置):

%# using find
idx = find(S);
%# draw 4 without replacement
fourRandomIdx = idx(randperm(length(idx),4));
%# draw 4 with replacement
fourRandomIdx = idx(randi(1,length(idx),4));
%# get row, column values
[row,col] = ind2sub(size(S),fourRandomIdx);



%# using rejection sampling
density = nnz(S)/prod(size(S));
%# estimate how many samples you need to get at least 4 hits
%# and multiply by 2 (or 3)
n = ceil( 1 / (1-(1-density)^4) ) * 2;
%# random indices w/ replacement
randIdx = randi(1,n,prod(size(S)));
%# identify the first four non-zero elements
[row,col] = find(S(randIdx),4,'first');

答案 1 :(得分:1)

具有nnz非零元素的n×m矩阵需要nnz + n + 1个整数来存储其非零条目的位置。对于逻辑矩阵,不需要存储非零条目的值:这些都是真的。相应地,您最好将逻辑稀疏矩阵转换为非零条目的线性索引列表,以及n和m,它只需要nnz + 2个存储整数。从这些(和ind2sub)中,您可以轻松地重建与您使用randi在1..nnz范围内随机选择的任何非零条目相对应的下标

答案 2 :(得分:0)

find是获取稀疏矩阵中非零元素的标准接口。看看http://www.mathworks.se/help/techdoc/math/f6-9182.html#f6-13040

[i,j,s] = find(S)

find返回向量i中非零值的行索引,向量j中的列索引以及向量s中的非零值本身。

无需得到s。只需在i,j中选择一个随机索引。

答案 3 :(得分:0)

通过以3列格式表示条目,即坐标列表(i,j,value),您只需从列表中选择项目即可。为此,您可以使用原始方法创建稀疏矩阵(即sparse()的前兆),或使用find命令,la [i,j,s] = find(S);

如果您不需要这些条目,而您似乎不需要,则可以只提取ij

如果由于某种原因,您的矩阵很大且RAM限制很严重,您可以简单地将矩阵划分为区域,并让选择给定子矩阵的概率与非零元素的数量成比例(在该子矩阵中使用nnz)。您可以将矩阵划分为单独的列,其余的计算是微不足道的。注意:通过将sum应用于矩阵,您可以获得每列计数(假设您的条目只是1)。

通过这种方式,您甚至无需担心拒绝采样(在这种情况下对我来说似乎毫无意义,因为Matlab知道所有非零条目都在哪里)。