设Ax=b,其中A∈Rn×n.
(1) 如果akk(k)≠0(k=1,2,···,n),则可以通过高斯消去法将Ax=b约化为等价的三角形线性方程组,如下:
[ a 11 ( 1 ) a 12 ( 1 ) … a 1 n ( 1 ) a 22 ( 2 ) … a 2 n ( 2 ) ⋱ ⋮ a n n ( n ) ] [ x 1 x 2 ⋮ x n ] = [ b 1 ( 1 ) b 2 ( 2 ) ⋮ b n ( n ) ] ( 1 ) \begin{bmatrix} a_{11}^{(1)}&a_{12}^{(1)}&\ldots&a_{1n}^{(1)}\\ &a_{22}^{(2)}&\ldots&a_{2n}^{(2)}\\ &&\ddots&\vdots\\ &&&a_{nn}^{(n)} \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ \vdots\\ x_n \end{bmatrix}= \begin{bmatrix} b_1^{(1)}\\ b_2^{(2)}\\ \vdots\\ b_n^{(n)}\\ \end{bmatrix}(1) ⎣⎢⎢⎢⎢⎡a11(1)a12(1)a22(2)……⋱a1n(1)a2n(2)⋮ann(n)⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎡b1(1)b2(2)⋮bn(n)⎦⎥⎥⎥⎥⎤(1)
且计算公式为:
(2)如果 A A A为非奇异矩阵,则可通过高斯消去法(及交换两行的初等变换)将方程组 A x = b Ax=b Ax=b约化为方程组(1).
# 自己原创
def lu_decomposition(coefficient_matrix: np.ndarray, right_hand_side_vector: np.ndarray):
"""
实现方程Ax=b系数矩阵A的LU decomposition
:param coefficient_matrix: 初始系数矩阵A
:param right_hand_side_vector: 初始常数列向量b
:return: 单位下三角矩阵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:
# LU decomposition
lower_triangular_matrix = np.eye(rows)
for k in range(rows - 1):
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 lower_triangular_matrix, coefficient_matrix, right_hand_side_vector
# 自己原创
def gaussian_elimination(coefficient_matrix: np.ndarray,
right_hand_side_vector: np.ndarray,
decomposition_function=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("系数矩阵的行数与常数列向量行数不相等")
对比系统LU分解函数和不选主元高斯消去法解线性方程组
[ 10 − 7 0 1 − 3 2.099999 6 2 5 − 1 5 − 1 2 1 0 2 ] [ x 1 x 2 x 3 x 4 ] = [ 8 5.900001 5 1 ] \begin{bmatrix} 10&-7&0&1\\ -3&2.099999&6&2\\ 5&-1&5&-1\\ 2&1&0&2 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4 \end{bmatrix}= \begin{bmatrix} 8\\ 5.900001\\ 5\\ 1 \end{bmatrix} ⎣⎢⎢⎡10−352−72.099999−11065012−12⎦⎥⎥⎤⎣⎢⎢⎡x1x2x3x4⎦⎥⎥⎤=⎣⎢⎢⎡85.90000151⎦⎥⎥⎤
if __name__ == '__main__':
square_matrix = np.array([[10, -7, 0, 1], [-3, 2.099999, 6, 2], [5, -1, 5, -1], [2, 1, 0, 2]])
vector = np.array([8, 5.900001, 5, 1]).reshape((4, 1))
copy_square_matrix1 = square_matrix.copy()
copy_vector1 = vector.copy()
copy_square_matrix2 = square_matrix.copy()
copy_vector2 = vector.copy()
solution = lu_solve(lu_factor(square_matrix), vector)
print("系统函数LU分解实现的解向量x=\n{}".format(solution))
solution_vector = gaussian_elimination(copy_square_matrix2, copy_vector2)
print("自己写的不选主元高斯消去法解向量x=\n{}".format(solution_vector))