python输出高斯消元法求解行列式的过程

前言

有人可能好奇,为啥有那么多工具还要自己写一个。emmm…
比如我求 Ax=b, 增广矩阵, 比如说我想要 [ A , I ] [A, I] [A,I] -> [ I , A − 1 ] [I, A^{-1}] [I,A1], 工具就用不了了



代码

"""
支持分数,主要用来计算阶梯型和最简阶梯型
Ax = b
Alter time: 2022.9.13 23:24
"""
from fractions import Fraction


cnt = 0  # 步骤计数器


# frac.numerator 整数/ frac.denominator分数
# 创造一个支持分数运算的矩阵
def make_matrix(list_matrix):
    global cnt
    cnt = 0
    fra_matrix = []
    for i in range(len(list_matrix)):
        row = []
        for j in list_matrix[i]:
            if not isinstance(j, Fraction):
                row.append(Fraction(j))
            else:
                row.append(j)
        fra_matrix.append(row)
    return fra_matrix


# 展示矩阵
def show(matrix, information_str='no tips'):
    global cnt
    print(information_str)
    print('-' * len(matrix[0]) * 10)
    for row in matrix:
        for item in row:
            print('{:>10}'.format(str(item)), end='')
        print()
    print()
    cnt += 1


# 交换两行 (行数下标从1开始, 即 m * n的矩阵, 行数下标从1 ~ m)
def change_row(matrix, row1_num, row2_num):
    global cnt
    matrix[row1_num - 1],  matrix[row2_num - 1] = matrix[row2_num - 1], matrix[row1_num - 1]
    show(matrix, 'process {}. change row {} and row {}'.format(cnt, row1_num, row2_num))


# 化简某一行 (行数下标从1开始, 即 m * n的矩阵, 行数下标从1 ~ m)
def simplify(matrix, row_num, pivot_col, reduce_echelon_form=False):
    global cnt
    # row_num -= 1
    pivot = matrix[row_num][pivot_col]
    for j in range(len(matrix[0])):
        matrix[row_num][j] /= pivot

    # 化简为 最简行列式
    if reduce_echelon_form:
        for i in range(len(matrix)):
            if i != row_num:
                times = matrix[i][pivot_col]
                for j in range(len(matrix[0])):
                    matrix[i][j] -= matrix[row_num][j] * times
    else: # 只是化为行列式
        for i in range(row_num + 1, len(matrix)):
            times = matrix[i][pivot_col]
            for j in range(len(matrix[0])):
                matrix[i][j] -= matrix[row_num][j] * times
    show(matrix, 'process {}. simplify row {}'.format(cnt, 1))


# 化为阶梯型
def echelon_form(a, cc_num=None, reduce_echelon_form=False):
    m, n = len(a), len(a[0])
    # print('s001: ', m, n, cofficient_cols_num)

    if cc_num is None:
        cc_num = n

    prc_row, prc_col = 0, 0
    while prc_row < m and prc_col < cc_num:
        if a[prc_row][prc_col] == 0:
            zero_flag = True
            for f_row in range(prc_row + 1, m):
                if a[f_row][prc_col] != 0:
                    change_row(prc_row, f_row)
                    zero_flag = False
                    break
            if zero_flag:
                prc_col += 1
                continue
        print('prc_row, prc_col:', prc_row, prc_col)
        simplify(a, prc_row, prc_col, reduce_echelon_form=reduce_echelon_form)
        prc_row += 1
        prc_col += 1
    
    tips_op = '(reduced)' if reduce_echelon_form else ''

    if prc_row == m:
        print('The matrix has been changed to {} echelon form'.format(tips_op))
    else:
        print('The matrix is singular')


if __name__ == '__main__':
    a = [[1, 2, 1, 3], [2, 5, -1, -4], [3, -2, -1, 5]]
    a = make_matrix(a)
    cnt = 0  # 步骤计数器

    cofficient_cols_num = 3

    echelon_form(a, cofficient_cols_num, reduce_echelon_form=True)

例子输出:

prc_row, prc_col: 0 0
process 0. simplify row 1
----------------------------------------
         1         2         1         3
         0         1        -3       -10
         0        -8        -4        -4

prc_row, prc_col: 1 1
process 1. simplify row 1
----------------------------------------
         1         0         7        23
         0         1        -3       -10
         0         0       -28       -84

prc_row, prc_col: 2 2
process 2. simplify row 1
----------------------------------------
         1         0         0         2
         0         1         0        -1
         0         0         1         3

The matrix has been changed to (reduced) echelon form



如果最后一行代码改一下, 即reduce_echelon_form为False, 我们只想得到阶梯型

echelon_form(a, cofficient_cols_num, reduce_echelon_form=False)

输出:

prc_row, prc_col: 0 0
process 0. simplify row 1
----------------------------------------
         1         2         1         3
         0         1        -3       -10
         0        -8        -4        -4

prc_row, prc_col: 1 1
process 1. simplify row 1
----------------------------------------
         1         2         1         3
         0         1        -3       -10
         0         0       -28       -84

prc_row, prc_col: 2 2
process 2. simplify row 1
----------------------------------------
         1         2         1         3
         0         1        -3       -10
         0         0         1         3

猜你喜欢

转载自blog.csdn.net/weixin_43850253/article/details/126843741