137 lines
3.7 KiB
Python
137 lines
3.7 KiB
Python
|
||
# 列主元高斯消元法
|
||
def SovleRowMain(A,b):
|
||
ks = 0.00000001
|
||
n = len(A)
|
||
if len(A[0]) != n:
|
||
raise ValueError("A要为方阵")
|
||
if len(b) != n:
|
||
raise ValueError("b与A的行数不匹配")
|
||
p = list(range(n))
|
||
for i in range(n):
|
||
row_max = abs(A[i][i])
|
||
row_max_index = i
|
||
for j in range(i + 1, n):
|
||
if abs(A[j][i]) > row_max:
|
||
row_max = abs(A[j][i])
|
||
row_max_index = j
|
||
A[i], A[row_max_index] = A[row_max_index], A[i]
|
||
b[i], b[row_max_index] = b[row_max_index], b[i]
|
||
p[i], p[row_max_index] = p[row_max_index], p[i]
|
||
|
||
if abs(A[i][i]) < ks:
|
||
raise ValueError("A矩阵奇异,无法进行高斯消元")
|
||
for j in range(i + 1, n):
|
||
m = A[j][i] / A[i][i]
|
||
A[j][i] = m
|
||
for k in range(i + 1, n):
|
||
A[j][k] -= m * A[i][k]
|
||
b[j] -= m * b[i]
|
||
|
||
if abs(A[n - 1][n - 1]) < ks:
|
||
raise ValueError("A矩阵奇异,无法进行高斯消元")
|
||
|
||
# 回代求解
|
||
b[n - 1] /= A[n - 1][n - 1]
|
||
for i in range(n - 2, -1, -1):
|
||
for j in range(i + 1, n):
|
||
b[i] -= A[i][j] * b[j]
|
||
b[i] /= A[i][i]
|
||
return b
|
||
|
||
|
||
# 最小二乘法拟合
|
||
def LeastSquares(list_x,list_y,n):
|
||
m = len(list_x)
|
||
for i in range(2*n):
|
||
tl = [list_x[j]**(i+1) for j in range(m)]
|
||
print(f"x^{i+1} :",tl)
|
||
print("sum:", sum(tl))
|
||
for i in range(n+1):
|
||
tl = [list_y[j]*list_x[j]**i for j in range(m)]
|
||
print(f"y*x^{i}: ",tl)
|
||
print("sum:", sum(tl))
|
||
x_n = []
|
||
b = []
|
||
for i in range(2*n+1):
|
||
x_n.append(0)
|
||
b.append(0)
|
||
for j in range(m):
|
||
x_n[i]+=(list_x[j]**i)
|
||
b[i]+=(list_y[j]*list_x[j]**i)
|
||
b = b[:n+1]
|
||
A = []
|
||
for i in range(n+1):
|
||
tmp = []
|
||
for j in range(n+1):
|
||
tmp.append(x_n[i+j])
|
||
A.append(tmp)
|
||
print("A:", A)
|
||
print("b:", b)
|
||
result = SovleRowMain(A, b)
|
||
print("result:", result)
|
||
return result
|
||
|
||
# 计算多项式在给定x值上的值
|
||
def CalculateY(list_x, coeff):
|
||
re = []
|
||
for i in range(len(list_x)):
|
||
re.append(0)
|
||
for j in range(len(coeff)):
|
||
re[i] += coeff[j]*list_x[i]**j
|
||
print("y预测:", re)
|
||
return re
|
||
|
||
# 计算均方根误差
|
||
def MeanSquareErr(list_y,list_y_approx):
|
||
m = len(list_y)
|
||
err = 0
|
||
print("y差值: ")
|
||
for i in range(m):
|
||
print(f"y-y测={list_y[i] - list_y_approx[i]}, (y-y测)^2={(list_y[i] - list_y_approx[i])**2}")
|
||
err += (list_y[i] - list_y_approx[i])**2
|
||
return err**0.5
|
||
|
||
# 计算最大误差
|
||
def MaxErr(list_y,list_y_approx):
|
||
m = len(list_y)
|
||
err = 0
|
||
for i in range(m):
|
||
if abs(list_y[i] - list_y_approx[i]) > err:
|
||
err = abs(list_y[i] - list_y_approx[i])
|
||
return err
|
||
|
||
# 打印拟合方程
|
||
def PrintEquation(coeff):
|
||
n = len(coeff)
|
||
str_ = str(coeff[0]) + "+"
|
||
for i in range(0,n-1):
|
||
str_ += str(coeff[i+1])
|
||
str_ += "*x^"+str(i+1)+"+"
|
||
str_ = str_[0:len(str_)-1]
|
||
print(str_)
|
||
|
||
#把x和y换成题干的数值###################
|
||
x = [2,4,6,8]
|
||
y = [2,11,28,40]
|
||
if __name__ == "__main__":
|
||
print("一次拟合")
|
||
coeff = LeastSquares(x,y,1)
|
||
PrintEquation(coeff)
|
||
y_approx = CalculateY(x, coeff)
|
||
# print()
|
||
print("均方根误差:",MeanSquareErr(y,y_approx))
|
||
# print()
|
||
print("最大误差:",MaxErr(y,y_approx))
|
||
|
||
print()
|
||
|
||
print("二次拟合")
|
||
coeff = LeastSquares(x,y,2)
|
||
PrintEquation(coeff)
|
||
y_approx = CalculateY(x, coeff)
|
||
# print()
|
||
print("均方根误差:",MeanSquareErr(y,y_approx))
|
||
# print()
|
||
print("最大误差:",MaxErr(y,y_approx))
|
||
|