武汉理工大学-数值分析-(3)线性代数方程组的数值解法

Bunny ·
更新时间:2024-11-10
· 894 次阅读

文章目录实验目标编程语言与扩展库高斯消元法(Gauss)列主元高斯消元法(Gauss)列主元LU直接分解法Jacobi迭代法Gauss-Seidel迭代法写在最后 实验目标

用编程语言编程实现以下算法:
1.用 高斯(Gauss)消元法 求n阶线性方程组的解。
2.用 列主元高斯(Gauss)消元法 求n阶线性方程组的解。
3.用 列主元LU直接分解法 求n阶线性方程组的解。
4.用 Jacobi迭代法 求n阶线性方程组的解。
5.用 Gauss-Seidel迭代法 求n阶线性方程组的解。

编程语言与扩展库

语言:Python
扩展模块:numpy

高斯消元法(Gauss) # 导入模块 from numpy import * # 高斯消元法 求解Ax=b def Gauss(A,b): # 获取A的行列 row = A.shape[0] column = A.shape[1] # 非方阵情况 if row != column: print('A不是方阵!') return n = row # 未知数数量 m = zeros((n,n)) # m矩阵存储乘数 # 消元过程 for k in range(0,n-1): for i in range(k+1,n): # 第i行除第k行得乘数 m[i,k] = A[i,k]/A[k,k] # 方程消元 A[i,:] = A[i,:] - m[i,k]*A[k,:] b[i] = b[i] - m[i,k]*b[k] # 回代过程 x = transpose(zeros((1,n))) x[n-1] = b[n-1]/A[n-1,n-1] # Xn的值 # 计算Xn-1,Xn-2,...,X1的解 for k in range(0,n-1)[::-1]: # 第n-1行到第0行逆序 sum = 0 for j in range(k+1,n): sum += A[k,j]*x[j] x[k] = (b[k]-sum)/A[k,k] return x if __name__ == '__main__': A = array([[1,1,1],[0,4,-1],[2,-2,1]], dtype = double) b = transpose(array([[6,5,1]], dtype = double)) x = Gauss(A,b) print(x)
列主元高斯消元法(Gauss) # 导入模块 from numpy import * # 列主元高斯消元法 求解Ax=b def Gauss_column_pivoting(A,b): # 获取A的行列 row = A.shape[0] column = A.shape[1] # 非方阵情况 if row != column: print('A不是方阵!') return n = row # 未知数数量 m = zeros((n, n)) # m矩阵存储乘数 for k in range(0,n-1): # 寻找最大主元的行数 h = argmax(abs(A[:,k])) # 交换行 if k != h: temp1 = copy(A[k,:]) # copy产生该行的复制 A[k,:] = A[h,:] A[h,:] = temp1 temp2 = copy(b[k]) b[k] = b[h] b[h] = temp2 # 消元过程 for i in range(k + 1, n): # 第i行除第k行得乘数 m[i, k] = A[i, k] / A[k, k] # 方程消元 A[i, :] = A[i, :] - m[i, k] * A[k, :] b[i] = b[i] - m[i, k] * b[k] # 回代过程 x = transpose(zeros((1, n))) # 构造x列向量 x[n - 1] = b[n - 1] / A[n - 1, n - 1] # Xn的值 # 计算Xn-1,Xn-2,...,X1的解 for k in range(0, n - 1)[::-1]: # 第n-1行到第0行逆序 sum = 0 for j in range(k + 1, n): sum += A[k, j] * x[j] x[k] = (b[k] - sum) / A[k, k] return x if __name__ == '__main__': A = array([[1, 1, 1], [0, 4, -1], [2, -2, 1]], dtype = double) b = transpose(array([[6, 5, 1]], dtype = double)) x = Gauss_column_pivoting(A,b) print(x)
列主元LU直接分解法 # 导入模块 from numpy import * # 列主元LU分解法 求解Ax=b def LU_column_pivoting(A,b): # 获取A的行列 row = A.shape[0] column = A.shape[1] # 非方阵情况 if row != column: print('A不是方阵!') return n = row Ip = list(range(n)) # 标记主元交换次序 for k in range(0,n): # 寻找最大主元的行数 h = argmax(abs(A[:,k])) # 只能选择未交换的行进行交换 if Ip[h] == h: temp = copy(A[k, :]) A[k, :] = A[h, :] A[h, :] = temp Ip[k] = h # 对角线减去对应行列乘积和 A[k,k] = A[k,k] - dot(A[k,0:k], A[0:k,k]) if A[k,k] == 0: print('第{}个主元为0!'.format(k+1)) return # 直接在A上保存L和U for j in range(k+1,n): # j>k A[k,j] = A[k,j] - dot(A[k,0:k], A[0:k,j]) A[j,k] = (A[j,k] - dot(A[j,0:k], A[0:k,k])) / A[k,k] # 单位下三角L和上三角U L = tril(A,-1) + identity((n)) U = triu(A,0) L.dtype = double U.dtype = double # 交换b对应行 for i in range(0,n): t = Ip[i] if t != i: temp = copy(b[i]) b[i] = b[t] b[t] = temp # 求解Ly=b y = transpose(array([arange(n)], dtype = double)) y[0] = b[0] for i in range(1,n): sum = 0 for t in range(0,i): sum += L[i,t]*y[t] y[i] = b[i] - sum # 求解Ux=y x = transpose(array([arange(n)],dtype = double)) x[n-1] = y[n-1]/U[n-1,n-1] for i in range(0,n-1)[::-1]: sum = 0 for t in range(i+1,n): sum += U[i,t]*x[t] x[i] = (y[i]-sum)/U[i,i] return x if __name__ == '__main__': A = array([[1,2,3],[2,5,2],[3,1,5]], dtype = double) b = transpose(array([[14,18,20]], dtype = double)) x = LU_column_pivoting(A,b) print(x)
Jacobi迭代法 # 导入模块 from numpy import * # 初始解向量,迭代上限,误差范围 x_start = array([[0],[0],[0]]) N = 100 tol = 1e-7 # Jacobi迭代 def Jacobi(A,b): # 获取A的行列 row = A.shape[0] column = A.shape[1] # 非方阵情况 if row != column: print('A不是方阵!') return n = row x_k = x_start # 删去A的对角线 A_ = copy(A) for i in range(n): A_[i,i] = 0 # 迭代求解 for i in range(N): t = transpose([diag(A)]) x_k_plus = (b - dot(A_, x_k))/t # 达到足够小的误差 if (max(abs((x_k - x_k_plus)[:,0])) < tol): print('迭代次数: {}'.format(i+1)) print('方程组解: ') print(x_k_plus) break x_k = x_k_plus if i == N: print('错误!不收敛!') if __name__ == '__main__': A = array([[8,-3,2],[4,11,-1],[6,3,12]], dtype = double) b = transpose(array([[20,33,36]], dtype = double)) Jacobi(A,b)
Gauss-Seidel迭代法 # 导入模块 from numpy import * # 初始解向量,迭代上限,误差范围 x_start = array([[1],[2],[3]]) N = 1000 tol = 1e-10 # GS迭代法 求解Ax=b def Gauss_Seidel(A,b): # 获取A的行列 row = A.shape[0] column = A.shape[1] # 非方阵情况 if row != column: print('A不是方阵!') return # 初值 n = row x_k = x_start # 构造DLU U = copy(A) # U DL = copy(A) # D-L for i in range(n): for j in range(n): if j<=i: U[i,j] = 0 else: DL[i,j] = 0 U = 0-U # DL逆与U, b相乘 DL_U = dot(linalg.inv(DL),U) DL_b = dot(linalg.inv(DL),b) # 迭代求解 for i in range(N): x_k_plus = dot(DL_U,x_k) + DL_b # 达到误差要求 if max(abs((x_k_plus - x_k)[:,0])) < tol: print('方程组解: ') print(x_k_plus) break x_k = x_k_plus if i == N: print('错误!不收敛!') if __name__ == '__main__': A = array([[8, -3, 2], [4, 11, -1], [6, 3, 12]], dtype=double) b = transpose(array([[20, 33, 36]], dtype=double)) Gauss_Seidel(A,b)
写在最后

声明:本文内容来源于武汉理工大学2019-2020学年数值分析方法课程实验,仅供学习参考
如有不足地方,还请指出。祝愿读者能够在编程之路上不断进步!


作者:-Kingzy-



数值分析 线性代数 代数 线性 大学

需要 登录 后方可回复, 如果你还没有账号请 注册新账号