找回密码
 注册
关于网站域名变更的通知
查看: 1070|回复: 3
打印 上一主题 下一主题

请问怎样用MATLAB求解微分方程组并画出解函数图?

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-4-20 10:27 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
求解微分方程组,画出解函数图。: Y, U" _1 I/ q; z

+ ^3 d) C0 g+ F. [1 c6 H, wx'= -x^3-y, x(0)=1     : |- g) ]  Y0 \4 k4 e, t* `) d% k; c
y'= x-y^3, y(0)=0.5   0<t<30
* l" _+ p2 s% }1 P- e. e$ m请教高手指点给出程序与结果,谢谢3 w  e( a, D) j# }9 Z
  • TA的每日心情

    2019-11-29 15:37
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 13:34 | 只看该作者
    本帖最后由 yin123 于 2020-4-20 13:36 编辑 # f+ |& e% w6 Q, N

    0 W" B( K# U8 ?6 Z% W碰巧正好学习了微分方程解法
    # {3 ]1 Q% y' rmatlab内置的函数(数值解法)有ode系列,help一下就可以了
    . B' b# p) M- F6 r如果你上的是有关数字分析的课程,我猜老师的意思应该让你自己写代码3 ~: M, p& ~* D7 c! K  r
    我分别尝试了Euler法 梯形法 四阶RK法  代码如下:- h- s/ Y% K8 M6 a; d* g& }
    以y‘=|sin2x、,y(0)=1为例:
    & Z- ~. R; V* \
    * F. N% H1 I. s% x编写一阶导数m文件:3 N* H3 @) {2 Z" l" Z: s: s$ f

    * p% n( f8 n7 j' r; V%一阶常微分方程的m文件& v, W6 N( m! o
    function y1=myfun(x,y)5 j  }' |7 Z3 E! A- d6 ~3 @
    y1=abs(sin(2*x));' Y; ~4 l0 Z2 S: _

    ) a. e$ A' E& Q3 h$ y, {
    0 P' b2 \) h8 ~+ t- s% c3 K7 ?
    4 j+ i/ ~: ?. c! xEuler法:4 F8 B5 J, N, p4 {% y* L9 X9 e' V5 T
    + U! p2 L+ D* t( d6 h$ z! s
    %向前差分Euler法解常微分方程7 x- t/ h3 J9 G$ q
        %fun:f(x)的一阶导数m文件
    . M$ _8 U: K: E5 S' Y& D  ^6 G0 d    %x0,xt:自变量的初值和终值) }$ I" F$ D, x7 q; Y) f* U
        %y0:f(x)在x0处的值7 c/ g/ a, s7 A/ j
        %h:步长
    - h& R( B* V1 p$ e& C" B9 rfunction [Eulerx,Eulery]=MyEuler(myfun,x0,xt,y0,h)
      k* ?( b/ Y) D5 _  j9 e  Cx=(x0:h:xt)';%定义自变量数组
    " A5 u  u  X+ B2 f  K9 gy(1,: )=y0;%初始化因变量数组) q. J1 D; F+ V+ E* M% i, O
    for k = 1:length(x)-1- q! z. P; K0 T3 \
        f=feval(myfun,x(k),y(k,: ));%计算每个迭代点的一阶导数值
    ' h# X% ?: z7 j# ^    f=f(: )';/ @6 r5 G" w2 ?+ l6 D
        y(k+1,: )=y(k,: )+h*f; %向前迭代' t8 n4 }% b- A7 u- D. i
    end6 F6 R6 H3 h% C# o2 A0 C
    Eulerx=x;
    , q8 Z& s: M* R. o0 L, yEulery=y;  Y. ~0 `9 E: m1 F( n

    9 h$ ~5 }) I9 I* H* c& @, L" ~( [( V7 y) m* S, u- ]4 B
    梯形法:
    ; E6 J* m% @" q; n" |
    : C" u2 N, D' ]! R: G0 l%梯形法解常微分方程! T" b+ ^) n) F
        %fun:f(x)的一阶导数m文件$ ^! R0 m7 P2 \* O5 p3 q4 V& X
        %x0,xt:自变量的初值和终值4 o1 }. A. R0 l$ Y" M4 N# ^
        %y0:f(x)在x0处的值- t' _- s/ t5 c6 Z& D
        %h:步长* c/ |- B- r5 P; x/ V
    function [Tixingx,Tixingy]=MyTixing(myfun,x0,xt,y0,h)
    % \- P% u4 u/ ?2 N4 r5 px=(x0:h:xt)';%定义自变量数组  Y) L6 S# p' H2 ]
    y(1,: )=y0;%初始化因变量数组6 _9 Y( h& {  Q( l7 V
    Y(1,: )=y0;%中间量
    1 m+ k' E8 M# y' j5 i1 [; bfor k=1:length(x)-1
    ( M+ ^/ ^% ^% C4 B5 c* {    f=feval(myfun,x(k),y(k,: ) );%计算每个迭代点的一阶导数值
      U; @8 w! \% Q9 k0 L- l; o    f=f(: )';
    # Y( v* @0 I5 k2 v* q! w. L' H/ A    Y(k+1,: )=y(k,: )+h*f; %y0(n+1)" M# U" y6 |3 E+ d) i4 |; G# a* t8 p
        F=feval(myfun,x(k+1),Y(k+1,: ));%计算每个迭代点的一阶导数值
    # x+ Y0 ?& t3 m! I    F=F(: )';. k& K3 P$ I2 E% p( F
        y(k+1,: )=y(k,: )+0.5*h*(f+F); %y(n+1); C/ |& E+ E8 h0 g- L4 w# G# E
    end
    & `, O5 Z5 S; B5 u) k5 V, ETixingx=x;
    ! u+ Z, s8 d8 S6 W8 |Tixingy=y;9 q7 }6 s/ b, M. k

    . C, T9 e4 E$ V3 Q6 H8 l: F6 z( v6 _+ g8 g+ ^; S
    四阶RK法:1 E" {' J# \, i4 G! O

      r' L( y. U1 L9 A%四阶Runge-Kutta法解常微分方程* ^+ A1 q5 {+ n4 Y# E% E
        %fun:f(x)的一阶导数m文件7 r% A- ^7 |* t) l: O/ `& T% h
        %x0,xt:自变量的初值和终值6 U+ n; W9 o  B
        %y0:f(x)在x0处的值
    # T5 M( _8 D7 Y# v4 r" O    %h:步长! g! ^. v! z: F
    function [RK4x,RK4y]=RK4(myfun,x0,xt,y0,h)
    1 W5 o# G$ {6 b$ @& k& h8 Ux=(x0:h:xt)';%定义自变量数组[code]clear all;clc;
    & y, l6 h! d4 Y4 m. Mx0=0;xt=2*pi;%x0,xt:自变量的初值和终值
    ; C6 o3 D, G+ K; q; @4 o( L; Ty0=1;%y0:f(x)在x0处的值
    & H% k3 v6 v# A" D% ?' ~7 W' g% ~h=0.2;%h:步长
    5 L+ M8 [) G, V8 z: V" q/ r[Eulerx,Eulery]=MyEuler(@myfun,x0,xt,y0,h);%欧拉法- L7 b5 D& d- d: ?
    a=fliplr(Eulery');%求算f(22*pi)
    " b( _# ^8 u; s! R- |. o- @% C* gy_Euler=a(1);
    ; B# W1 X" e1 a4 J8 O[Tixingx,Tixingy]=MyTixing(@myfun,x0,xt,y0,h);%梯形法: _, I6 d/ Q- M5 @2 I
    a=fliplr(Tixingy');%求算f(22*pi)0 ~, v$ d& T, j
    y_Tixing=a(1);8 D/ @, o+ R' o
    [RK4x,RK4y]=RK4(@myfun,x0,xt,y0,h);%四阶Runge-Kutta法法
    # h7 T& |! s: ?: Ba=fliplr(RK4y');%求算f(22*pi)  c- `( `& o7 U2 |
    y_RK4=a(1);8 s. g* @  X0 v2 {( L: \
    [ode45x,ode45y]=ode45(@myfun,[x0:h:xt],[1]);%matlab内置函数2 [; @: `& n  @, e* G8 ?9 U
    a=fliplr(ode45y');%求算f(22*pi)$ z5 I4 Z/ N4 X4 b/ r
    y_ode45=a(1);
    9 m3 |! ?1 |2 S& V3 w: i5 afigure;& Q+ E+ t+ v% }, g. F
    figure_FontSize=18; %修改字体
    % I0 w- L4 A4 S" ^/ uplot(Eulerx,Eulery,'ro',Tixingx,Tixingy,'g*',RK4x,RK4y,'bd',ode45x,ode45y,'ks','LineWidth',2);%做图( A( `! |" j: r: I1 B
    legend('Euler','Tixing','RK4','ode45');%图例8 c8 ?; `9 ^$ b7 k
    Y=[y_Euler,y_Tixing,y_RK4,y_ode45];
    4 e# V! }4 H9 r# V, s8 S# laxis([x0 xt y0 max(Y)]); %定义坐标轴范围3 u0 A1 P2 c- ]
    label1={'方法';'Euler';'Tixing';'RK4';'ode45'};  k/ [: L5 u7 @  H3 _& Q
    label2={'y(2π)';y_Euler;y_Tixing;y_RK4;y_ode45};) R' D- }& z# o! n  f- \
    % label=[label1,label2];( y$ f  Q/ d( j+ |2 {+ t5 i. g* C
    text(x0+0.1*(xt-x0),0.8*max(Y),label1); %显示y(2π)" A1 s" W- @' R4 C6 c
    text(x0+0.3*(xt-x0),0.8*max(Y),label2);
    ( n" D9 s  C, `+ h" ?0 m2 E; ?, M0 H# u4 Z! i) C' P" T2 M$ \* I  Z

    # u1 O5 {. Z* O( O, T6 Ry(1,: )=y0;%初始化因变量数组
    , j( [& z: s( R& s  i; Lfor k=1:length(x)-16 A& U6 l, q: f9 c8 K  Q8 n7 ^
        K1=feval(myfun,x(k),y(k,: ));%计算系数8 C, T2 T+ Z' t# L3 D
        K2=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K1');
    8 ?& \, F7 W6 k4 T$ ?    K3=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K2');
    / I8 B5 v- K1 T# B. T    K4=feval(myfun,x(k)+h,y(k,: )+h*K3');+ }  \$ u  W/ k5 y% Q) t& k
        y(k+1,: )=y(k,: )+(1/6)*h*(K1'+2*K2'+2*K3'+K4');%迭代
    8 B) w. e$ J' qend
    - [; P. ?: w) d; u7 pRK4x=x;
    + L$ Q' }/ r  ^) k% BRK4y=y;

    该用户从未签到

    3#
    发表于 2020-4-20 13:39 | 只看该作者

    , [7 m# f' e2 Y$ @8 z9 o8 H- |; r楼主的图用Forcal绘制,代码:
    • !using["XSLSF"];                //使用命名空间XSLSF
    • //数组xArray存放x的值;ti为当前有效值的个数;tmax为ti对应的时间;tmin为起始时间。
    • xt(t:k:xArray,ti,tmax,tmin)=
    • {
    •   k=(t-tmin)/(tmax-tmin)*ti-1,
    •   if[k<0, k=0], if[k>=ti, k=ti-1],
    •   xArray.getrai[k]
    • };
    • //数组yArray存放y的值;ti为当前有效值的个数;tmax为ti对应的时间;tmin为起始时间。
    • yt(t:k:yArray,ti,tmax,tmin)=
    • {
    •   k=(t-tmin)/(tmax-tmin)*ti-1,
    •   if[k<0, k=0], if[k>=ti, k=ti-1],
    •   yArray.getrai[k]
    • };
    • //函数定义,用于计算微分方程组中各方程右端函数值,连分式法对微分方程组积分一步函数pbs1将调用该函数f。
    • //t为自变量,x,y为函数值,dx,dy为右端函数值(即微分方程的值)。
    • f(t,x,y,dx,dy)=
    • {
    •   dx=-(x^3)-y,
    •   dy=x-y^3
    • };
    • //用连分式法对微分方程组进行积分,获得理论值。
    • //t1,t2为积分的起点和终点。
    • //h,s为自动变量。
    • //模块变量:hf为函数f的句柄,要预先获得该句柄;Array为工作数组;step为积分步长;eps为积分精度。
    • 积分(t1,t2:h,s:hf,Array,step,eps)=
    • {
    •   s=ceil[(t2-t1)/step],        //计算积分步数
    •   h=(t2-t1)/s,                 //重新计算积分步长
    •   {   pbs1[hf,t1,Array,h,eps], //对微分方程组积分一步
    •       t1=t1+h                  //积分步长增加
    •   }.until[abs(t1-t2)<h/2]      //连续积分至t2
    • };
    • 数据(:i,h,t1,t2,x,y,static,free:hf,Array,step,eps,max,xArray,yArray,ti,tmax,tmin)= //微分方程组积分获得数据
    • {
    •   if[free,delete(Array),delete(xArray),delete(yArray),return(0)],
    •   hf=HFor("f"),                               //模块变量hf保存函数f的句柄,预先用函数HFor获得该句柄
    •   step=0.01,eps=1e-6,                         //积分步长step要合适,积分精度eps越小越精确,用于对微分方程组积分一步函数pbs1
    •   Array=new[rtoi(real_s),rtoi(2*15)],         //申请工作数组
    •   max=1001,
    •   xArray=new[rtoi(real_s),rtoi(max)],         //申请工作数组
    •   yArray=new[rtoi(real_s),rtoi(max)],         //申请工作数组
    •   Array.setra(0,1,0.5),                         //设置积分初值,通过模块变量Array传递,Array是一个数组
    •   xArray.setra(0,1),                          //设置xArray的第一个值
    •   yArray.setra(0,0.5),                          //设置yArray的第一个值
    •   ti=1, h=step*3, tmin=0, tmax=0, t1=0, t2=h,
    •   i=1,(i<max).while{
    •     积分(&t1,t2),                             //从t1积分到t2
    •     Array.getra(0,&x,&y),                     //从数组Array获得t2时的积分值
    •     xArray.setra(i,x), yArray.setra(i,y),     //将积分值保存到数组
    •     ti=i+1, tmax=t1, t2=t2+h,
    •     i++
    •   }
    • };
    • //绘制函数图形
    • (::hxt,hyt)= hxt=HFor("xt"), hyt=HFor("yt");  //获得函数xt和yt的句柄,保存在模块变量中
    • gleDrawScene[HFor("Scene")],stop();      //设置场景绘制函数后退出
    • Scene(::hxt,hyt,tmax,tmin)=
    • {
    •     glClear[],                           //清除屏幕以及深度缓存
    •     glLoadIdentity[],                    //重置视图
    •     glTranslated[0,0,-20],               //移动坐标,向屏幕里移动10个单元
    •     glColor3d[0,0,1],                    //设置颜色
    •     fgPlot[hxt,tmin,tmax,FG_Y,-1,2],   //绘制一元函数图象
    •     glColor3d[1,0,0],                    //设置颜色
    •     fgPlot[hyt,tmin,tmax,FG_Y,-1,2]    //绘制一元函数图象
    • };
      # {4 ~" g; \2 C* e/ b! N% K/ w

    5 X5 h3 I5 |9 M

    # s  l3 v. A# l- B6 Z& W( }- V9 l- T

    $ n; ^+ C" z2 B5 n" o% V, T 9 {. d) x- D, B( W# @1 o
    1 u; t$ {5 h( o1 S0 s" W% U
    . W( s+ b" F' ?7 j1 f( j$ w7 V

    * @, k3 R& R" `6 X! k' b3 E$ K* u4 R7 `! O% S

    该用户从未签到

    4#
    发表于 2020-4-20 13:39 | 只看该作者
    用1stOpt更简单:% {  h" q+ z* K: D1 C5 v3 s
    • Variable t=[0:0.2:30],x=1,y=0.5;
    • Plot x,y;
    • ODEFunction x'= -x^3-y, y'= x-y^3;
      / P: A1 C& D0 a4 ^+ b( R+ F9 ]& x3 a

    6 b. k1 e3 E# k0 E0 I! Z
    + ~. i( K' S/ V) U( w
      w7 `6 N" W5 Z6 k1 r9 E& |
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-6 13:07 , Processed in 0.140625 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表