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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
求解微分方程组,画出解函数图。" x  e& j; D$ `" x
3 f" P$ }* y  ]: E# U3 G
x'= -x^3-y, x(0)=1     % o/ ?2 i2 ~+ e: Z
y'= x-y^3, y(0)=0.5   0<t<304 _' S1 u0 S0 T. `, G8 y: `
请教高手指点给出程序与结果,谢谢& x! d2 E: B2 [. `  s7 A, M/ H. V$ z
  • TA的每日心情

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

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 13:34 | 只看该作者
    本帖最后由 yin123 于 2020-4-20 13:36 编辑
    7 {' V4 J  T/ g/ n5 a2 J! F( Q+ ]  V0 `& X$ C3 R
    碰巧正好学习了微分方程解法
    + g, E6 }: R: N; h! a( }matlab内置的函数(数值解法)有ode系列,help一下就可以了+ z# A5 a$ P5 n& P
    如果你上的是有关数字分析的课程,我猜老师的意思应该让你自己写代码
    # x- p1 Z0 C6 ^/ {1 w我分别尝试了Euler法 梯形法 四阶RK法  代码如下:
    $ N3 T* p6 D' o: y( ]以y‘=|sin2x、,y(0)=1为例:
    9 t: d! S1 C$ V  |3 I+ r' a
    ! n4 D9 v3 R& u! O编写一阶导数m文件:
    . Z9 }: X, k3 D! @6 G- Y4 j# E9 z" x! l7 Q( R0 k7 y* I
    %一阶常微分方程的m文件" k" a1 F* N4 Z+ u& F& D3 @0 b
    function y1=myfun(x,y)
    & p) l. g" G4 _4 uy1=abs(sin(2*x));3 N* p: O" K1 t$ m' u
    & {, g; ]7 v7 U5 ^, T

    ! G$ E. Q5 w) ~  K6 f1 a/ w" |2 s# \8 ^' y) i
    Euler法:
    1 F- y7 k& Y, r/ C% }! f( t1 ~/ Q/ l% _
    %向前差分Euler法解常微分方程% E6 U, k+ h" `  {+ `4 D
        %fun:f(x)的一阶导数m文件+ C. U* @! X5 h9 K
        %x0,xt:自变量的初值和终值( R# L5 c7 ^5 K% u
        %y0:f(x)在x0处的值
    & u3 i8 Y% [" L8 h& c5 @    %h:步长1 {# I/ p0 c+ k8 e
    function [Eulerx,Eulery]=MyEuler(myfun,x0,xt,y0,h). y& |, c! k$ S" }
    x=(x0:h:xt)';%定义自变量数组
    7 P6 m$ U" A2 p0 a0 t# qy(1,: )=y0;%初始化因变量数组& `+ G4 \. p8 o* ^; S! S
    for k = 1:length(x)-1
    5 D7 `' L& ^7 v" ^% ~  ]& U    f=feval(myfun,x(k),y(k,: ));%计算每个迭代点的一阶导数值
    # o' b+ u$ _2 o    f=f(: )';: c4 `" h# x* g9 {
        y(k+1,: )=y(k,: )+h*f; %向前迭代! ~, w9 D: h0 l; ]( d
    end0 m  p0 \4 X7 B
    Eulerx=x;
    ( ~) z9 y7 Q0 z" YEulery=y;
    " f4 s  n" U" y: p( a
    6 ~" `4 J- l! v! z! a* q+ p& F# D6 B: N6 i) E! P* b
    梯形法:
    & K% @% J. _+ ^  V+ P6 [' d) Z6 @3 G, G% L: R" D: g
    %梯形法解常微分方程, u, |+ y& ]# ~' @( S
        %fun:f(x)的一阶导数m文件7 J- C3 J$ E* {1 p% ^+ U, z) W* J
        %x0,xt:自变量的初值和终值* d4 N/ c$ }& S7 [* r" X
        %y0:f(x)在x0处的值5 j8 M& Z- r4 r* \. e- u. j1 Z2 L
        %h:步长
    ; M# k6 [! i; p; Y6 m& Wfunction [Tixingx,Tixingy]=MyTixing(myfun,x0,xt,y0,h)8 l) L, `0 A' ]" v
    x=(x0:h:xt)';%定义自变量数组
    " M: j& I( |: s7 D; [! X* _- ky(1,: )=y0;%初始化因变量数组5 o/ T0 y7 R/ O( J
    Y(1,: )=y0;%中间量
    1 f) B) z6 u. z; _: A  ]* h/ Rfor k=1:length(x)-1% b& ?4 @+ Q& [8 A( Z$ ?
        f=feval(myfun,x(k),y(k,: ) );%计算每个迭代点的一阶导数值! j1 m* z2 D) h% z2 O, @
        f=f(: )';
    4 r4 E' p( U- g7 {8 [* F    Y(k+1,: )=y(k,: )+h*f; %y0(n+1)6 y  N% ~/ d1 ], d  j
        F=feval(myfun,x(k+1),Y(k+1,: ));%计算每个迭代点的一阶导数值
    - Y7 S4 {4 s2 U# D/ E/ d4 H    F=F(: )';
    / B6 w& [6 g" ^: e2 ?5 e    y(k+1,: )=y(k,: )+0.5*h*(f+F); %y(n+1)0 e/ J; N; C+ a& e- A, o
    end
    # }  ]6 |! i/ @, d0 U! l. wTixingx=x;
    $ a" ?+ _3 o9 {* d) x0 h: u, M. vTixingy=y;+ L3 l; \0 H- {0 R2 a
    ' g% }) c6 ?" i- C& t

    - w+ z( G1 P1 S, X四阶RK法:( e2 y! \- k8 w7 F4 Z$ f
    ' e; i" \& [9 v% W
    %四阶Runge-Kutta法解常微分方程
    4 h/ o0 F# q8 O- i    %fun:f(x)的一阶导数m文件
    . F! w8 q, ]- ^0 O# p  s2 k    %x0,xt:自变量的初值和终值
    & F1 ?* ~% k7 ?# x( A- h7 d4 P    %y0:f(x)在x0处的值
    % r; R9 i/ L4 V% Y7 B9 p    %h:步长9 x& _. u. N6 J7 y7 W9 h" _3 h' j: |
    function [RK4x,RK4y]=RK4(myfun,x0,xt,y0,h)
    # w, h0 j  V, f  _x=(x0:h:xt)';%定义自变量数组[code]clear all;clc;
    5 i6 D: p% c, Z, Q! H+ H+ z3 @x0=0;xt=2*pi;%x0,xt:自变量的初值和终值
    ; a9 G. ?; G0 z, c  }9 k4 M5 D! @8 Sy0=1;%y0:f(x)在x0处的值" e- {. k7 ~7 \( G+ s/ `
    h=0.2;%h:步长
    * b7 @+ k) o9 V8 M2 s4 [[Eulerx,Eulery]=MyEuler(@myfun,x0,xt,y0,h);%欧拉法
    : {: [4 m$ X- p# n" M! @6 Ba=fliplr(Eulery');%求算f(22*pi)! @3 C( @0 @/ t8 v* V( T7 ~
    y_Euler=a(1);
    5 y4 T2 Y/ w: K' l[Tixingx,Tixingy]=MyTixing(@myfun,x0,xt,y0,h);%梯形法, g* n! N8 s& V
    a=fliplr(Tixingy');%求算f(22*pi)4 X) v( E# L, a1 _& P* ]4 J: n
    y_Tixing=a(1);
    ( w3 x. o- w! n7 y  x% p[RK4x,RK4y]=RK4(@myfun,x0,xt,y0,h);%四阶Runge-Kutta法法
    5 E, m) K$ ?7 x, W9 G: m) ^) H( ca=fliplr(RK4y');%求算f(22*pi)3 T# i% m' {* M8 ~+ L0 d
    y_RK4=a(1);
    * A1 U+ a- K+ b( G# w" g5 s) }9 n[ode45x,ode45y]=ode45(@myfun,[x0:h:xt],[1]);%matlab内置函数
    / m. a7 Z% l: b) S( L2 v9 aa=fliplr(ode45y');%求算f(22*pi)
    ; n) p/ i$ ~5 b: s0 ^y_ode45=a(1);: r% A# w" s: f1 R' Y
    figure;1 @1 _! ~( D/ L  s
    figure_FontSize=18; %修改字体
    4 @7 \) Z( ]% L& Z3 ^: fplot(Eulerx,Eulery,'ro',Tixingx,Tixingy,'g*',RK4x,RK4y,'bd',ode45x,ode45y,'ks','LineWidth',2);%做图$ i6 i0 m! o8 |  A' ?% Y
    legend('Euler','Tixing','RK4','ode45');%图例
    ' Q% o0 a  `8 b4 MY=[y_Euler,y_Tixing,y_RK4,y_ode45];$ _2 z  f5 F$ e  l+ w- R' r
    axis([x0 xt y0 max(Y)]); %定义坐标轴范围/ {9 x- T* x+ |0 w  f: v' \$ g
    label1={'方法';'Euler';'Tixing';'RK4';'ode45'};
    : A+ K' V6 s% g5 p8 K9 U  r% slabel2={'y(2π)';y_Euler;y_Tixing;y_RK4;y_ode45};& c3 w/ m" H0 O9 T' Y
    % label=[label1,label2];9 }4 |" \* u* z" Y! e; O% O
    text(x0+0.1*(xt-x0),0.8*max(Y),label1); %显示y(2π)9 z" N% B8 \, S  h. q
    text(x0+0.3*(xt-x0),0.8*max(Y),label2);
    " o8 y* j0 F% \- i0 v; P9 a
    " S  ?) M1 c  }# Z6 K- O! r9 n% ^  Y" T- f
    y(1,: )=y0;%初始化因变量数组/ y& p2 t) x3 h* p. o* {; Y
    for k=1:length(x)-1
    : d$ ]& e4 d  A# x% G% U    K1=feval(myfun,x(k),y(k,: ));%计算系数
    * U) l& P5 L" g/ d' {    K2=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K1');
    7 z5 d' {5 |; Y, U    K3=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K2');
    8 s5 x4 ^, `4 R6 T& e7 m' j    K4=feval(myfun,x(k)+h,y(k,: )+h*K3');1 h- S$ O% n9 r9 o! Q1 [& l
        y(k+1,: )=y(k,: )+(1/6)*h*(K1'+2*K2'+2*K3'+K4');%迭代
    ' }4 |1 f0 d  h4 x: Qend1 X) |* o3 ]* i2 f7 F: o! w+ x
    RK4x=x;2 a" s! r8 i; s$ R9 y( \
    RK4y=y;

    该用户从未签到

    3#
    发表于 2020-4-20 13:39 | 只看该作者
    ( B3 S' u  i2 @& p+ {
    楼主的图用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 c+ f3 Z  u+ z3 M% h8 \, I8 K
    , h9 }  U9 V' O3 h
    8 M) ^" H) x: D

    9 d+ U+ v5 L+ e2 p) t
    ( I" y/ L9 D7 W2 H. T: K( _
    1 p/ h6 u% [8 I% f: t1 Q+ J, S: r( `; S/ w" m

    7 s6 b0 @. w* [( W8 }' R9 \) i4 g8 ?
    / p1 ^# t$ p4 [! ^) K1 R& W/ z& U9 M6 J6 ^2 d0 o+ F

    该用户从未签到

    4#
    发表于 2020-4-20 13:39 | 只看该作者
    用1stOpt更简单:2 k. E5 F) S) r
    • Variable t=[0:0.2:30],x=1,y=0.5;
    • Plot x,y;
    • ODEFunction x'= -x^3-y, y'= x-y^3;
      + M# {% ^/ w% |5 {
    , O* S- |5 z# x0 H# f7 z1 Z# B# l% }
    7 d8 r3 C7 \% T4 e

    . Q9 F" _: M* j; Y  m( n6 t
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-23 09:21 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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