用python面向对象的方法实现欧拉算法和龙格库塔算法

 1 #!/bin/python3
 2 # -*-coding:utf-8 -*-
 3 import math
 4 import numpy as np
 5 
 6 #定义一个欧拉算法的类,从而实现不同步长的引用
 7 class Euler:
 8     y_list=[]                #定义一个空列表来实现y值的存储
 9     def __init__(self, h=0.1, y0=1,):        #初始化Euler类的方法
10         self.h = h
11         self.y0 = y0
12         self.y = y0
13         self.n = 1/h
14         self.y_list = Euler.y_list
15 
16     def euler(self, y0, h,):       #定义Euler算法的过程
17         x = 0
18         y = y0
19         n = 1/h
20         for i in range(int(self.n+1)):
21             y_dere = 1 + math.log(x + 1)
22             y += self.h * y_dere
23             self.y_list = Euler.y_list.append("%.10f" % y)
24 
25 #  print("%.3f" % x, "%.10f" % y)
26             x += self.h
27 # print(Euler.y_list,)
28         return np.linspace(0, 1, n+1,dtype=float), Euler.y_list   #为了引用结果列表,从而返回两个列表
29 
30 
31 #定义一个实现龙格库塔方法
32 class RungeKutta:
33     y_list = []           #同理,设置一个空列表来储存y值
34     def __init__(self, h=0.1, y0=1,):
35         self.h = h
36         self.y0 = y0
37 
38     def make_ks(self, x_k,y_k):
39 
40         def y_ders(x_k):
41             y_der = 1 + math.log(x_k + 1)
42             return y_der
43 #计算K1,K2,K3,K4
44         k1 = y_ders(x_k)
45         k2 = y_ders(x_k + self.h/2)
46         k3 = y_ders(x_k + (self.h/2))
47         k4 = y_ders(x_k + self.h)
48         y_k = y_k+self.h/6*(k1+(2-math.sqrt(2))*k2 + (2 + math.sqrt(2))*k3 + k4)
49         return x_k, y_k
50 
51     def make(self, h, y0):
52         n = int(1/self.h)
53         y_k = y0
54         x_k = 0
55         for i in range(n):          #用循环遍历来实现y值的计算
56             x_k, y_k = self.make_ks(x_k,y_k)
57             x_k += h
58 # print("%.3f" % x_k, "%.10f" % y_k)
59             RungeKutta.y_list.append("%.10f" % y_k)
60 
61         return np.linspace(0, 1, 1/h+1, dtype=float), RungeKutta.y_list
62 
63 
64 #下面将收集计算的值,首先输出Euler法,再输出rungkutta,x,y数据的顺序是:x,y
65 print("Euler", "h=0.1")
66 a1 = Euler()
67 ax1, ay1 = a1.euler(h=0.1, y0=1)
68 print(ax1, "
", ay1)
69 print("----------------------------------------------------------------------------")
70 print("Euler", "h=0.1")
71 print("h=0.01")
72 a2 = Euler()
73 ax2, ay2 = a2.euler(h=0.01, y0=1)
74 print(ax2, "
", ay2)
75 print("----------------------------------------------------------------------------")
76 print("Euler", "h=0.1")
77 print("h=0.2")
78 a3 = Euler()
79 ax3, ay3 = a3.euler(h=0.2, y0=1)
80 print(ax3, "
", ay3)
81 print("----------------------------------------------------------------------------")
82 
83 print("Rungkutta", "h=0.2")
84 c1 = RungeKutta(h=0.2, y0=1)
85 cx1, cy1 = c1.make(h=0.2, y0=1)
86 print(cx1, "
", cy1)
87 print("-----------------------------------------------------------------------------")
88 
89 print("Rungkutta", "h=0.1")
90 c2 = RungeKutta(h=0.1, y0=1)
91 cx2, cy2 = c2.make(h=0.1, y0=1)
92 print(cx2, "
", cy2)
93 print("-----------------------------------------------------------------------------")
94 
95 print("Rungkutta", "h=0.01")
96 c3 = RungeKutta(h=0.01, y0=1)
97 cx3, cy3 = c3.make(h=0.01, y0=1)
98 print(cx3, "
", cy3)
99 print("-----------------------------------------------------------------------------")

以上的代码是实现算法的过程,以及输出的部分,还可以加入自定义的文件读取的办法,以及其他存储方式保存数据结果。

》》》》》》》》》》》》》》》》》》》》》》

程序2.0版本:

》》》》》》》》》》》》》》》》》》》》》》

# -*-coding:utf-8 -*-
import math
import numpy as np
import matplotlib.pyplot as plt


# 定义一个欧拉算法的类,从而实现不同步长的引用


class Euler:
    # y_list = []  # 定义一个空列表来实现y值的存储

    def __init__(self, h,  y0):  # 初始化Euler类的方法
        self.h = h
        self.y0 = y0
        self.y = y0
        self.n = 1 / self.h
        self.x = 0

    def euler(self):  # 定义Euler算法的过程
        # x = 0
        #  y = self.y0
        # n = 1 / self.h
        for i in range(int(self.n + 1)):
            y_dere = 1 + math.log(self.x + 1)
            self.y += self.h * y_dere
            self.y_list = Euler_y_list.append("%.10f" % self.y)
            self.x += self.h
        # print(Euler.y_list,)
        return np.linspace(0, 1, self.n + 1, dtype=float), Euler_y_list  # 为了引用结果列表,从而返回两个列表


# 定义一个实现龙格库塔方法
class RungeKutta:

    def __init__(self, h, y0=1):
        self.h = h
        self.y0 = y0

    def make_ks(self, x_k, y_k):
        def y_ders(x_k):
            y_der = 1 + math.log(x_k + 1)
            return y_der

        # 计算K1,K2,K3,K4
        k1 = y_ders(x_k)
        k2 = y_ders(x_k + self.h / 2)
        k3 = y_ders(x_k + (self.h / 2))
        k4 = y_ders(x_k + self.h)
        y_k = y_k + self.h / 6 * (k1 + (2 - math.sqrt(2)) * k2 + (2 + math.sqrt(2)) * k3 + k4)
        return x_k, y_k

    def make(self):
        n = int(1 / self.h)
        y_k = self.y0
        x_k = 0
        for i in range(n):  # 用循环遍历来实现y值的计算
            x_k, y_k = self.make_ks(x_k, y_k)
            x_k += self.h
            RungeKutta_y_list.append(y_k)

        return np.linspace(0, 1, n+1, endpoint=True,dtype=float), RungeKutta_y_list


class Plots:
    def __init__(self, x, y, title):
        self.x = list(x)
        self.y = list(y)
        self.title = title

    def plots(self):
        plt.figure(figsize=(8, 4))
        plt.scatter(self.x, self.y, label="y'=1+ln(x+1),
y0=1
(0<x<=1) ", color="red", linewidth=2)
        plt.xlabel("x")
        plt.ylabel("y")
        plt.title(self.title)
      #  plt.ylim(min(self.y), max(self.y))
        plt.ylim()
        plt.legend()
        plt.show()


if __name__ == "__main__":
     while True:
        name = input("本程序提供Euler算法和Rungekutta算法
选择算法时输入exit退出
请输入需要的算法名:")
        try:
             a = float(input("请输入所需要的h值:"))
             if  a =="exit" or a=="Exit":
                 break
        except ValueError as ve:
            print(ve)
        if name == "Euler":
            Euler_y_list =[]
            l1 = Euler(h=a, y0=1)
            l1x, l1y = l1.euler()
            with open("Euler.txt","a+") as f:
                f.write("h=%s
" % l1.h)
                f.write("x值--------------y值
")
                for i in range(len(l1x)):
                     print("x是:%.5f  y是:%.10f" % (float(l1x[i]),float(l1y[i])))
                     a,b = str(l1x[i]),str(l1y[i])
                     f.write(a+" "*6+b+"
")
            l1p = Plots(l1x, l1y, name)
            l1p.plots()
            print("请储存好你的x值,和y值")
            del l1, l1p, l1x, l1y
            Euler.y_list = []
        elif name == "Rungekutta":
            RungeKutta_y_list = [0]
            l2 = RungeKutta(h=a)
            l2x, l2y = l2.make()
            with open("Rungekutta.txt", "a+") as f:
                f.write("h=%s
" % l2.h)
                f.write("x值--------------y值
")
                for i in range(len(l2x)):
                     print("x是:%.5f  y是:%.10f" % (l2x[i], l2y[i]))
                     a, b = str(l2x[i]), str(l2y[i])
                     f.write(a + " " * 6 + b + "
")
            l2p = Plots(l2x, l2y, name)
            l2p.plots()
            print("请储存好你的x值,和y值")
            del l2, l2p
        elif name =="exit":
            break
        else:
            print("请输入正确的算法名!!!!")

加入了退出和写入到文件的功能

原文地址:https://www.cnblogs.com/BlogOfMr-Leo/p/8537097.html