2012-07-27 88 views
2

我想矢量化3D函數,但函數沒有解析表達式。舉例來說,我可以做這樣的事情在Matlab和Octave中矢量化非顯式函數

function out = Vect_fn(x, y,z) 
    out(1) = x.*sin(y); 
    out(2) = z.*y; 
    out(3) = x.*y; 
end 

,然後運行該腳本

a = linspace(0,1,10); 
[xx, yy, zz] = meshgrid(a, a, a); 
D = Vect_fn(xx, yy, zz) 

但是矢量化功能

F(x, y, z) = (sin(y)*x, z*y, x*y) 

,假設函數沒有解析表達式,例如

function y = Vect_Nexplicit(y0) 
     %%%%%%y0 is a 3x1 vector%%%%%%%%%%%%%% 
     t0 = 0.0; 
     tf = 3.0; 
     [t, z] = ode45('ODE_fn', [t0,tf], y0); 
     sz = size(z); 
     n = sz(1); 
     y = z(n, :); 
end 

其中ODE_fn只是吐出ODE右側的一些函數。因此,該功能簡單地解決了一個ODE,因此該功能不明確。當然,我可以用一個for循環,但這些都是比較慢(尤其是在八度,這是我比較喜歡,因爲它有lsode解決常微分方程)

試圖像

a = linspace(0,1,10); 
[xx, yy, zz] = meshgrid(a, a, a); 
D = Vect_Nexplicit(xx, yy, zz) 

的東西不起作用。另外這裏是ODF_fn代碼:

function ydot = ODE_fn(t, yin) 

A = sqrt(3.0); 
B = sqrt(2.0); 
C = 1.0; 

x = yin(1, 1); 
y = yin(2,1); 
z = yin(3, 1); 

M = reshape(yin(4:12), 3, 3); 

ydot(1,1) = A*sin(yin(3)) + C*cos(yin(2)); 
ydot(2,1) = B*sin(yin(1)) + A*cos(yin(3)); 
ydot(3,1) = C*sin(yin(2)) + B*cos(yin(1)); 

DV = [0 -C*sin(y) A*cos(z); B*cos(x) 0 -A*sin(z); -B*sin(x)  C*cos(y) 0]; 

Mdot = DV*M; 

ydot(4:12,1) = reshape(Mdot, 9, 1); 


end 
+2

如果沒有解析解,並且必須爲每個新輸入求解一個微分方程,我不明白某種迴路構造可能如何。 (arrayfun等在matlab本質上也是一個循環) – 2012-07-27 14:11:16

+1

我認爲你的當前方法可能工作,如果'ODE_fn'是正確的矢量化。 – Isaac 2012-07-27 15:27:01

回答

0

可以解微分方程的系統與ODE45,所以如果ODE_fn是矢量化,你可以使用你的方法。 y0也只是一個向量。您可以創建[x1,...,xn,y1,...,yn,z1,...,zn,M1_1-9,...,Mn_1-9]的y0,然後用於x,y,z只是適當的索引,即1:n,n + 1:2 * n,2 * n + 1:3n。然後使用重塑(yin(3 * n + 1:end),3,3,n)。但我不確定如何矢量化矩陣乘法。

+0

謝謝。向量化我的特定形式的ODE_fn可能有點困難,但我可以嘗試。關於t0和tf也很好理解。 – db1234 2012-08-09 13:22:52

+0

只要將它看作是一個非耦合微分方程組。 – simmmons 2012-08-09 13:34:54

+0

解耦不是正確的詞。對於二維方程解耦意味着(xdot,ydot)=(f(x),g(y))。請注意,系統(xdot,ydot)=(f(x,y),g(x,y))未解耦。自從我演進矩陣以來,我所擁有的甚至更復雜一些...... – db1234 2012-08-09 14:12:14