简体   繁体   English

MATLAB解决常微分方程

[英]MATLAB solve Ordinary Differential Equations

How can I use matlab to solve the following Ordinary Differential Equations? 如何使用matlab求解以下常微分方程?

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

with two known points, such as t=0: x(0)= x0, y(0) = y0; 具有两个已知点,例如t = 0:x(0)= x0,y(0)= y0; t=1: x(1) = x1, y(1) = y1 ? t = 1:x(1)= x1,y(1)= y1吗? It doesn't need to be a complete formula if it is difficult. 如果很困难,则不必是一个完整的公式。 A numerical solution is ok, which means, given a specific t, I can get the value of x(t) and y(t). 数值解是可以的,这意味着,给定特定的t,我可以得到x(t)和y(t)的值。

If matlab is hard to do this, mathematica is also OK. 如果matlab很难做到这一点,mathematica也可以。 But as I am not familiar with mathematica, so I would prefer matlab if possible. 但是由于我对mathematica不熟悉,因此,如果可能的话,我更喜欢使用matlab。

Looking forward to help, thanks! 期待帮助,谢谢!

I asked the same question on stackexchange, but haven't get good answer yet. 我在stackexchange上问了同样的问题,但是还没有很好的答案。 https://math.stackexchange.com/questions/812985/matlab-or-mathematica-solve-ordinary-differential-equations https://math.stackexchange.com/questions/812985/matlab-or-mathematica-solve-ordinary-differential-equations

Hope I can get problem solved here! 希望我能在这里解决问题!

What I have tried is: 我试过的是:

---------MATLAB --------- MATLAB

syms t 符号

>> [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 -------- MATLAB

Also, I tried to add conditions, such as x(0) = 2, y(0)=8, x(1) = 7, y(1) = 18, and the errors are still similar. 另外,我尝试添加条件,例如x(0)= 2,y(0)= 8,x(1)= 7,y(1)= 18,并且错误仍然相似。 So what I think is that this cannot be solve by dsolve function. 所以我认为这不能通过dsolve函数解决。

So, again, the key problem is, given two known points, such as when t=0: x(0)= x0, y(0) = y0; 因此,关键的问题是,给定两个已知点,例如当t = 0时:x(0)= x0,y(0)= y0; t=1: x(1) = x1, y(1) = y1 , how I get the value of x(t) and y(t)? t = 1:x(1)= x1,y(1)= y1,我怎么得到x(t)和y(t)的值?

Update: I tried ode45 functions. 更新:我尝试了ode45函数。 First, in order to turn the 2-order equations into 1-order, I set x1 = x, x2=y, x3=x', x4=y'. 首先,为了将2阶方程变成1阶,我设置x1 = x,x2 = y,x3 = x',x4 = y'。 After some calculation, the equation becomes: 经过一些计算,等式变为:

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)

So the matlab code I wrote is: 所以我写的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)

It can work. 它可以工作。 However, actually this is not right. 但是,实际上这是不对的。 Because, what I know is that when t=0, the value of x and y, which is x(1) and x(2); 因为,我知道的是,当t = 0时,x和y的值分别为x(1)和x(2); and when t=1, the value of x and y. 当t = 1时,x和y的值。 But the ode functions need the initial value: x0, I just wrote the condition x0 = [2 3 5 7]' randomly to help this code work. 但是ode函数需要初始值:x0,我只是随机编写条件x0 = [2 3 5 7]'以帮助此代码工作。 So how to solve this problem? 那么如何解决这个问题呢?

UPDATE: I tried to use the function bvp4c after I realized that it is a boundary value problem and the following is my code (Suppose the two boundry value conditions are: when t=0: x=1, y=3; when t=1, x=6, y=9. x is x(1), y is x(2) ): 更新:我意识到这是一个边界值问题并且下面是我的代码后,我尝试使用函数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,:)

It can work, but I don't know whether it is right. 它可以工作,但我不知道它是否正确。 I will check it again to make sure it is the right code. 我将再次检查以确保它是正确的代码。

EDIT: This is how I would solve the problem. 编辑:这就是我要解决的问题。 Note: I don't really like the matlabFunction creator but this is simply a personal preference for various reasons I won't go into. 注意:我不是很喜欢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')

As in my comments I have made a lot of assumtions that you need to fix for example, you didn't specify what the initial conditions for the first derivatives of the states are ie (z1, z3) which is important for the response of the system. 正如我在评论中所做的那样,我做了很多假设,例如,您没有指定状态的一阶导数的初始条件(即(z1,z3)),这对于响应响应非常重要。系统。 Also you didn't specify the time interval your interested for the simulation etc. 另外,您也没有指定您对仿真感兴趣的时间间隔等。

Note: The second m file can be used with any state function in the correct format 注意:第二个m文件可以与任何状态函数一起使用,格式正确

As mentioned, this isn't a math site, so try to give code or something showing some effort. 如前所述,这不是一个数学网站,因此请尝试提供代码或需要付出一些努力的东西。 However, the first step you need to do is turn the DE into normal form (ie, no 2nd derivatives). 但是,您需要做的第一步是将DE转换为正常形式(即没有二阶导数)。 You do this by making a separate variable equal to the derivative. 您可以通过使单独的变量等于导数来实现。 Then, you use 然后,您使用

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

to define variables as symbolic. 将变量定义为符号。 Use matlabfunction to create a symbolic function based on these variables. 使用matlabfunction基于这些变量创建符号函数。 Finally, you can use the ode45 function to solve the symbolic function while passing variable values. 最后,您可以在传递变量值时使用ode45函数来解决符号函数。 I recommend you look up the full documentation in matlab in order to understand it better, but here is a very basic syntax: 我建议您在matlab中查找完整的文档,以更好地理解它,但这是一个非常基本的语法:

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

Hopefully this puts you in the right direction, so try messing around with it and provide code if you need more help. 希望这可以为您提供正确的方向,因此,如果需要更多帮助,请尝试弄乱它并提供代码。

The following is the answer we finally get @Chriso: use matlab bvp4c function to solve this boundary value problem (Suppose the two boundry value conditions are: when t=0: x=1, y=3; when t=1, x=6, y=9. x is x(1), y is x(2) ): 以下是我们最终得到@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