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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
求解微分方程组,画出解函数图。6 h! h+ y! W. j- C% [; |2 J& W
  g+ b5 I) N* ~, F2 U
x'= -x^3-y, x(0)=1     6 K7 U& S/ ~" E- Q& N
y'= x-y^3, y(0)=0.5   0<t<30
" q+ B' N; F, ~+ \1 T" H+ D# Y请教高手指点给出程序与结果,谢谢4 g( z6 r0 C- ]$ {
  • TA的每日心情

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

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 13:34 | 只看该作者
    本帖最后由 yin123 于 2020-4-20 13:36 编辑 + [5 g" Q7 c" q- P- u8 ~' X5 o

    % [+ H# v8 P, t" A0 ~碰巧正好学习了微分方程解法. `# @8 z4 Z& n0 T2 ]) X
    matlab内置的函数(数值解法)有ode系列,help一下就可以了/ S3 |. i  L( @2 s8 ~2 W
    如果你上的是有关数字分析的课程,我猜老师的意思应该让你自己写代码' `$ @; [" a7 [( T8 V" H6 u
    我分别尝试了Euler法 梯形法 四阶RK法  代码如下:6 F; ~$ [  R( |+ T) m( ?% z' n+ D& v
    以y‘=|sin2x、,y(0)=1为例:3 h" l  F9 a- K/ C' K
    1 D3 }2 V, }; u9 T
    编写一阶导数m文件:, s$ ^# O% f9 R0 ~8 k, |. i

    8 z  }4 {1 ^7 Q4 b%一阶常微分方程的m文件
    % r$ \/ D. `& S+ l4 c3 Zfunction y1=myfun(x,y)  y/ @3 S% h% m& P. {% ]
    y1=abs(sin(2*x));5 p# N$ s% c/ e
    : |  _# F/ V3 h4 b* e2 J2 D
    $ z$ d) N: a- R( b  \6 J/ e, w3 T

    , T) B1 o- L. k: y" WEuler法:; K1 d& N! Y; _$ J7 D- e2 l
    # z% J0 O) F/ l
    %向前差分Euler法解常微分方程1 O& ~  ?9 p3 F/ ?
        %fun:f(x)的一阶导数m文件
    2 w! M# V0 R0 |! v, y% a% h    %x0,xt:自变量的初值和终值# h* `4 S% g6 W- o; O
        %y0:f(x)在x0处的值# R  ]& `' I% a. U! H- C
        %h:步长
    1 ~) u1 {5 B5 z+ U1 ^, Cfunction [Eulerx,Eulery]=MyEuler(myfun,x0,xt,y0,h)
    0 J. {2 K" |& Y. a2 hx=(x0:h:xt)';%定义自变量数组
    ) L% ?: ]2 B* `9 B- w3 A0 ny(1,: )=y0;%初始化因变量数组
    5 B: x) A% ^4 l& g7 Dfor k = 1:length(x)-1
    $ P' ^  q# x& Y  s    f=feval(myfun,x(k),y(k,: ));%计算每个迭代点的一阶导数值  U* F$ U' ]6 ]7 X; F
        f=f(: )';
    - l) B( e/ r: E; J5 a    y(k+1,: )=y(k,: )+h*f; %向前迭代
    0 a& a6 M) v: ]9 B6 p' Wend
    ) Z7 n+ F. f1 e! L' _0 eEulerx=x;8 m3 n: @. c% p
    Eulery=y;
    ( R5 J/ v8 J: ]1 k& r& P4 W/ z: _: a6 P1 R9 G" p
    2 @/ P( u6 K& j
    梯形法:( i; q' Z$ q8 M2 Y) J  ]" D
    # l" o9 {" B2 R- k& U8 Q+ G
    %梯形法解常微分方程' y- Z; h' C1 N' q; {0 ]& @
        %fun:f(x)的一阶导数m文件
    ' ~5 o/ L* B: U$ |8 ?9 \  c    %x0,xt:自变量的初值和终值# I0 P- C3 J: b" Z
        %y0:f(x)在x0处的值# m  Y5 T- g) }
        %h:步长
    ' R! z* f, E1 k) j' I2 F* \9 W. ]function [Tixingx,Tixingy]=MyTixing(myfun,x0,xt,y0,h)
    , x2 m2 T! a5 }$ N" B3 M/ y$ K) I7 bx=(x0:h:xt)';%定义自变量数组
    7 g! f! d( K9 |1 j  By(1,: )=y0;%初始化因变量数组& x! o2 [- p& r: t" ]! j2 T
    Y(1,: )=y0;%中间量# Q/ h; n) `' l: I+ U4 K, w' ?
    for k=1:length(x)-1
    ' x  |: N3 s- }" L    f=feval(myfun,x(k),y(k,: ) );%计算每个迭代点的一阶导数值
    5 _5 _6 |3 m5 e& ?) y5 O    f=f(: )';9 F) W  F+ `& g& ?- A! ^3 [
        Y(k+1,: )=y(k,: )+h*f; %y0(n+1)9 N  w- q3 E- m5 D* O, `7 u0 j
        F=feval(myfun,x(k+1),Y(k+1,: ));%计算每个迭代点的一阶导数值
    ) ?1 _* y8 G3 H( @    F=F(: )';
    " Z! }1 c2 h, b: ]$ g* V! Z    y(k+1,: )=y(k,: )+0.5*h*(f+F); %y(n+1)& ~$ P1 u* Q7 j: U1 T$ v
    end
    2 D, L6 o/ y5 N/ K7 JTixingx=x;# M6 j$ y" E: `* v  r' P! p
    Tixingy=y;
      c4 ?, j; ?3 w6 H2 r
    ) `& b7 o2 X. q+ {" [% E
    8 G! |( m( Y1 f. ]2 ^四阶RK法:
    ' J  l$ ^8 w7 p) n4 L
    # @% J1 Q; [1 \6 u# L%四阶Runge-Kutta法解常微分方程% _& e, i0 S2 G3 z
        %fun:f(x)的一阶导数m文件- @  n+ S: v2 X
        %x0,xt:自变量的初值和终值
    % O. o, I4 d4 J/ W9 s    %y0:f(x)在x0处的值( A, E5 R! {3 a0 y1 X5 F% a
        %h:步长6 f/ Y8 s/ A2 U8 i
    function [RK4x,RK4y]=RK4(myfun,x0,xt,y0,h)$ U1 F- x! D8 K- C6 Z
    x=(x0:h:xt)';%定义自变量数组[code]clear all;clc;
    , R5 q: W& G( k0 ]& Mx0=0;xt=2*pi;%x0,xt:自变量的初值和终值; R; J1 V% N" Q0 X
    y0=1;%y0:f(x)在x0处的值; K! x( F: @& F5 l
    h=0.2;%h:步长% W* k5 e0 Y( Y$ u7 |
    [Eulerx,Eulery]=MyEuler(@myfun,x0,xt,y0,h);%欧拉法
      k5 G$ r; L& C4 v, \a=fliplr(Eulery');%求算f(22*pi)+ r2 d; l# |  S7 G$ C
    y_Euler=a(1);
    . n  q& h2 }, S& R" V[Tixingx,Tixingy]=MyTixing(@myfun,x0,xt,y0,h);%梯形法
    + Q) P: [$ [3 e: v* Na=fliplr(Tixingy');%求算f(22*pi)
    4 Z' N, J8 I/ j6 V; h; i3 v- Vy_Tixing=a(1);
    3 u6 G0 e1 \2 ^$ L$ b+ T- ^[RK4x,RK4y]=RK4(@myfun,x0,xt,y0,h);%四阶Runge-Kutta法法3 j" Z2 q5 l- w" v/ _' N5 ~# O  X7 H
    a=fliplr(RK4y');%求算f(22*pi)4 H1 F! N' O5 `! y7 T
    y_RK4=a(1);( w+ |( i  j- ~( W( w  d. l
    [ode45x,ode45y]=ode45(@myfun,[x0:h:xt],[1]);%matlab内置函数( S1 p! [, {- f4 Z
    a=fliplr(ode45y');%求算f(22*pi)
    4 Y) q! o) X: Y) h: M# t+ }y_ode45=a(1);/ n& v1 ]; v8 L
    figure;
    . _& S3 u( s2 x9 C2 {. Zfigure_FontSize=18; %修改字体
    3 L8 C: @" _$ X  l2 \! Yplot(Eulerx,Eulery,'ro',Tixingx,Tixingy,'g*',RK4x,RK4y,'bd',ode45x,ode45y,'ks','LineWidth',2);%做图
    ; D, z$ r, v/ J! m& ~2 t0 Nlegend('Euler','Tixing','RK4','ode45');%图例
    6 w; \6 i9 H: x* @Y=[y_Euler,y_Tixing,y_RK4,y_ode45];; |, r2 w3 G$ {! y2 D/ `
    axis([x0 xt y0 max(Y)]); %定义坐标轴范围2 [9 G6 n5 ]3 H& j+ z/ ?
    label1={'方法';'Euler';'Tixing';'RK4';'ode45'};
    ! T: K. R& E1 J' o6 b% c! clabel2={'y(2π)';y_Euler;y_Tixing;y_RK4;y_ode45};$ x' N7 [. S" P+ F/ ^
    % label=[label1,label2];- V: ~2 ^# l5 p  ^) [6 T# F" e( {
    text(x0+0.1*(xt-x0),0.8*max(Y),label1); %显示y(2π)
    + T. x# N2 Q  e$ Itext(x0+0.3*(xt-x0),0.8*max(Y),label2);3 i! n' r8 r4 x0 m0 t* X9 s

    - J" O0 F- `. ]* z5 d% _" f  Z5 L- u, Z# G6 k3 V
    y(1,: )=y0;%初始化因变量数组
    9 c6 ^5 n7 N7 H2 P3 }( h. qfor k=1:length(x)-10 `) b9 [- b2 M$ q% i; h) ~  Y
        K1=feval(myfun,x(k),y(k,: ));%计算系数
    ! |4 D4 i  S/ V) ]; M& `- v2 ?; |    K2=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K1');
    " ^9 `+ C& G& w2 m    K3=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K2');
    0 V/ Q) F, G9 U$ T* P3 M    K4=feval(myfun,x(k)+h,y(k,: )+h*K3');' x- S+ J/ Z, P; z2 `9 ?) P+ k
        y(k+1,: )=y(k,: )+(1/6)*h*(K1'+2*K2'+2*K3'+K4');%迭代2 o! b: A! ], A6 Y; C+ I
    end
    : h" N. S9 ?* q* X* T' A1 JRK4x=x;, Y& ?0 q9 s& [4 U1 L2 `/ l
    RK4y=y;

    该用户从未签到

    3#
    发表于 2020-4-20 13:39 | 只看该作者
    5 }: ~. D; G+ b
    楼主的图用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]    //绘制一元函数图象
    • };
      " c  D& b+ f* V  w0 P2 |  s
    8 `3 h7 O* n1 F

    . A) r5 t' ^7 C
      n% ~3 j' Q# l& G. K/ I) f; c1 k: v8 V* _) C9 Y) r$ @
    ; N1 Z5 A: L: P3 P
    , C) c" v) |. l" k
    8 i4 V2 j9 _' E: B, t. r$ P

    ; J/ r+ C. x; r' ]; k, A% S" }
    ; [4 |9 `" A' F4 m9 r% E

    该用户从未签到

    4#
    发表于 2020-4-20 13:39 | 只看该作者
    用1stOpt更简单:
    : ?3 |6 G9 R( [: {- {! M' l
    • Variable t=[0:0.2:30],x=1,y=0.5;
    • Plot x,y;
    • ODEFunction x'= -x^3-y, y'= x-y^3;
      0 x" u, _3 h+ h& n* z6 D7 |# ^

    # ^' Y* k5 i9 Y2 I9 ^' B
    " }# S/ {) g3 @; s9 M

    " y/ X! Z. P% Y" j) w9 N
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 05:43 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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