2012-02-14 53 views
4

我有一個稀疏的邏輯矩陣,它非常大。我想從它繪製隨機非零元素,而不將其所有非零元素存儲在單獨的向量中(例如,通過使用find命令)。是否有捷徑可尋?從稀疏矩陣中繪製一個隨機的非零元素

目前我正在執行拒絕採樣,它正在繪製一個隨機元素並檢查它是否非零。但是當非零元素的比例很小時,效率不高。

+0

我認爲對於稀疏矩陣而言,find是相當優化的,如果這是您所擔心的。 – 2012-02-15 00:11:02

+0

我很擔心內存不在運行時間。但是,即使在運行時間方面,如果您只想抽取幾個項目,發現並不是那麼有效。 – user1210230 2012-02-15 01:24:29

+0

使用'nonzeros'應該比'find'略高的內存效率,因爲您不存儲行和列索引。 – 2012-02-15 10:57:27

回答

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中選擇一個隨機索引。

+0

也許我的觀點不夠清楚。我不想使用查找,因爲那麼我必須將索引存儲在一個單獨的向量中(在您的示例中爲i和j),這將會非常耗費內存。將它與作爲稀疏邏輯矩陣的稀疏矩陣本身進行比較。 – user1210230 2012-02-15 00:27:09

+0

這是明確的,但沒有其他辦法。 – 2012-02-15 09:04:36

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

與NNZ非零元素N×M矩陣需要NNZ + N + 1點的整數來保存它的非零的位置條目。對於邏輯矩陣,不需要存儲非零條目的值:這些都是真實的。相應地,您最好將您的邏輯稀疏矩陣轉換爲其非零條目的線性索引列表,以及n和m,這隻需要nnz + 2個存儲整數。從這些(和ind2sub)中,您可以輕鬆地重建與您使用隨機選擇的任何非零條目對應的下標,範圍爲1..nnz

+0

我的應用程序也需要從零個條目進行採樣。因此,我維持稀疏矩陣能夠檢查隨機條目的值。使用索引解決方案,抽樣零元素是不可能的。 – user1210230 2012-02-17 01:24:38

+0

你能澄清你的目標嗎?你原來的帖子表明你想繪製「隨機非零元素」;然而,在你的評論中,你似乎也想從零條目中抽取。你能澄清嗎?也就是說,當你從矩陣中隨機抽取時,你是從所有條目中抽取的,還是僅僅抽取了一些(如果是的話)?當你畫畫時,你想要什麼(例如,指數,指數和元素值,或者......)?最後,這個矩陣是作爲一個隨機矩陣來給你看的,還是由其他東西構成,以便它的表示在你的控制之下? – lsfinn 2012-02-25 22:46:18

0

通過以3列格式表示條目,又名座標列表(i,j,值),您可以簡單地從列表中選擇項目。爲了得到這一點,你可以用你原來的方法創建稀疏矩陣(即前體sparse()),或使用find命令,一拉[i,j,s] = find(S);

如果您不需要的條目,看來你不要,你可以提取ij

如果由於某種原因,您的矩陣很大並且RAM的限制很嚴重,那麼您可以簡單地將該矩陣劃分爲區域,並讓選擇給定子矩陣的概率與非零數在該子矩陣中使用元素(使用nnz)。你甚至可以將矩陣分成單獨的列,其餘的計算是微不足道的。注意:通過將sum應用於矩陣,您可以獲得每列計數(假設您的條目僅爲1秒)。通過這種方式,您甚至不需要排斥採樣(在這種情況下對我來說似乎毫無意義,因爲Matlab知道所有非零入口在哪裏)。

相關問題