2013-05-26 41 views
3

如果我有一首頌歌,並寫在兩個方面,喜歡這裏:向量化ODE在八度/ Matlab的

function re=rabdab() 
x=linspace(0,2000,2000)'; 
tic; 
[T,Y] = ode45(@fun,[x],[0 1 1]); 
[T,Y] = ode45(@fun,[x],[0 1 1]); 
[T,Y] = ode45(@fun,[x],[0 1 1]); 
toc; 

tic; 
[A,B] = ode45(@fun2,[x],[0 1 1]); 
[A,B] = ode45(@fun2,[x],[0 1 1]); 
[A,B] = ode45(@fun2,[x],[0 1 1]); 
toc; 



function dy = fun(t,y) 
dy = zeros(3,1); % a column vector 
dy = [y(2) * y(3);... 
-y(1) * y(3);... 
-0.51 * y(1) * y(2);]; 

function dy = fun2(t,y) 
dy = zeros(3,1); % a column vector 
dy(1) = y(2) * y(3); 
dy(2) = -y(1) * y(3); 
dy(3) = -0.51 * y(1) * y(2); 

有時間幾乎沒有差別。一個和另一個一樣長。但我認爲funfun2的矢量化版本。還是我誤解了? 目的是加快我的代碼一點。該示例取自matlab網頁。 我想我還沒有真正理解「矢量化」的含義。 如果這已經被矢量化了,那麼非矢量化的代碼是什麼樣的?

回答

3

Vectorization是一個概念,它與functional programming密切相關。在MATLAB中,它意味着對數組(向量或矩陣)執行操作而不隱式地寫一個循環。

例如,如果你要計算功能f(x) = 2x 1和100之間的每個整數x,可以編寫:

for x = 1:100 
    f(x) = 2 * x; 
end 

未量化代碼。該矢量版本是:

x = 1:100; %// Declare a vector of integer values from 1 to 100 
f = 2 * x; %// Vectorized operation "*" 

甚至更​​短:

f = 2 * (1:100); 

MATLAB是一種解釋語言,所以很明顯的解釋將這種陷入某種循環「引擎蓋下」,但它的優化,通常比實際解釋循環要快得多(請參閱this question以供參考)。那麼,就是這樣 - 直到最近發佈的MATLAB,其中JIT acceleration已被集成(閱讀here)。

現在回到代碼中:這裏有兩個向量化代碼:一個垂直連接三個值,另一個直接將這些值分配到列向量中。這基本上是一樣的。如果你使用明確的for循環來完成它,這將不會被「矢量化」。關於「向量化」一個循環(即,將for循環轉換爲向量化操作)的實際性能增益,這取決於for循環實際上由於JIT加速所引起的速度。

似乎並沒有太多的工作要加快你的代碼。你的功能是非常基礎的,所以它歸結爲ode45的內部實現,你不能修改。

如果您有興趣進一步閱讀有關矢量化和編寫速度更快的MATLAB代碼,請參閱以下有趣的文章:Loren on the Art of MATLAB: "Speeding Up MATLAB Applications"

快樂編碼!

+1

感謝您讓我擺脫這種困惑。所以,使用ode23可能會更快,因爲它不夠準確,但矢量化不是問題。但是,由於你的解釋,我可以找出我可以矢量化的代碼中的其他角落。 – lyvic