zoukankan      html  css  js  c++  java
  • QR分解

    实数域

    Hermite矩阵

    (满足mathrm{P^{H}=P})
    (P = (I-2vv^{T})为初等正交Hermite(对称)矩阵)
    (即:P^{T}=P,P^TP=I)

    QR分解

    Q为正交矩阵 R为上三角阵

    一步

    (先考虑Px=ke,P=(I-2vv^{T}),xinmathrm{R}^{d}的情况下,求解P。)
    (Px=ke)
    (k^2=|Px|_2^2=x^2=x_1^2+x_2^2+ldots+x_d^2)
    (S:=sqrt{x_1^2+x_2^2+ldots+x_d^2})
    (then, k=pm S)
    (K:=v^Tx)
    $ x-2Kv=ke( )then, x_1-2Kv_1=k ( )x_i-2Kv_i=0, quad i e1( ) herefore v_1=(x_1-k)/2K( )v_i = x_i/2K( )ecause Px=x-2Kv=ke, 2Kv=x-ke( ) herefore 2K^2=S^2-x_1k=S^2pm x_1S( )if quad u:=(x_1 pm S, x_2, x_3,ldots, x_d)( )then, P = (I-uu^T/2K^2)$

    正负号的选择

    (k=pm S)
    (2K^2=S^2pm x_1S)
    (如何选择正负号呢,为了避免K=0,我们选择符号为x_1的符号即可。)

    多步

    (假设矩阵A的前r列已经是上三角形,则A_r如下)
    第r+1步矩阵A

    (为了把对角化剩下的,我们只需取:)
    第r+1步矩阵P

    二者相乘,我们容易发现,右下角变成了第一步的情况,依此知道对角化完全。
    可得:
    (A=QR)
    (Q=P_1P_2ldots)

    Tips 子空间

    (V=QR)
    (Q=(q_1, q_2, ldots, q_r, ldots, q_d))
    (V=(v_1, v_2, ldots, v_r))
    (如果v_1, v_2, ldots,v_r的极大线性无关组为本身,那么)
    (q_1,q_2,ldots,q_r与v_1, v_2, ldots, v_r张成同一个子空间(互相线性表出)。)

    代码

    import numpy as np
    
    def step_one_QR(x):
        """
        一步
        x 为ndarray
        :param x:向量
        :return: P
        """
        u = np.array(x, dtype=float)
        sign = lambda x: 1 if x >= 0 else -1
        S_2 = u @ u
        S = np.sqrt(S_2) * sign(u[0])
        K_2 = S_2 + S * u[0] #K_2 = 2K^2 here
        vector_ones = np.ones(len(u), dtype=float)
        u[0] += S
        return np.diag(vector_ones) - np.outer(u, u) / K_2
    
    
    def step_all_QR(A):
    
        """
        d:A的行数
        r:A的列数
        P:每步得到的Hermite矩阵
        :param A:d x r的矩阵
        :return:Q, R(A)
        """
        A = np.array(A, dtype=float) #注意经此操作后,后续操作不会改变原来的A
        d, r = A.shape
        Q = np.diag(np.ones(d, dtype=float))
        for i in range(r):
            P = np.diag(np.ones(d, dtype=float))
            P[i:, i:] = step_one_QR(A[i:,i])
            Q = Q @ P
            A = P @ A
    
        return Q, A
    
    """
    对上面的一个改进,速度明显提高,不过
    俩个方法对列非满秩的抗性都不高。
    """
    def step_one_QR_2(x):
        """
        一步 第二种
        x 为ndarray
        :param x:向量
        :return:u, K_2
        """
        u = np.array(x, dtype=float)
        sign = lambda x: 1 if x >= 0 else -1
        S_2 = u @ u
        S = np.sqrt(S_2) * sign(u[0])
        K_2 = S_2 + S * u[0] #K_2 = 2K^2 here
        vector_ones = np.ones(len(u), dtype=float)
        u[0] += S
        return u, K_2
    
    def step_all_QR_2(A):
        """
         d:A的行数
         r:A的列数
         :param A:
         :return:
         """
        A = np.array(A, dtype=float)  # 注意经此操作后,后续操作不会改变原来的A
        d, r = A.shape
        Q = np.diag(np.ones(d, dtype=float))
        for i in range(r):
            u, k = step_one_QR_2(A[i:, i])
            if k <= 0.0000001:
                print("Matrix may not full rank...")
                return Q, A  #A非列满秩
            Q[:, i:] -= np.outer(Q[:, i:] @ u, u / k)
            A[i:, :] -= np.outer(u / k, u @ A[i:, :])
    
        return Q, A
    
  • 相关阅读:
    阶段3 3.SpringMVC·_03.SpringMVC常用注解_1 RequestParam注解
    阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_7 获取Servlet原生的API
    函数传参
    利用 操作符特性 代替if判断语句
    for(;;)和 while(1) 有什么区别吗?for()和while()的使用情景。
    一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)
    ARM异常---一个DataAbort的触发过程:
    C语言,单链表操作(增删改查)(version 0.1)
    Cpu实验
    H-JATG:NAND_FLASH的参数设置
  • 原文地址:https://www.cnblogs.com/MTandHJ/p/10527983.html
Copyright © 2011-2022 走看看