2022-2023国科大李保滨老师矩阵分析期末大作业

要求完成课堂上讲的关于矩阵分解的LU、QR(Gram-Schmidt)、Orthogonal Reduction (Householder reduction 和Givens reduction)和 URV程序实现,要求如下:

    1、一个综合程序,根据选择参数的不同,实现不同的矩阵分解;在此基础上,实现Ax=b方程组的求解,以及计算A的行列式;

     2、可以用matlab、Python等编写程序,需附上简单的程序说明,比如参数代表什么意思,输入什么,输出什么等等,附上相应的例子;

     3、一定是可执行文件,例如 .m文件等,不能是word或者txt文档。附上源代码,不能为直接调用matlab等函数库;
import numpy as np
import copy

#LU分解函数
def LU_Factorization(A):
    #输入:N * N的方阵A
    #输出:对角元全为1的下三角矩阵L与对角元素不为0的上三角元素U
    A = np.array(A)
    B = copy.deepcopy(A)
    n = B.shape[0]
    L = np.identity(n, dtype=int)
    U = np.zeros_like(A)
    for i in range(n):
        for j in range(i+1, n):
            L[j][i] = B[j][i] / B[i][i]
            B[j] = B[j] - L[j][i]*B[i]
        U[i] = B[i]
    return L, U

#LU分解函数
def LU_Factorization2(A):
    #输入:N * N的方阵A
    #输出:对角元全为1的下三角矩阵L与对角元素不为0的上三角元素U
    n = len(A[0])
    L = [[0] * n for i in range(n)]
    U = [[0] * n for i in range(n)]
    B = copy.deepcopy(A)
    for i in range(n):
        L[i][i] = 1
        U[i][i] = B[i][i]
        for j in range(i+1, n):
            L[j][i] = B[j][i] / B[i][i]
            for k in range(n):
                B[j][k] = B[j][k] - L[j][i]*B[i][k]
            U[i][j] = B[i][j]
    return L, U

#QR分解的函数
def QR_Factorization(A):
    #输入:N * N的方阵A
    #方法:使用Gram-Schmidt正交化方法 A = QR
    #输出:单位正交矩阵Q与对角元素不为0的上三角元素R
    A = np.array(A, dtype=float)
    n = A.shape[0]
    Q = copy.deepcopy(A)
    R = np.zeros_like(A)
    for i in range(n):
        for j in range(i):
            temp = np.sum(Q[:, j]*A[:, i])
            R[j][i] = temp
            Q[:, i] -= temp*Q[:, j]
        num = 0
        for k in range(n):
            num += Q[k][i]**2
        num = np.sqrt(num)
        Q[:, i] = Q[:, i] / num
        R[i][i] = num
        # R[i][i] = np.linalg.norm(Q[:, i])
        # Q[:, i] = Q[:, i] / np.linalg.norm(Q[:, i])
    return Q, R

#利用Householder reduction进行Orthogonal Reduction
def HouseHolder(A):
    #输入:N * N的方阵A
    #方法:使用Householder变换正交化方法,PA=T
    #输出:P为正交矩阵 T为上三角矩阵
    A = np.mat(A, dtype=float)
    n = A.shape[0]
    T = copy.deepcopy(A)
    P = np.eye(n)
    for i in range(n-1):
        sub_A = T[i:, i:]
        R = np.eye(n)
        e = np.zeros_like(sub_A[:, 0])
        e[0] = 1.0
        u = sub_A[:, 0] - np.linalg.norm(sub_A[:, 0]) * e
        R_ = np.eye((n-i)) - 2*u.dot(u.T) / (u.T.dot(u))
        R[i:, i:] = R_
        T = R.dot(T)
        P = R.dot(P)
    return P, T

#利用Givens reduction进行Orthogonal Reduction
def Givens(A):
    #输入:N * N的方阵A
    #方法:使用Givens变换正交化方法,PA=T
    #输出:P为正交矩阵 T为上三角矩阵
    A = np.array(A, dtype=float)
    n = A.shape[0]
    T = copy.deepcopy(A)
    P = np.eye(n)
    for i in range(n):
        for j in range(i+1, n):
            P_ = np.eye(n)
            c, s = T[i, i], T[j, i]
            c, s = c/np.sqrt(c**2+s**2), s/np.sqrt(c**2+s**2)
            P_[i, i] = c
            P_[i, j] = s
            P_[j, i] = -s
            P_[j, j] = c
            P = P_.dot(P)
            T = P_.dot(T)
    return P, T

