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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
求解微分方程组,画出解函数图。2 O4 l' e# r" A1 r

: d" t) R4 e1 @0 C! Cx'= -x^3-y, x(0)=1     
( R$ B4 T8 r+ qy'= x-y^3, y(0)=0.5   0<t<30
1 b; @* V3 v, \# U  X' g/ Q' u& Q请教高手指点给出程序与结果,谢谢# x+ C) @. K* R% L% D: w
  • TA的每日心情

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

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 13:34 | 只看该作者
    本帖最后由 yin123 于 2020-4-20 13:36 编辑 , ~* P9 s/ a0 m4 k

    , ]& S8 y8 l' R/ K碰巧正好学习了微分方程解法
    8 ^' Q! o* y7 o- L2 amatlab内置的函数(数值解法)有ode系列,help一下就可以了
    ; w4 w- |. A8 x) w5 c0 }0 m9 X' v如果你上的是有关数字分析的课程,我猜老师的意思应该让你自己写代码: w) m# R9 ~5 ]1 b# C: m- o( b
    我分别尝试了Euler法 梯形法 四阶RK法  代码如下:
    * ^: B4 k  ^3 B; ^3 v" z以y‘=|sin2x、,y(0)=1为例:
    ( V) L, G* A+ E7 \8 G! W
    . F6 @- A$ z! g7 J% L编写一阶导数m文件:
    # k5 Q' t% }9 x2 b& D6 F2 ~% W1 J0 |! b" M1 N
    %一阶常微分方程的m文件
    2 b& Y8 V$ k: {& _' V3 m" mfunction y1=myfun(x,y)3 `% P$ x8 U6 U
    y1=abs(sin(2*x));4 ~3 h3 w2 X  j/ Y! L% O% e0 z
    : p0 p$ k- k/ U. E2 T. w% i

    " m6 q5 X/ d, ~7 V9 G9 i$ Q  T0 `9 o! p% C$ k; l- |
    Euler法:  P1 b$ j( \& u. G6 Q
    7 W3 x2 L8 q* ?- T0 J
    %向前差分Euler法解常微分方程9 }" j' y  e) J
        %fun:f(x)的一阶导数m文件& z( D: |, ^& ?
        %x0,xt:自变量的初值和终值" c8 Q4 W( T& `! Y6 ^+ i& }; @8 E
        %y0:f(x)在x0处的值% v0 P  B7 |, Z/ f* {
        %h:步长4 \8 M$ P( L. c5 b) `$ R' S+ Q
    function [Eulerx,Eulery]=MyEuler(myfun,x0,xt,y0,h)- E' l9 R/ P, Z% H9 E- `: p3 e
    x=(x0:h:xt)';%定义自变量数组
    / N, m6 h: Q3 Y' W/ o& B2 k* _y(1,: )=y0;%初始化因变量数组7 `8 E9 B6 R: z
    for k = 1:length(x)-1
    - m# k* y/ ?: E* Z: w7 ~    f=feval(myfun,x(k),y(k,: ));%计算每个迭代点的一阶导数值5 v0 e5 ~1 l+ x6 Z7 I3 P1 s( @
        f=f(: )';! b5 _7 g: W* T! m
        y(k+1,: )=y(k,: )+h*f; %向前迭代
    7 @1 ?- a+ f% ]: D6 oend
    ( C( X( o6 `: f  n8 ]9 R; p, UEulerx=x;
    ( r. n6 L' A' U' ]2 w( WEulery=y;* d/ O$ ]3 U- V. h$ o6 ?9 v- A7 k# x

    0 h4 B+ w0 u( o7 O, p1 h3 A  L+ Z; f$ ]: p/ }
    梯形法:- ^; i7 D$ Q7 Y' Y* |: `

    ; J+ e9 {% m" o# Z' Q%梯形法解常微分方程: ?$ x' V9 \0 B/ j
        %fun:f(x)的一阶导数m文件7 w8 ?2 o/ u9 n2 f
        %x0,xt:自变量的初值和终值! l' _3 m6 e4 u) w
        %y0:f(x)在x0处的值1 O/ o4 t% K, ^: ]% y: Q3 z. x8 U5 U
        %h:步长
    6 i8 Z; u) ^9 y7 k0 F0 |, i( V7 [7 H$ ifunction [Tixingx,Tixingy]=MyTixing(myfun,x0,xt,y0,h)
    7 r0 \' u- L* C. _0 Lx=(x0:h:xt)';%定义自变量数组( m  V$ @& v7 D* X" Z8 E, s2 v
    y(1,: )=y0;%初始化因变量数组
    % d9 O% A0 c$ ~1 b) W% r4 NY(1,: )=y0;%中间量8 K9 {: p/ R# Y& f$ g+ z" D1 a
    for k=1:length(x)-1
    : H, Z; L  x7 R$ O! F) v    f=feval(myfun,x(k),y(k,: ) );%计算每个迭代点的一阶导数值# y/ D( ?9 Q  T% r) L  m* L
        f=f(: )';5 y; ~3 q- y$ S! p* X7 S* z6 k
        Y(k+1,: )=y(k,: )+h*f; %y0(n+1): y# T2 \* s5 N+ Y6 T2 n
        F=feval(myfun,x(k+1),Y(k+1,: ));%计算每个迭代点的一阶导数值
    2 h( y7 F; y* w, D& I  |    F=F(: )';7 U/ `0 D  o+ {* j1 t9 A
        y(k+1,: )=y(k,: )+0.5*h*(f+F); %y(n+1)* E" i+ G4 ~$ E1 `9 n/ \. k% z
    end: L) M+ N2 u4 W2 E. V- U* F
    Tixingx=x;/ _  n; @* c3 a0 {4 v
    Tixingy=y;/ b: [7 f2 c$ o6 W$ v, s- S
    ! ~4 z& L9 ]2 ]) o$ ]" U3 B
    + p$ I7 e' F; u( j( K
    四阶RK法:% M1 Y9 M9 U0 Q

    ! h  q3 U$ O) {9 `%四阶Runge-Kutta法解常微分方程# |2 l& U+ C6 G( T, b$ g) E
        %fun:f(x)的一阶导数m文件
    2 T$ q8 f8 u. V! m3 t' ?    %x0,xt:自变量的初值和终值
    2 l8 b2 Y" r6 o9 z9 P    %y0:f(x)在x0处的值
    3 U  G* A, S9 X$ L* K: I    %h:步长
    . F4 Q( ~$ L. a$ C( m5 b* |& `1 Qfunction [RK4x,RK4y]=RK4(myfun,x0,xt,y0,h)
    & _  N! M, |6 f9 N1 Gx=(x0:h:xt)';%定义自变量数组[code]clear all;clc;
    7 L. A3 V/ B* ix0=0;xt=2*pi;%x0,xt:自变量的初值和终值, p( }" P" m- d& J& m
    y0=1;%y0:f(x)在x0处的值
    + O6 f; U2 C: y9 A" U4 W+ Nh=0.2;%h:步长
    - b, B" d7 I* R  x" p1 T$ y) j[Eulerx,Eulery]=MyEuler(@myfun,x0,xt,y0,h);%欧拉法
    4 [/ o  a3 s& S: k. O: Ta=fliplr(Eulery');%求算f(22*pi)
    6 g8 W, N0 g3 Uy_Euler=a(1);7 e8 T2 [2 R7 h# P- V0 Y. i
    [Tixingx,Tixingy]=MyTixing(@myfun,x0,xt,y0,h);%梯形法
    3 D* L& x  ]# }5 Ja=fliplr(Tixingy');%求算f(22*pi)$ @; ?, C0 |! f% e
    y_Tixing=a(1);% U2 ?2 ^0 k' e; S; J
    [RK4x,RK4y]=RK4(@myfun,x0,xt,y0,h);%四阶Runge-Kutta法法
    ' y9 Y) h  W6 a7 Ea=fliplr(RK4y');%求算f(22*pi)! [0 r- t+ K4 b3 h* {
    y_RK4=a(1);5 T; R- g" w+ {4 _# Z1 b  b
    [ode45x,ode45y]=ode45(@myfun,[x0:h:xt],[1]);%matlab内置函数: z8 H0 T- c, v, \  Q" y3 L5 C
    a=fliplr(ode45y');%求算f(22*pi)
    6 I+ U1 _, F8 D8 r" p8 o  H' u# |# R+ oy_ode45=a(1);
    ! g$ l! T% a+ @1 yfigure;
    * \+ d7 h$ d( Z7 `- sfigure_FontSize=18; %修改字体
    - v( H; z) M( d6 h3 _plot(Eulerx,Eulery,'ro',Tixingx,Tixingy,'g*',RK4x,RK4y,'bd',ode45x,ode45y,'ks','LineWidth',2);%做图
    9 {7 U) z. P2 t; Llegend('Euler','Tixing','RK4','ode45');%图例; Q- I+ e7 C8 X9 k' o' B
    Y=[y_Euler,y_Tixing,y_RK4,y_ode45];
    ! @: Q! A( H& D' b3 _2 ^axis([x0 xt y0 max(Y)]); %定义坐标轴范围- W6 s+ Y* Z$ F" w: l+ [( S: f& O# K
    label1={'方法';'Euler';'Tixing';'RK4';'ode45'};
    0 C/ X, i  v% x' i7 tlabel2={'y(2π)';y_Euler;y_Tixing;y_RK4;y_ode45};) Z# M; H: m; m/ Y* J7 K6 k  V
    % label=[label1,label2];
    ! I% z$ v" u3 b; O' s. D  z% O7 ]text(x0+0.1*(xt-x0),0.8*max(Y),label1); %显示y(2π)
    5 N, Z7 |1 u( xtext(x0+0.3*(xt-x0),0.8*max(Y),label2);
    8 f; ~( c( O/ {# }: z- Z9 z
    ! [0 |! U4 l7 e" Q5 T1 t. H  Y# H4 V
    0 |4 X4 V& S; r/ q  M  @y(1,: )=y0;%初始化因变量数组: a* Z. o$ f- g' s
    for k=1:length(x)-1! N& {$ ~! M% _8 s' D8 s8 k
        K1=feval(myfun,x(k),y(k,: ));%计算系数
    & v3 R) v+ j/ ]) D: j7 F    K2=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K1');' h5 T5 H% s9 H9 ^7 M# J/ t% H4 f2 R0 K
        K3=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K2');* O/ ^- D7 d# n% E6 t
        K4=feval(myfun,x(k)+h,y(k,: )+h*K3');
    & B& h/ f7 c6 S% ^# n    y(k+1,: )=y(k,: )+(1/6)*h*(K1'+2*K2'+2*K3'+K4');%迭代' b# t+ F. _8 j
    end/ _  }6 [0 h! A7 h. G, ]3 v
    RK4x=x;8 N9 ~4 M& ]5 _
    RK4y=y;

    该用户从未签到

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

    ' z; K/ U; c) I- n- d9 o7 v楼主的图用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]    //绘制一元函数图象
    • };
      7 W! K$ M: x4 p! E$ _

      A" {2 y; [$ U4 z: _9 V7 Z8 W2 s
    7 }; ?7 p/ X8 ~, W
    ) C' y: z" ?5 v2 k2 ]
    5 s' W- D( ^3 s1 b, A- G

    # `& y' L& R) A- c
      ]  m2 A3 H. l3 t) m5 n1 f3 g4 t* _& m# c
    - S5 o7 b( o9 h
    1 \; p6 V& N; c5 e' I0 e9 m

    该用户从未签到

    4#
    发表于 2020-4-20 13:39 | 只看该作者
    用1stOpt更简单:3 b2 j1 _$ n9 Q
    • Variable t=[0:0.2:30],x=1,y=0.5;
    • Plot x,y;
    • ODEFunction x'= -x^3-y, y'= x-y^3;/ a+ `5 T+ t+ l$ f; O

    - p7 L4 V7 u# \, J

    $ r9 Y7 L% H  n6 {( I: ?) p" x' X$ r7 F
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 01:50 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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