defback_substitution(A,b):'''
回代法求解方程组Ax=b的解, 其中A为下三角行列式
'''
n =len(b)
x =[0for i inrange(n)]for i inrange(n-1,-1,-1):sum=0for j inrange(n-1,i,-1):sum+=A[i][j]*x[j]
x[i]=(b[i]-sum)/A[i][i]return x
# A = [[1,1,1],[0,1,3],[0,0,2]]# b = [1,-2,4]# print(back_substitution(A, b))deffront_substitution(A,b):'''
前代法求解方程组Ax=b的解, 其中A为上三角行列式
'''
x =[]
n =len(b)for i inrange(n):sum=0for j inrange(i):sum+=A[i][j]*x[j]
x.append((b[i]-sum)/A[i][i])return x
# A = [[2,0,0],[3,1,0],[1,1,1]]# b = [4,-2,1]# print(front_substitution(A, b))
Gauss消元法
defgauss(A,b,is_print=False):'''
高斯消元法求解方程组Ax=b的解
'''
n =len(b)
ga =[]
gb =[i for i in b]# 深度复制for i inrange(n):
tmp =[]for j inrange(n):
tmp.append(A[i][j])
ga.append(tmp)for k inrange(n-1):for i inrange(k+1,n):
l = ga[i][k]/ ga[k][k]
ga[i][k]=0for j inrange(k+1,n):
ga[i][j]-= l*ga[k][j]
gb[i]-= l * gb[k]if is_print:print('k= '+str(k)+':')print(ga)print(gb)return back_substitution(ga, gb)# A = [[1,1,1],[1,2,4],[1,3,9]]# b = [1,-1,1]# print(gauss(A, b,True))
列选主元Gauss消元法
defcolumn_pivot_element_gauss(A,b,is_print=False):'''
利用列选主元高斯消元法求解方程组Ax=b的解
'''
n =len(b)# 深度复制
ga =[[ j for j in i]for i in A]
gb =[i for i in b]for k inrange(n-1):# 先进行列选主元max= ga[k][k]
index = k
for i inrange(k+1,n):if ga[i][k]>max:max,index = ga[i][k],i
for i inrange(k,n):
ga[k][i],ga[index][i]= ga[index][i],ga[k][i]
gb[k],gb[index]= gb[index],gb[k]if is_print:if index == k:print('----------')print(ga)print(gb)print('k= '+str(k)+':')# sys.stdout.flush() # import sys 用来强制刷新缓存,输出# todo: 两次输出一样for i inrange(k+1,n):
l = ga[i][k]/ ga[k][k]
ga[i][k]=0for j inrange(k+1,n):
ga[i][j]-= l*ga[k][j]
gb[i]-= l * gb[k]if is_print:print(ga)print(gb)return back_substitution(ga, gb)# A = [[1,-2,3],[-1,1,2],[2,4,1]]# b = [-20,-8,9]# print(column_pivot_element_gauss(A, b,True))
LU分解
defDoolittle(A,b,is_print=False):'''
杜立特尔(Doolittle)分解法
'''
n =len(b)# 初始化
L =[[0for j inrange(n)]for i inrange(n)]
U =[[0for j inrange(n)]for i inrange(n)]# 求解U的第一行,L的第一列for i inrange(n):
U[0][i]= A[0][i]
L[i][0]= A[i][0]/U[0][i]
L[i][i]=1for k inrange(1,n):for j inrange(k,n):sum=0for q inrange(k):sum+= L[k][q]*U[q][j]
U[k][j]= A[k][j]-sumfor i inrange(k+1,n):sum=0for q inrange(k):sum+= L[i][q]*U[q][k]
L[i][k]=(A[i][k]-sum)/U[k][k]
y = front_substitution(L, b)
x = back_substitution(U, y)if is_print:print("L =",L)print("U =",U)print("y =",y)return x
# A = [[1,1,1,1],[1,2,1,3],[4,3,2,1],[6,11,3,7]]# b = [6,12,14,45]# print(Doolittle(A,b,True))
迭代法
defjacobi(A,b,x0,is_print=False,e=1e-8,N=100,norm=None):'''
利用Jacobi迭代法求解方程Ax=b的解
x0为初始值
e:代表迭代精度
N: 最大的迭代次数
norm: 代表向量范数,默认为2范数
'''# 2范数deftwo_norm(x1,x2):
n =len(x1)sum=0for i inrange(n):
d = x1[i]-x2[i]sum+= d*d
return math.sqrt(sum)ifnot norm:
norm = two_norm
# 初始化
n =len(b)
k =0
x =[0for i inrange(n)]while k<N:
k +=1for i inrange(n):# 注释部分误差大# sum = A[i][i]*x0[i] # 省略掉下面的if判断# for j in range(n):# sum += A[i][j]*x0[j]sum=0for j inrange(n):if i != j:# sum += A[i][j]*x0[j] # 表示使用雅可比迭代sum+= A[i][j]*x[j]# 表示使用高斯赛德尔迭代
x[i]=(b[i]-sum)/A[i][i]if norm(x,x0)<e:return x
for i inrange(n):
x0[i]= x[i]if is_print:print('x',k,' = ',x0,sep='')print('已超过最大迭代次数')
A =[[10,-1,-2],[-1,10,-2],[-1,-1,5]]
b =[72,83,42]print(jacobi(A, b,[0,0,0],True))
数据拟合
线性回归
deflinearRegression(x,y):'''
线性回归
x: 横坐标数据,List
y: 纵坐标数据,List
return: (a,b) 即y=a+bx
'''
n =len(x)
avg_x =sum(x)/n
avg_y =sum(y)/n
sum1 =0
sum2 =0for i inrange(n):
sum1 +=(x[i]-avg_x)*(y[i]-avg_y)
sum2 +=(x[i]-avg_x)*(x[i]-avg_x)
b = sum1/sum2
a = avg_y-b*avg_x
return(a,b)# print(linearRegression([0,1,2],[1,3,2]))
一般最小二乘拟合
defnormal_equation(x,y,funcs,w=None,is_print=False):'''
利用最小二乘拟合来拟合x,y数据
funcs 为需要拟合的函数组
w:为每点的权,默认为1
'''
n =len(funcs)
m =len(x)# 初始化ifnot w:
w =[1for i inrange(m)]
A =[[0for j inrange(n)]for i inrange(n)]
b =[0for i inrange(n)]for i inrange(n):for j inrange(i+1):sum=0for t inrange(m):sum+= w[t]*funcs[i](x[t])*funcs[j](x[t])
A[i][j]=A[j][i]=sumsum=0for t inrange(m):sum+= w[t]*funcs[i](x[t])*y[t]
b[i]=sumif is_print:print('A =',A)print('b =',b)return column_pivot_element_gauss(A, b)# x = [-3,-2,-1,0,1,2,3]# y = [4,2,3,0,-1,-2,-5]# print(normal_equation(x, y, [lambda x:1,lambda x:x,lambda x:x*x],None,True))# x = [-3,-1.5,0,1.5,3]# y = [-0.1385,-2.1587,0.8330,2.2774,-0.5110]# print(normal_equation(x, y, [lambda x:math.sin(x),lambda x:math.cos(x)],None,True))
defcomplexification_trapezoid(func,a,b,n):'''
复化梯形求积公式
func: 被积函数
求积区间[a,b] 分为n等分
'''sum=0.5*(func(a)+func(b))
h =(b-a)/n
for i inrange(1,n):sum+= func(a+h*i)return h*sumdefcomplexification_simpson(func,a,b,n):'''
利用复化Simpson求积公式
func: 被积函数
把区间[a,b] 分为2n等分
'''
h =(b-a)/(2*n)sum= func(a)+func(b)for i inrange(1,n):sum+=2*func( a+h*2*i)for i inrange(n):sum+=4*func(a+h*(2*i+1))return h*sum/3deftest_func(x):return4/(1+x*x)print(complexification_trapezoid(test_func,0,1,8))print(complexification_simpson(test_func,0,1,4))
变长求积公式
defelongate_simpson(func,a,b,e=1e-6,is_print=False,N=100):'''
变步长梯形求积公式
func被积函数,求积区间[a,b],e代表精度,N最大迭代次数
'''defrecursion(func,a,h,n,T1):'''
求解T的递推公式 T(h) = 1/2 * T(2h) + h*sum(f(2k-1),k=1,n/2)
func 被积函数,a积分下限,
'''sum=0for i inrange(1,n,2):sum+= func(a+h*i)return0.5*T1 + h*sum
T1 = complexification_trapezoid(func, a, b,1)# 求初始值
h =(b-a)/2
k =1
c =1/3
T2 = recursion(func, a, h,2, T1)
S1 = T2 + c*(T2-T1)if is_print:print('S',k,' = ',S1,sep='')
T1 = T2
while k<N:
h /=2
k +=1
T2 = recursion(func, a, h,2**k, T1)
d = c*(T2-T1)
S2 = T2 + d
d =abs(S2-S1)/15if is_print:print('S',k,' = ',S2,sep='')print('误差估计:',d)if d < e:return S2
T1 = T2
S1 = S2
print('已超过最大迭代次数')defelongate_test_func(x):if x ==0:return1return math.sin(x)/x
defelongate_trapezoid(func,a,b,e=1e-6,is_print=False,N=100):'''
变步长梯形求积公式
func被积函数,求积区间[a,b],e代表精度,N最大迭代次数
'''
T1 = complexification_trapezoid(func, a, b,1)# 求初始值
h = b-a
if is_print:# print('T(',h,') = 0.5*[ f('a')print('T(',h,') = ',T1,sep='')
k =0
c =1/3while k<N:sum=0
k +=1
h /=2for i inrange(1,2**k,2):sum+= func(a+h*i)
T2 =0.5*T1 + h*sum
d =abs(c*(T2-T1))if is_print:print('T(',h,') = ',T2,sep='')print('误差估计:',d)if d < e:return T2
T1 = T2
print('已超过最大迭代次数')# print(elongate_trapezoid(elongate_test_func, 0, 1,1e-3,True))# print(elongate_simpson(elongate_test_func, 0, 1,1e-6,True))
龙贝格(Romberg)求积法
deftest_func(x):if x ==0:return1return math.sin(x)/x
defromberg(func,a,b,e=1e-3,is_print=False,N=100):'''
龙贝格(Romberg)数值积分方法
'''
r =[]
k =0
r.append([complexification_trapezoid(func, a, b,1)])while k<N:
k+=1
tmp =[]
tmp.append(complexification_trapezoid(func,a,b,2**k))for i inrange(1,k+1):
tmp.append(tmp[i-1]+(tmp[i-1]-r[k-1][i-1])/(4**i-1))
r.append(tmp)ifabs(tmp[k]-r[k-1][k-2])<e:if is_print:for item in r:print(item)return tmp[k]print('已超过最大迭代次数')print(romberg(test_func,0,1,0.5*1e-5,True))