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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
求解微分方程组,画出解函数图。: v* W( _8 S4 ~. j* F

) U5 s, E0 [: U0 s- X) {6 Wx'= -x^3-y, x(0)=1     ; j# l% ~: J( e9 V5 [
y'= x-y^3, y(0)=0.5   0<t<30. C8 Q: X7 ^. b, J. K* t  ~8 w
请教高手指点给出程序与结果,谢谢
  ^( M9 y& h2 b$ t4 ]3 D
  • TA的每日心情

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

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 13:34 | 只看该作者
    本帖最后由 yin123 于 2020-4-20 13:36 编辑
    + T% b7 x+ I" g$ B2 P
    + h) Q! p, i  ?+ Z" s4 d碰巧正好学习了微分方程解法0 _* j! C" o( M- j0 x
    matlab内置的函数(数值解法)有ode系列,help一下就可以了
      y& N' ?2 c* K2 Q) E如果你上的是有关数字分析的课程,我猜老师的意思应该让你自己写代码4 c0 \6 \- v: S4 @( S" O3 T2 T
    我分别尝试了Euler法 梯形法 四阶RK法  代码如下:
    , m. r5 _! i* G) [3 s  X; t, [以y‘=|sin2x、,y(0)=1为例:
    $ I% l9 f2 {6 Z
    ; x1 a$ `* O6 p, E; ?编写一阶导数m文件:
    " ~1 M) R0 [. Q* f; ~1 G
    2 p% N$ Z$ h" R%一阶常微分方程的m文件
    0 N; y0 N+ W7 F3 @9 z8 Afunction y1=myfun(x,y)2 s0 u" n& K# l5 ?
    y1=abs(sin(2*x));/ Y8 V3 k; ]$ Z/ W) c1 u, \

      W' c$ ]9 w/ R
    , ?5 U/ R; V, x2 H) L" d' `9 J4 k3 U# N: \) A: A) {* V
    Euler法:
      K' |# f& d; a' F0 U+ {# C) t- K. f. A3 C& B
    %向前差分Euler法解常微分方程
    " p& h+ q" `6 a. @7 f    %fun:f(x)的一阶导数m文件/ A6 T+ ]; Y4 D% H
        %x0,xt:自变量的初值和终值# W7 N7 m$ t* k; l8 H8 x
        %y0:f(x)在x0处的值
    , Q! f% \6 h( b; t+ h! R9 R    %h:步长2 c7 q& i0 t- Z# e! J
    function [Eulerx,Eulery]=MyEuler(myfun,x0,xt,y0,h)
    7 H4 B) u; f- g$ j8 w1 H0 E$ Ex=(x0:h:xt)';%定义自变量数组
    - e0 C+ _1 m7 n$ x( l) xy(1,: )=y0;%初始化因变量数组, ^: f7 v* |. M
    for k = 1:length(x)-1
    $ d9 Y2 o3 ?! h8 Q: i7 d8 m& q# Y" j    f=feval(myfun,x(k),y(k,: ));%计算每个迭代点的一阶导数值/ P) ]& I4 p$ R; ^0 k4 ^
        f=f(: )';% U8 x& O! Z3 Z" k2 \0 @
        y(k+1,: )=y(k,: )+h*f; %向前迭代
    % u; i/ U. y% B) i6 u9 k% oend4 L. E) r8 y! v9 M
    Eulerx=x;
    ' w, ?8 A! C4 @& H9 r6 v/ L# I' R& sEulery=y;" y. G% Y& X1 k2 ^
    " H8 K, G7 c( P4 {
    % g$ g& m, a8 L/ v8 t4 d
    梯形法:* t* o' w, q- z
    . T8 S* a3 j6 N9 T" z
    %梯形法解常微分方程) \: N2 S0 Q" x4 l+ t6 X+ d" @. f
        %fun:f(x)的一阶导数m文件
    / j2 o( u+ C5 A$ s    %x0,xt:自变量的初值和终值
    7 U  G: G* }$ ]    %y0:f(x)在x0处的值3 v/ i) w: s1 d( E# m( [
        %h:步长" i: `' f6 _$ ]7 C8 |  w( M
    function [Tixingx,Tixingy]=MyTixing(myfun,x0,xt,y0,h), y4 V1 }& Y# ]% z
    x=(x0:h:xt)';%定义自变量数组" W% E8 A$ b' U+ R% c
    y(1,: )=y0;%初始化因变量数组% V  q+ x/ I* z& }( a
    Y(1,: )=y0;%中间量
    ) w+ C- \0 x  _for k=1:length(x)-1) N) h. [  e' x# f+ {5 R; t8 w6 P
        f=feval(myfun,x(k),y(k,: ) );%计算每个迭代点的一阶导数值; \0 z4 z6 i" p- |2 g
        f=f(: )';
      U. |  B& c) |( e9 i- j    Y(k+1,: )=y(k,: )+h*f; %y0(n+1)6 o2 Y+ L" l  H/ O% ]
        F=feval(myfun,x(k+1),Y(k+1,: ));%计算每个迭代点的一阶导数值: d2 y! R( ^  I1 [1 A+ F
        F=F(: )';2 B: O3 ~! b" l% p
        y(k+1,: )=y(k,: )+0.5*h*(f+F); %y(n+1)4 `8 l4 |0 \/ {. X9 f8 j
    end9 d6 R- a% w( }1 B# c$ i6 \
    Tixingx=x;& E& F. V) O2 E, c& v
    Tixingy=y;
    + g0 v. ]& i( a# b7 P
    ' e. [. y3 p* |4 }+ T1 \; k5 ?1 M% B1 A
    四阶RK法:
    0 `$ L6 b% Z& J- w8 p' ^$ \
    7 |' I  v& V3 _9 L5 @%四阶Runge-Kutta法解常微分方程7 R/ l5 ~$ r$ M9 H8 g
        %fun:f(x)的一阶导数m文件. ?$ U8 X) N# V% Z8 e
        %x0,xt:自变量的初值和终值, u& |) n" R/ u# F7 I
        %y0:f(x)在x0处的值+ o+ N, z! U# B6 Z
        %h:步长+ e4 ]9 F0 B3 s: ?
    function [RK4x,RK4y]=RK4(myfun,x0,xt,y0,h)
    8 S4 s. R$ A0 H8 R9 `! H! N- r9 Yx=(x0:h:xt)';%定义自变量数组[code]clear all;clc;4 s- e# }: j9 u2 O2 D) Y; Q
    x0=0;xt=2*pi;%x0,xt:自变量的初值和终值
    * `  \+ {( V! J  X' {y0=1;%y0:f(x)在x0处的值) V/ |4 w9 ]1 s( M7 B2 t
    h=0.2;%h:步长3 f( ]! n# @* k3 t/ Z3 L/ u# h
    [Eulerx,Eulery]=MyEuler(@myfun,x0,xt,y0,h);%欧拉法1 [% A$ R9 ^( h0 p8 k( W  y, r
    a=fliplr(Eulery');%求算f(22*pi)/ Z) `. f; a: @% L- x4 u3 q
    y_Euler=a(1);/ h' h% i) b* {
    [Tixingx,Tixingy]=MyTixing(@myfun,x0,xt,y0,h);%梯形法6 l4 P1 [6 g6 e
    a=fliplr(Tixingy');%求算f(22*pi)
    ( u7 @( L  R" i4 l' [- |0 p5 J) Ny_Tixing=a(1);3 A1 [; ^6 w5 ]" q
    [RK4x,RK4y]=RK4(@myfun,x0,xt,y0,h);%四阶Runge-Kutta法法
    ! U' J# p/ b7 H- p4 Z, Ua=fliplr(RK4y');%求算f(22*pi); \  s; P. P) T( f! G
    y_RK4=a(1);
    ! C! d# `- Z, Z9 A! }0 L% x6 J[ode45x,ode45y]=ode45(@myfun,[x0:h:xt],[1]);%matlab内置函数
    1 V- \# ?6 J8 ta=fliplr(ode45y');%求算f(22*pi)8 k' |+ h2 V5 B5 d" n9 i  N7 v* P
    y_ode45=a(1);3 w4 l* d2 p9 a7 |
    figure;
    % q1 f& r+ t0 q* Lfigure_FontSize=18; %修改字体) J& C3 \- o3 c* f# P7 H  n
    plot(Eulerx,Eulery,'ro',Tixingx,Tixingy,'g*',RK4x,RK4y,'bd',ode45x,ode45y,'ks','LineWidth',2);%做图- {6 p. \4 Z# Q4 U, _) f
    legend('Euler','Tixing','RK4','ode45');%图例
    . F" O4 n# `6 ]) V" y' G# m% P" _: g# bY=[y_Euler,y_Tixing,y_RK4,y_ode45];
    1 ^: i3 U3 B; d  g, @- B- Yaxis([x0 xt y0 max(Y)]); %定义坐标轴范围/ q# U0 }. f2 x1 r
    label1={'方法';'Euler';'Tixing';'RK4';'ode45'};
    2 s' [# P% D) R- ^4 Nlabel2={'y(2π)';y_Euler;y_Tixing;y_RK4;y_ode45};
    $ I! }# l* R( Q  S4 e9 F% label=[label1,label2];
    $ x4 m# O9 Z: |9 btext(x0+0.1*(xt-x0),0.8*max(Y),label1); %显示y(2π)2 ]. s/ {" S! [( v& s
    text(x0+0.3*(xt-x0),0.8*max(Y),label2);9 S, U/ ?+ n4 I, i9 E8 B9 F

    9 v! T! o& ~  M% {- v; Y( g) T# h3 b* I* ^2 j4 x
    y(1,: )=y0;%初始化因变量数组$ ^6 ]; s6 E" [
    for k=1:length(x)-1
    9 Z5 M# |  e/ C0 b1 N; v0 g    K1=feval(myfun,x(k),y(k,: ));%计算系数
    1 }! a; {# I9 p3 c9 `+ e    K2=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K1');
    $ V# J8 w1 a5 |1 V8 O+ z4 \% e. B    K3=feval(myfun,x(k)+0.5*h,y(k,: )+0.5*K2');' H8 M6 K7 a' \8 X' N
        K4=feval(myfun,x(k)+h,y(k,: )+h*K3');5 T! |' s; f4 A7 x. c! @. r" y
        y(k+1,: )=y(k,: )+(1/6)*h*(K1'+2*K2'+2*K3'+K4');%迭代
    4 U; r& D6 }8 G# V' e! uend
    & j9 j1 e  k- S. |  YRK4x=x;) D+ L; l3 `- W" s
    RK4y=y;

    该用户从未签到

    3#
    发表于 2020-4-20 13:39 | 只看该作者
    * [! K( O% G* L7 H; z
    楼主的图用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]    //绘制一元函数图象
    • };8 \& {# v1 ~9 }, O
    ) s$ r7 o* t1 X# {4 I

    - v" Q3 j  j4 E' |9 L1 I
    ) j, H7 X3 t8 ?: e# s
    5 E# L4 U. ?& F8 e
    % ?9 Y. f! T  J# b' I. x  s6 p' H$ P6 Y7 V* v5 n) |) p; }* g% A
    9 C6 g+ W0 W0 g& l
    - ^; Y" m$ Z0 Y$ `; M

    3 ~: e% g4 k# ]. E

    该用户从未签到

    4#
    发表于 2020-4-20 13:39 | 只看该作者
    用1stOpt更简单:
    ( }2 s0 b5 ?2 {# S" v
    • Variable t=[0:0.2:30],x=1,y=0.5;
    • Plot x,y;
    • ODEFunction x'= -x^3-y, y'= x-y^3;. o! _- j, F# U, B
    ) T' ]/ ]" h3 P/ N
    ) Y( b  w8 a7 y" H1 n

    ) k/ r, ^3 c! S! s
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 02:59 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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