[英]Drawing a random non-zero element from a sparse matrix
我有一個稀疏的邏輯矩陣,它很大。 我想從中繪制隨機的非零元素,而不將其所有非零元素存儲在單獨的向量中(例如,使用find命令)。 是否有捷徑可尋?
目前,我正在實施拒絕采樣,它繪制了一個隨機元素並檢查它是否為非零。 但是,當非零元素的比例較小時,效率不高。
如果要選擇隨機位置,則稀疏邏輯矩陣並不是數據的實用表示。 拒絕采樣和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');
具有nnz個非零元素的nxm矩陣需要nnz + n + 1個整數來存儲其非零條目的位置。 對於邏輯矩陣,無需存儲非零條目的值:這些都是正確的。 相應地,您最好將邏輯稀疏矩陣與n和m一起轉換為其非零條目的線性索引的列表,而n和m僅需要nnz + 2個整數存儲。 從這些(和ind2sub)中,您可以輕松地重建與您使用randi在1..nnz范圍內隨機選擇的任何非零條目相對應的下標。
find是獲取稀疏矩陣中非零元素的標准接口。 在這里看看http://www.mathworks.se/help/techdoc/math/f6-9182.html#f6-13040
[i,j,s] = find(S)
find返回向量i中非零值的行索引,向量j中的列索引以及向量s中的非零值本身。
無需獲取。 只需在i,j中選擇一個隨機索引。
通過以3列格式(也稱為坐標列表(i,j,值))表示條目,您可以簡單地從列表中選擇項目。 為此,您可以使用原始方法創建稀疏矩陣(即sparse()
的前身),也可以使用find
命令la [i,j,s] = find(S);
如果您不需要這些條目,並且似乎不需要,則可以提取i
和j
。
如果由於某種原因您的矩陣很大且RAM限制很嚴格,則可以簡單地將矩陣划分為多個區域,並使選擇給定子矩陣的概率與非零元素的數量成比例(使用nnz
)在該子矩陣中。 您甚至可以將矩陣划分為單獨的列,其余的計算很簡單。 注意:通過將sum
應用於矩陣,您可以獲取每個列的計數(假設您的條目僅為1s)。
這樣,您甚至不必費心拒絕采樣(在這種情況下,這對我來說似乎毫無意義,因為Matlab知道所有非零條目的位置)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.