2013-08-01 198 views
2

比方說,我有一個方形矩陣M:計算部分累計總和方陣

M = [0 0 0 0 0 1 9; 0 0 0 0 0 4 4; 0 0 1 1 6 1 1; 0 1 2 9 2 1 0; 2 1 8 3 2 0 0; 0 8 1 1 0  0 0; 14 2 0 1 0 0 0] 


     0 0 0 0 0 1 9 
     0 0 0 0 0 4 4 
     0 0 1 1 6 1 1 
M = 0 1 2 9 2 1 0 
     2 1 8 3 2 0 0 
     0 8 1 1 0 0 0 
    14 2 0 1 0 0 0 

現在,我想計算兩個不同的累計總和:一是,從每列的頂部進入列的元素,即矩陣的對角線元素,以及從列的底部到相同對角線元素的列。因此

產生的矩陣M'應該是以下幾點:

 0 0 0 0 0 1 9 
     0 0 0 0 0 4 5 
     0 0 1 1 6 2 1 
M' = 0 1 3 9 4 1 0 
     2 2 8 5 2 0 0 
     2 8 1 2 0 0 0 
     14 2 0 1 0 0 0 

我希望的是什麼,我試圖達到的解釋是足夠的理解。由於我的矩陣比這個例子中的矩陣大得多,所以計算也應該是高效的......但到目前爲止,我甚至都不知道如何「低效地」計算它。

+0

是你的矩陣總是平方? – horchler

+0

是的,它們總是正方形的 – Schnigges

+0

你會介意清理:「從每列的頂部到列的元素,即矩陣的對角線元素,以及從列的底部到相同的對角元素。「我相信我有一個解決方案,但這讓我感到困惑。因此,它將從列頂部的所有元素添加到對角線,但不包括對角線,從底部到對角線除外。 – voxeloctree

回答

2

在一個行:

Mp = fliplr(triu(fliplr(cumsum(M)),1)) ... 
    +flipud(triu(cumsum(flipud(M)),1)) ... 
    +flipud(diag(diag(flipud(M)))); 
1

下面將做的工作:

Mnew = fliplr(triu(cumsum(triu(fliplr(M)),1))) + flipud(triu(cumsum(triu(flipud(M)),1))); 
Mnew = Mnew - fliplr(diag(diag(fliplr(Mnew)))) + fliplr(diag(diag(fliplr(M)))); 

但它是最快的方法是什麼?

我認爲合理的索引可能讓你有使用一些翻轉和上三角功能triu更快

+0

drat ...太多的trius和翻轉!好工作@horchler –

+0

非常感謝!我不知道這是一種比較兩種解決方案的好方法,但是使用'tic'和'toc'你的一個是幾毫秒的「慢」:D – Schnigges

+0

我很驚訝我們非常接近相同的解決方案。我認爲你說得對,可能有更快的方法來做到這一點,但這些方法是相當可讀的,JIT編譯器可以做得很好。 – horchler