簡體   English   中英

MATLAB解決常微分方程

[英]MATLAB solve Ordinary Differential Equations

如何使用matlab求解以下常微分方程?

x''/ y = y''/ x =-(x''y + 2x'y'+ xy'')

具有兩個已知點,例如t = 0:x(0)= x0,y(0)= y0; t = 1:x(1)= x1,y(1)= y1嗎? 如果很困難,則不必是一個完整的公式。 數值解是可以的,這意味着,給定特定的t,我可以得到x(t)和y(t)的值。

如果matlab很難做到這一點,mathematica也可以。 但是由於我對mathematica不熟悉,因此,如果可能的話,我更喜歡使用matlab。

期待幫助,謝謝!

我在stackexchange上問了同樣的問題,但是還沒有很好的答案。 https://math.stackexchange.com/questions/812985/matlab-or-mathematica-solve-ordinary-differential-equations

希望我能在這里解決問題!

我試過的是:

--------- MATLAB

符號

>> [x, y] = dsolve('(D2x)/y = -(y*D2x + 2Dx*Dy + x*D2y)', '(D2y)/x = -(y*D2x + 2Dx*Dy + x*D2y)','t')


Error using sym>convertExpression (line 2246)
Conversion to 'sym' returned the MuPAD error: Error: Unexpected 'identifier'.
[line 1, col 31]

Error in sym>convertChar (line 2157)
s = convertExpression(x);

Error in sym>convertCharWithOption (line 2140)
    s = convertChar(x);

Error in sym>tomupad (line 1871)
    S = convertCharWithOption(x,a);

Error in sym (line 104)
        S.s = tomupad(x,'');

Error in dsolve>mupadDsolve (line 324)
sys = [sys_sym sym(sys_str)];

Error in dsolve (line 186)
sol = mupadDsolve(args, options);

-------- MATLAB

另外,我嘗試添加條件,例如x(0)= 2,y(0)= 8,x(1)= 7,y(1)= 18,並且錯誤仍然相似。 所以我認為這不能通過dsolve函數解決。

因此,關鍵的問題是,給定兩個已知點,例如當t = 0時:x(0)= x0,y(0)= y0; t = 1:x(1)= x1,y(1)= y1,我怎么得到x(t)和y(t)的值?

更新:我嘗試了ode45函數。 首先,為了將2階方程變成1階,我設置x1 = x,x2 = y,x3 = x',x4 = y'。 經過一些計算,等式變為:

x(1)' = x(3)                                                (1)

x(2)' = x(4)                                                (2)

x(3)' = x(2)/x(1)*(-2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2))     (3)

x(4)' = -2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)                 (4)

所以我寫的matlab代碼是:

myOdes.m

function xdot = myOdes(t,x)

xdot = [x(3); x(4); x(2)/x(1)*(-2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)); -2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)]

end

main.m
t0 = 0;
tf = 1;
x0 = [2 3 5 7]';
[t,x] = ode45('myOdes',[t0,tf],x0);
plot(t,x)

它可以工作。 但是,實際上這是不對的。 因為,我知道的是,當t = 0時,x和y的值分別為x(1)和x(2); 當t = 1時,x和y的值。 但是ode函數需要初始值:x0,我只是隨機編寫條件x0 = [2 3 5 7]'以幫助此代碼工作。 那么如何解決這個問題呢?

更新:我意識到這是一個邊界值問題並且下面是我的代碼后,我嘗試使用函數bvp4c(假定兩個邊界值條件是:當t = 0時:x = 1,y = 3;當t = 1,x = 6,y = 9。x是x(1),y是x(2)):

1. bc.m
function res = bc(ya,yb)
res = [ ya(1)-1; ya(2)-3; yb(1) - 6; yb(2)-9];
end
2. ode.m
function dydx = ode(t,x)
dydx = [x(3); x(4); x(2)/x(1)*(-2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)); -2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)];
end
3. mainBVP.m
solinit = bvpinit(linspace(0,6,10),[1 0 -1 0]);
sol = bvp4c(@ode,@bc,solinit);
t = linspace(0,6);
x = deval(sol,t);
plot(t,x(1,:));
hold on
plot(t,x(2,:));