#利用URV分解
def URV_Factorization(A):
    #输入:N * N的方阵A
    #方法:
    # U的前r列为R(A)的标准正交基
    # U的后m-r列为N(A.T)的标准正交基
    # V的前r列为R(A.T)的标准正交基
    # V的后n-r列为N(A)的标准正交基
    # 可以利用Householder或者Givens reduction方法来获得标准正交基P满足PA=(B|0).T
    # 对B.T再使用一次Householder或者Givens reduction方法得到标准正交基Q和非奇异上三角矩阵T
    #输出:P为正交矩阵 T为上三角矩阵
    A = np.array(A, dtype=float)
    U, B = HouseHolder(A)

    rank_A = np.linalg.matrix_rank(A)
    P = B[:rank_A, :]

    Q, T = HouseHolder(B.T)
    rank_B = np.linalg.matrix_rank(B.T)

    V = Q.T
    T = T[:rank_B, :]
    R = np.zeros_like(A, dtype=float)
    R[: rank_B, :rank_B] = T.T

    U = P

    return U, R, V

if __name__ == "__main__":
    '''该程序将会对给定的矩阵A进行LU、QR(Gram-Schmidt)
    Orthogonal Reduction (Householder reduction 和Givens reduction)和URV分解
    运行程序时需要numpy的环境 如果未安装则需要在python环境中进行pip install numpy的操作
    运行时需要输入1-5的数字进行分解的选择,输入其他字符程序无法运行
    输入完毕后可以输入1或0自己选择是使用程序给定的样例A与b进行运行或者自己输入A和b进行运算
    最后会对矩阵A进行相应的分解操作获得分解后的矩阵并对Ax=b进行求解同时计算出A的行列式
    '''
    num = int(input('请输入1-5来选择进行何种分解\n'
                    '1:LU\n'
                    '2:QR\n'
                    '3:HouseHolder\n'
                    '4:Givens\n'
                    '5:URV\n'))
    if num not in [i for i in range(1, 6)]:
        print('请输入1-5的数字')
        exit()
    print('将在给定的A矩阵进行相应的分解操作,并求得AX=b的解与A的行列式')
    mode = ['LU', 'QR', 'HouseHolder', 'Givens', 'URV'][num-1]
    flag = int(input('输入1将使用程序给定的A和b\n'
                     '输入0用户可以自己输入一个矩阵A和b\n'))
    if flag == 1:
        b = np.array([12, 24, 12], dtype=float)
        if mode == 'LU':
            A = [[2, 2, 2],
                 [4, 7, 7],
                 [6, 18, 22]]
            print("A矩阵:\n", A)
            L, U = LU_Factorization(A)
            print("矩阵A经过LU分解后得到的结果:")
            print("L矩阵:\n", L)
            print("U矩阵:\n", U)
            n = len(A[0])
            x = np.zeros_like(A[0])
            y = np.zeros_like(A[0])
            for i in range(n):
                y[i] = b[i]
                for j in range(i):
                    y[i] = y[i] - y[j] * L[i][j]
            for i in range(n):
                x[n - i - 1] = y[n - i - 1]
                for j in range(i):
                    x[n - i - 1] = x[n - i - 1] - x[n - j - 1] * U[n - i - 1][n - j - 1]
                x[n - i - 1] /= U[n - i - 1][n - i - 1]
            print("AX=B的解如下:")
            print("X:", x)
            det_L, det_U = 1, 1
            for i in range(n):
                det_L = det_L * L[i][i]
                det_U = det_U * U[i][i]
            det_A = det_L * det_U
            print("A的行列式为:", det_A)

        elif mode == 'QR':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            print("A矩阵:\n", A)
            Q, R = QR_Factorization(A)
            print("矩阵A经过QR分解后得到的结果:")
            print("Q矩阵:\n", Q)
            print("R矩阵:\n", R)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = Q.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * R[i][j]
            print("AX=B的解如下:")
            print("X:", x)
            det_R = 1
            for i in range(n):
                det_R = det_R * R[i][i]
            det_A = det_R
            print("A的行列式为:", det_A)

        elif mode == 'HouseHolder':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            print("A矩阵:\n", A)
            P, T = HouseHolder(A)
            print("矩阵A经过HousHolder变换后得到的结果:")
            print("P矩阵:\n", P)
            print("T矩阵:\n", T)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = P.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * T[i, j]
            print("AX=B的解如下:")
            print("X:", x)
            det_T = 1
            for i in range(n):
                det_T = det_T * T[i, i]
            det_A = det_T
            print("A的行列式为:", det_A)

        elif mode == 'Givens':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            P, T = Givens(A)
            print("A矩阵:\n", A)
            print("矩阵A经过Givens变换后得到的结果:")
            print("P矩阵:\n", P)
            print("T矩阵:\n", T)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = P.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * T[i, j]
            print("AX=B的解如下:")
            print("X:", x)
            det_T = 1
            for i in range(n):
                det_T = det_T * T[i, i]
            det_A = det_T
            print("A的行列式为:", det_A)

        elif mode == 'URV':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            U, R, V = URV_Factorization(A)
            n = len(A[0])
            x = np.zeros_like(A[0])
            y = np.zeros_like(A[0])
            b = U.dot(b.T)
            for i in range(n):
                y[i] = b[0, i]
                for j in range(i):
                    y[i] = y[i] - y[j] * R[i, j]
            print(y)
            x = V.dot(y.T)
            print("AX=B的解如下:")
            print("X:", x)
            det_A = 1
            for i in range(n):
                if R[i, i] == 0:
                    break
                det_A = det_A * R[i, i]
            print("A的行列式为:", det_A)

        else:
            print('无法选择其他方法!')

    elif flag == 0:
        n = int(input('请输入矩阵A的大小\n'))
        b_input = input('请输入'+str(n)+'个数\n')
        A_input = input('请输入'+str(n*n)+'个数\n')
        b = [int(temp) for temp in b_input.split(' ')]
        b = np.array(b, dtype=float)
        A = [int(temp) for temp in A_input.split(' ')]
        A = np.array(A, dtype=float)
        A = A.reshape(n, n)
        if mode == 'LU':
            print("A矩阵:\n", A)
            L, U = LU_Factorization(A)
            print("矩阵A经过LU分解后得到的结果:")
            print("L矩阵:\n", L)
            print("U矩阵:\n", U)
            n = len(A[0])
            x = np.zeros_like(A[0])
            y = np.zeros_like(A[0])
            for i in range(n):
                y[i] = b[i]
                for j in range(i):
                    y[i] = y[i] - y[j] * L[i][j]
            for i in range(n):
                x[n - i - 1] = y[n - i - 1]
                for j in range(i):
                    x[n - i - 1] = x[n - i - 1] - x[n - j - 1] * U[n - i - 1][n - j - 1]
                x[n - i - 1] /= U[n - i - 1][n - i - 1]
            print("AX=B的解如下:")
            print("X:", x)
            det_L, det_U = 1, 1
            for i in range(n):
                det_L = det_L * L[i][i]
                det_U = det_U * U[i][i]
            det_A = det_L * det_U
            print("A的行列式为:", det_A)

        elif mode == 'QR':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            print("A矩阵:\n", A)
            Q, R = QR_Factorization(A)
            print("矩阵A经过QR分解后得到的结果:")
            print("Q矩阵:\n", Q)
            print("R矩阵:\n", R)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = Q.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * R[i][j]
            print("AX=B的解如下:")
            print("X:", x)
            det_R = 1
            for i in range(n):
                det_R = det_R * R[i][i]
            det_A = det_R
            print("A的行列式为:", det_A)

        elif mode == 'HouseHolder':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            print("A矩阵:\n", A)
            P, T = HouseHolder(A)
            print("矩阵A经过HousHolder变换后得到的结果:")
            print("P矩阵:\n", P)
            print("T矩阵:\n", T)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = P.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * T[i, j]
            print("AX=B的解如下:")
            print("X:", x)
            det_T = 1
            for i in range(n):
                det_T = det_T * T[i, i]
            det_A = det_T
            print("A的行列式为:", det_A)

        elif mode == 'Givens':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            P, T = Givens(A)
            print("A矩阵:\n", A)
            print("矩阵A经过Givens变换后得到的结果:")
            print("P矩阵:\n", P)
            print("T矩阵:\n", T)
            n = len(A[0])
            x = np.zeros_like(A[0])
            b = P.dot(b.T)
            for i in range(n):
                x[i] = b[i]
                for j in range(i):
                    x[i] = x[i] - x[j] * T[i, j]
            print("AX=B的解如下:")
            print("X:", x)
            det_T = 1
            for i in range(n):
                det_T = det_T * T[i, i]
            det_A = det_T
            print("A的行列式为:", det_A)

        elif mode == 'URV':
            A = [[0, -20, -14],
                 [3, 27, -4],
                 [4, 11, -2]]
            U, R, V = URV_Factorization(A)
            n = len(A[0])
            x = np.zeros_like(A[0])
            y = np.zeros_like(A[0])
            b = U.dot(b.T)
            for i in range(n):
                y[i] = b[0, i]
                for j in range(i):
                    y[i] = y[i] - y[j] * R[i, j]
            print(y)
            x = V.dot(y.T)
            print("AX=B的解如下:")
            print("X:", x)
            det_A = 1
            for i in range(n):
                if R[i, i] == 0:
                    break
                det_A = det_A * R[i, i]
            print("A的行列式为:", det_A)

        else:
            print('无法选择其他方法!')
    else:
        print("只能输入1和0")
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值