Files
CalWay_Python/89-1.py
2025-06-19 00:08:48 +08:00

137 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 列主元高斯消元法
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))