plot(t,x(3,:));

plot(t,x(4,:));
x(1,:)
x(2,:)

它可以工作,但我不知道它是否正確。 我將再次檢查以確保它是正確的代碼。

編輯:這就是我要解決的問題。 注意:我不是很喜歡matlabFunction創建器,但是出於各種原因,這只是我的個人喜好。

% Seperate function of the first order state equations
function dz = firstOrderEqns(t,z)
    dz(4,1) = 0;
    dz(1) = -2.*z(3).*z(1).*z(4)./(1 + z(4).^2 + z(2).^2);
    dz(2) = z(1);
    dz(3) = -2.*z(2).*z(3).*z(1)./(1 + z(4).^2 + z(2).^2);
    dz(4) = z(3);
end

% runfirstOrderEqns
%% Initial conditions i.e. @ t=0
z1 = 5; % dy/dt = 5 (you didn't specify these initial conditions, 
%  these will depend on the system which you didn't really specify
z2 = 0; % y = 0
z3 = 5; % dx/dt = 5 (The same as for z1)
z4 = 0; % x = 0
IC = [z1, z2, z3, z4];
%% Run simulation
% Time vector: i.e closed interval [0,20]
t = [0,20]; % This is where you have to know about your system
           % i.e what is it's time domain.
           % Note: when a system has unstable poles at
           % certain places the solver can crash you need
           % to understand these.
% using default settings (See documentation ode45 for 'options') 
[T,Y] = ode45(@firstOrderEqns,t,IC);

%% Plot function
plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),':',T,Y(:,4),'.');
legend('dy/dt','y','dx/dt','x')

正如我在評論中所做的那樣,我做了很多假設,例如,您沒有指定狀態的一階導數的初始條件(即(z1,z3)),這對於響應響應非常重要。系統。 另外,您也沒有指定您對仿真感興趣的時間間隔等。

注意:第二個m文件可以與任何狀態函數一起使用,格式正確

如前所述,這不是一個數學網站,因此請嘗試提供代碼或需要付出一些努力的東西。 但是,您需要做的第一步是將DE轉換為正常形式(即沒有二階導數)。 您可以通過使單獨的變量等於導數來實現。 然后,您使用

syms x y % or any variable instead of x or y

將變量定義為符號。 使用matlabfunction基於這些變量創建符號函數。 最后,您可以在傳遞變量值時使用ode45函數來解決符號函數。 我建議您在matlab中查找完整的文檔,以更好地理解它,但這是一個非常基本的語法:

MyFun= matlabFunction(eq,'vars',{x,y});
[xout,yout]=ode45(@(x,Y) MyFun(variables),[variable values],Options);

希望這可以為您提供正確的方向,因此,如果需要更多幫助,請嘗試弄亂它並提供代碼。

以下是我們最終得到@Chriso的答案:使用matlab bvp4c函數解決該邊值問題(假設兩個邊界值條件為:當t = 0時:x = 1,y = 3;當t = 1時,x = 6,y = 9。x是x(1),y是x(2)):

1. bc.m
function res = bc(ya,yb)
res = [ ya(1)-1; ya(2)-3; yb(1) - 6; yb(2)-9];
end
2. ode.m
function dydx = ode(t,x)
dydx = [x(3); x(4); x(2)/x(1)*(-2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)); -2*x(1)*x(3)*x(4)/(1+x(1)^2+x(2)^2)];
end
3. mainBVP.m
solinit = bvpinit(linspace(0,6,10),[1 0 -1 0]);
sol = bvp4c(@ode,@bc,solinit);
t = linspace(0,6);
x = deval(sol,t);
plot(t,x(1,:));
hold on
plot(t,x(2,:));

plot(t,x(3,:));

plot(t,x(4,:));
x(1,:)
x(2,:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM