这里简单介绍几种数值积分的python实现,具体数学原理后面补上。
1 import math 2 import numpy as np 3 4 three_x = [-0.5773503, 0.5773503] 5 three_A = [1.0000000] 6 7 five_x = [-0.9061798, -0.5384693, 0, 0.5384693, 0.9061798] 8 five_A = [0.2369269, 0.4786287, 0.5688889] 9 10 def f_x(x): 11 return 1.0 / x 12 13 def gauss_legendre5(a, b): 14 addt = (a + b) / 2 15 coef = (b - a) / 2 16 return f_x(addt + coef * five_x[0]) * five_A[0] + f_x(addt + coef * five_x[1]) * five_A[1] + f_x(addt + coef * five_x[2]) * five_A[2] + f_x(addt + coef * five_x[3]) * five_A[1] + f_x(addt + coef * five_x[4]) * five_A[0] 17 18 def gauss_legendre2(a, b): 19 addt = (a + b) / 2 20 coef = (b - a) / 2 21 return coef * (f_x(addt + coef * three_x[0]) * three_A[0] + f_x(addt + coef * three_x[1]) * three_A[0]) 22 23 def composite_gauss_legendre2(a, b, n): 24 h = b - a 25 sn = 0.0 26 left = a 27 right = a + (h / n) 28 for i in range(n): 29 sn += gauss_legendre2(left, right) 30 left = right 31 right = left + (h / n) 32 sn = sn * h / 2 33 return sn 34 35 36 37 def simpson(left, h, n): 38 ''' 39 simpson插值积分 40 ''' 41 sn = 0.0 42 for i in range(n): 43 right = left + h 44 middle = 0.5 * (left + right) 45 sn += f_x(left) + 4.0 * f_x(middle) + f_x(right) 46 left = right 47 print(sn) 48 return h * sn / 6.0; 49 50 def composite_trapezoidal(left, h, n): 51 ''' 52 复化梯形插值积分 53 ''' 54 sn = 0.0 55 for i in range(n): 56 right = left + h 57 sn += f_x(left) + f_x(right) 58 left = right 59 return h * sn / 2.0; 60 61 def romberg(left, h, err): 62 ''' 63 romberg插值积分,一种递推式的积分 64 ''' 65 T = np.zeros((5,5)) 66 67 for i in range(5): 68 n = pow(2, i) 69 T[i][0] = composite_trapezoidal(left, h/n, n) 70 71 flag = 0 72 for i in range(5): 73 for j in range(i): 74 binary_times = pow(4, j+1) 75 T[i][j+1] = (binary_times * T[i][j] - T[i-1][j]) / (binary_times - 1) 76 if i > 0 and abs(T[i][i] - T[i-1][i-1]) <= err: 77 flag = i 78 break 79 return T[flag][flag]