繁体   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