一,列主元Guass消去法
因为在使用不选主元的Guass消去法消元时,可能出现akk(k)=0的情况,此时消去法无法进行下去;即使主元素akk(k)≠0但绝对值很小时,用作除数会导致其他元素数量级严重增长和舍入误差的扩散,最后也使得计算结果不可靠.对于一般的矩阵来说,每一步选取系数矩阵(或消元后的低阶矩阵)中绝对值最大的元素作为主元素,以使高斯消去法具有较好的数值稳定性,这就是列主元高斯消去法.
二,列主元Guass消去法Python代码
# 自己原创
def pivot_lu_decomposition(coefficient_matrix: np.ndarray, right_hand_side_vector: np.ndarray):
"""
实现方程Ax=b系数矩阵A的pivoted LU decomposition
:param coefficient_matrix: 初始系数矩阵A
:param right_hand_side_vector: 初始常数列向量b
:return: 排列矩阵P,单位下三角矩阵L,上三角矩阵U,常数列向量b
"""
# first step: evaluate the lu decomposition condition
rows, columns = coefficient_matrix.shape
if rows == columns: # judge if it is a square matrix
for k in range(rows): # 判断各阶顺序主子式是否为0
if det(coefficient_matrix[:k + 1, :k + 1]) == 0:
raise Exception("cannot generate LU decomposition")
else:
# pivot LU decomposition
lower_triangular_matrix = np.eye(rows)
permutation_matrix = np.eye(rows)
for k in range(rows - 1):
max_index = np.argmax(abs(coefficient_matrix[k:, k]))
coefficient_matrix[[k, max_index + k], :] = coefficient_matrix[[max_index + k, k], :]
right_hand_side_vector[[k, max_index + k], :] = right_hand_side_vector[[max_index + k, k], :]
permutation_matrix[[k, max_index + k], :] = permutation_matrix[[max_index + k, k], :]
for row in range(k + 1, rows):
multiplier = coefficient_matrix[row, k] / coefficient_matrix[k, k]
coefficient_matrix[row, k:] += -multiplier * (coefficient_matrix[k, k:])
right_hand_side_vector[row] += -multiplier * right_hand_side_vector[k]
lower_triangular_matrix[row, k] = multiplier
else:
raise Exception("ERROR:please pass a square matrix.")
return permutation_matrix, lower_triangular_matrix, coefficient_matrix, right_hand_side_vector
# 自己原创
def gaussian_elimination(coefficient_matrix: np.ndarray,
right_hand_side_vector: np.ndarray,
decomposition_function=pivot_lu_decomposition):
"""
实现高斯消元法解方程Ax=b
:param decomposition_function:分解函数
:param coefficient_matrix: 初始系数矩阵A
:param right_hand_side_vector: 初始列向量b
:return: 解向量x
"""
*_, upper_triangular_matrix, constant_column_vector = decomposition_function(coefficient_matrix,
right_hand_side_vector)
rows = right_hand_side_vector.shape[0]
if upper_triangular_matrix.shape[0] == rows: # 判断上三角矩阵的行数是否等于列向量行数
# 此处不指定双精度浮点数据类型,则可能会损失精度,导致结果偏差太大
variable_column_vector = np.ones_like(right_hand_side_vector, dtype=np.float64) # 构建一个与列向量同形状的1矩阵
for row in range(rows - 1, -1, -1):
prod = 0 # 声明累积变量,初始化为0
for column in range(row + 1, rows):
prod += variable_column_vector[column] * upper_triangular_matrix[row, column]
# 回代运算得到解向量
variable_column_vector[row] = (constant_column_vector[row] - prod) / upper_triangular_matrix[row, row]
return variable_column_vector
else:
raise Exception("系数矩阵的行数与常数列向量行数不相等")