2014-03-12 58 views
2

我正在嘗試創建一個矩陣,該矩陣包含較大nxn矩陣的kxk子矩陣的平均值,其中n可被k整除。我可以像這樣arrayfun具有不同尺寸輸入的函數

mat = mat2cell(mat, k*ones(1,n/k), k*ones(1,n/k)) 
mat = cellfun(@mean,mat,'UniformOutput',false); 
mat = cellfun(@mean,mat,'UniformOutput',false); %repeated to collapse cells to 1x1 
mat = cell2mat(mat) 

但是相當有效做到這一點,因爲我有一個非常大的量都非常大的矩陣數據,重複該過程仍需要很長的時間,即使在一個集羣,並結合由於內存限制,矩陣不是一個選項。我不知道是否有可能使用arrayfun改寫這個代碼,而不是這樣我就可以利用它的GPU能力(如GPU無法處理單元陣列),但由於輔助功能我遇到問題的

function avg = blockavg(mat,i,j,k) 
i1 = (i-1)*k+1; 
i2 = i*k; 
j1 = (j-1)*k+1; 
j2 = j*k 
avg = mean(mean(mat(i1:i2,j1:j2))); 
end 

電話兩個廣播變量mat,一個nxn矩陣和一個標量k,當插入arrayfun時,這些不是陣列輸入。當運行

ii = 1:(n/k); 
jj = 1:(n/k); 
matavg = arrayfun(@blockavg,mat,ii,jj,k) 

錯誤消息返回,指出輸入參數必須是相同的尺寸和形狀的陣列,因爲只有iijj是陣列的輸入,而matk不跨越元素而變化。我不太清楚如何解決這個問題,或者即使這種類型的操作完全可以用於arrayfun。任何建議表示讚賞。

謝謝!

+0

要解決輸入大小問題,這可能會導致解決方案較慢,您必須使用常量的標準模式。定義一個包含這些常量的匿名函數:'matavg = arrayfun(@(ii,jj)(blockavg(mat,ii,jj,k)),mat,ii,jj,k)'。但我認爲這個解決方案比我建議的兩個版本更慢。 – Daniel

回答

2

另一個不錯可能性,而無需使用圖像處理工具箱:

squeeze(mean(mean(reshape(X,k,n/k,k,n/k),1),3)) 

此代碼重塑的方式的矩陣,每個塊可以通過Y(一個,來訪問:,B,:),該裝置它們具有相同的一維和三維索引。然後將均值應用於第一維和第三維,最後刪除單個維度以獲得2d結果。

+0

謝謝!這使我的運行時間減少了大約一半。感謝其他指針,非常感謝! – SeamusX

1

你正在嘗試做的是什麼blockproc從圖像處理工具箱提供:

blockproc(X,[k k],@(x)(mean(mean(x.data)))) 

加快,您可以嘗試設置UseParallel -parameter。