我有一个稀疏的逻辑矩阵,它非常大。我想从中绘制随机的非零元素,而不将其所有非零元素存储在单独的向量中(例如,通过使用find命令)。有一个简单的方法吗?
目前我正在实施拒绝抽样,即抽取随机元素并检查是否为非零。但是当非零元素的比例很小时效率不高。
答案 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);
如果您不需要这些条目,而您似乎不需要,则可以只提取i
和j
。
如果由于某种原因,您的矩阵很大且RAM限制很严重,您可以简单地将矩阵划分为区域,并让选择给定子矩阵的概率与非零元素的数量成比例(在该子矩阵中使用nnz
)。您可以将矩阵划分为单独的列,其余的计算是微不足道的。注意:通过将sum
应用于矩阵,您可以获得每列计数(假设您的条目只是1)。
通过这种方式,您甚至无需担心拒绝采样(在这种情况下对我来说似乎毫无意义,因为Matlab知道所有非零条目都在哪里)。