1. 程式人生 > >MATLAB中對矩陣元素操作的for迴圈優化方法

MATLAB中對矩陣元素操作的for迴圈優化方法

           眾所周知,MATLAB程式效率最低最有潛力的地方便是迴圈了。最常見的迴圈莫過於對矩陣中的每一個元素進行操作,對於程式設計思維還在C語言或者C++,JAVA的人來說,第一反應就是兩層迴圈,先來個 “for i=1:m”對矩陣的行進行迴圈,再來個“for j=1:n”對矩陣的列進行迴圈。 所以我前面就直接寫出了一個四重for迴圈,被自己蠢哭了!程式時間長到壓根沒法等。其實自己知道這四重迴圈是可以優化的,但一直沒專門研究過MATLAB迴圈優化的問題,既然碰到了,也就專門考慮了下這個問題。下面有兩種對於矩陣元素操作for迴圈的優化方法。

           一,採用meshgrid函式。

      大家都知道採用向量化或者矩陣化運算來代替迴圈是MATLAB裡最好的最有效率的優化方法。這裡對於2*3大小的矩陣A的元素進行操作,就可以採用meshgrid函式對for迴圈進行矩陣化替代。對於

i=1:2;
j=1:3;
可以替代為
[m,n]=meshgrid(i , j);

m=[ 1   1  1  
    2   2  2 ]

n=[1  2  3
   1  2  3 ]

可以看到這裡,生成的矩陣m和n的規模大小是相等的,都是2*3 。

A(m(1,1),n(1,1))=A(1,1)  A(m(2,2),n(2,2))=A(2,2)

A(m(2,1),n(2,1))=A(2,1)   

A(m(2,3),n(2,3))=A(2,3)  

    大家發現規律沒,m,n其實就是矩陣A的下角標行和列的索引。例如:求函式f(x,y)=x^2+y^3,x=1:256,y=257:512,

優化後的程式碼:

x=1:256;

y=257:512;

[m,n]=meshgrid(x,y);

f=m.^2+n.^3;

完全沒有用到for迴圈,採用矩陣化運算,速度大幅度提高。

    二,通過求餘優化

        在電腦記憶體裡,矩陣作為二維向量,其實也是當成一維矩陣存放的。假設A為3*4的矩陣,即A(2,3)=A(7)。所以,也可以把二維矩陣當成一位向量來看。我們可以把一維矩陣A(k)通過求餘的方法得到這個元素才二維矩陣裡對應的行i和列j。

       同樣採用A(2,3)=A(7)的例子,(7-1)/4+1,再向下取整得到2,(7-1)mod(4)+1=3 ,從而得到了A(7)元素在二維矩陣中對應的下標位置(2,3)。

例如,對於大小為m*n的矩陣A,計算B(i,j)=A(i,j)+i+j後的矩陣B,具體程式實現:

for k=1:m*n

     row=floor(k-1,n)+1;

     col=mod(k-1,n)+1;

     B(k)=A(k)+row+col;

end

     這樣就把兩層for迴圈優化成了一層,雖然計算量並沒有減少多少,但可以這樣可以開MATLAB的並行運算了,照樣可以大幅度提高運算速度,因為parfor是不支援兩層兩層以上的迴圈的,所以這種優化是有意義的。並且在適合的情況下,也可以進一步把for k=1:m*n迴圈改成向量化運算k=1:m*n,一層迴圈都不用。

    以上就是我前面在碰到四重for迴圈後優化程式碼的一點收穫,應該還有其他的優化技巧,希望能同大家共同交流進步!