常微分方程初值问题的数值解法—数值分析实验

一、目的与要求
(一)目的通过设计、编制、调试1~2个求常微分方程初值问题的数值解解的程序,加深对其数值计算方法及有关的基础理论知识的理解。
(二)要求 用编程语言实现用改进的欧拉(Euler)公式求解常微分方程初值问题、用四阶龙格-库塔(Runge-Kutta)方法求解常微分方程初值问题的程序。
二、示例
1、问题用改进的欧拉(Euler)公式求解常微分方程初值问题。
2、算法描述(略)
3、程序中变量说明 (略)
4、源程序清单及运行结果(略)
5、按以上4点要求编写上机实验报告。
三、实验题用编程语言编程实现以下算法:
1、用改进的欧拉(Euler)公式求解常微分方程初值问题。2、用四阶龙格-库塔(Runge-Kutta)方法求解常微分方程初值问题。
数值分析实验真的都是直接套公式即可…
做法:首先理解书上关于欧拉公式以及四阶龙贝格库塔方法,明白其中的道题,模拟程序流程。
只是图画的有点丑…
代码

import numpy as np
import matplotlib.pyplot as plt
import math
def func(x,y):
    return y - 2*x/y
#模拟常微分方程为:
#      f'(x)=y-2*x/y
#      f(x0)=y0
#另外:解析法可知f(x) = 根号下(2*x+1)
x0 = 0
y0 = 1
h = 0.1
N = 10
# 改进的欧拉(Euler)公式
def ImproEuler():
    x1 = np.zeros(N+1)
    y1 = np.zeros(N+1)
    for i in range(N+1):
        x1[i] = x0 + h*(i)
    # 计算y数组各值
    for i in range(N+1):
        if i==0:
            y1[i] = y0
        else:
            k1 = y1[i-1] + h*func(x1[i-1],y1[i-1])
            k2 = y1[i-1] + h*func(x1[i],k1)
            y1[i] = (k1+k2)*1/2
    return x1,y1
# 四阶龙格-库塔(Runge-Kutta)方法
def RungeKutta():
    x1 = np.zeros(N+1)
    y1 = np.zeros(N+1)
    for i in range(N+1):
        x1[i] = x0 + h*(i)
    for i in range(N+1):
        if i==0:
            y1[i] = y0
        else:
            k1 = func(x1[i-1],y1[i-1])
            k2 = func(x1[i-1]+h/2,y1[i-1]+k1*h/2)
            k3 = func(x1[i-1]+h/2,y1[i-1]+k2*h/2)
            k4 = func(x1[i-1]+h,y1[i-1]+h*k3)
            y1[i] = y1[i-1] + (k1+2*k2+2*k3+k4)*h/6
    print(x1,y1)
    return x1,y1
def Draw():
#三条线画在同一张图中 发现误差很小
    xEuler,yEuler = ImproEuler()
    xKutta,yKutta = RungeKutta()
    plt.plot(xEuler,yEuler,'*',xKutta,yKutta,'gx',xEuler,np.sqrt(2*xEuler+1),'r')
    plt.annotate(r'Euler Formula or Runge Kutta',xy=(xEuler[5],yEuler[5]),xytext=(xEuler[5],yEuler[5]-0.2),arrowprops=dict(facecolor='black',shrink=0.1,width=2))
    plt.annotate(r'Correct results',xy=(xEuler[10]-0.05,np.sqrt(2*xEuler[10]+1)),xytext=(xEuler[10]-0.05,np.sqrt(2*xEuler[10]+1)-0.2),arrowprops=dict(facecolor='black',shrink=0.1,width=2))
    plt.grid(True)
    plt.savefig('ODE test',dpi = 600)
    plt.show()
if __name__ == '__main__':
    Draw()

你可能感兴趣的:(常微分方程初值问题的数值解法—数值分析实验)