householder进行矩阵QR分解

本文详细介绍了Householder变换的原理,通过实际案例展示了如何使用Householder变换进行QR分解,最终将矩阵A分解成正交矩阵Q和上三角矩阵R。

1. HouseHolder 理论分析

HouseHolder变换的目的是为了将向量 x 1 x_1 x1通过镜面反射的方式,在保持大小不变的情况下,变成在x轴上的向量 x 2 x_2 x2具体如下图所示:
在这里插入图片描述
HouseHolder变换和Givens变换的目的是一致的,都是通过反射,旋转的方式,将任意向量 x 1 x_1 x1变到x轴上,形成向量 x 2 x_2 x2

  • 由图可得向量之间关系如下
    x 1 = x 2 + 2 w (1) x_1=x_2+2w\tag{1} x1=x2+2w(1)
  • 做一个辅助单位向量 w 0 w_0 w0,使得 w 0 w_0 w0平行于w, ∣ w 0 ∣ = 1 |w_0|=1 w0=1
    在这里插入图片描述
  • w w w的长度可以计算如下:
    w 0 T x 1 = ∣ w 0 ∣ ∣ x 1 ∣ cos ⁡ θ 2 (2) w_0^Tx_1=|w_0||x_1|\cos{\theta_2}\tag{2} w0Tx1=w0∣∣x1cosθ2(2)
    ∣ w ∣ = ∣ x 1 ∣ cos ⁡ θ 2 (3) |w|=|x_1|\cos{\theta_2}\tag{3} w=x1cosθ2(3)
  • 方程1,3结合可得如下:
    x 1 = x 2 + 2 w 0 T x 1 ∣ w 0 ∣ w 0 (4) x_1=x_2+2\frac{w_0^Tx_1}{|w_0|}w_0\tag{4} x1=x2+2w0w0Tx1w0(4)
  • 因为我们定义 ∣ w 0 ∣ = 1 |w_0|=1 w0=1,并且 w 0 T x 1 w_0^Tx_1 w0Tx1为一个数,所以在矩阵中可以任意调位置,即
    x 1 = x 2 + 2 w 0 w 0 T x 1 (5) x_1=x_2+2w_0w_0^Tx_1\tag{5} x1=x2+2w0w0Tx1(5)
  • 整理可得如下
    x 2 = x 1 − 2 w 0 w 0 T x 1 = ( I − 2 w 0 w 0 T ) x 1 (6) x_2=x_1-2w_0w_0^Tx_1=(I-2w_0w_0^T)x_1\tag{6} x2=x12w0w0Tx1=(I2w0w0T)x1(6)
  • 变成常规大家熟悉的公式如下,u为单位向量
    u = [ 1 0 0 ] (7) u=\begin{bmatrix}1\\\\0\\\\0\end{bmatrix}\tag{7} u= 100 (7)
    y = ( I − 2 u u T ) x (8) y=(I-2uu^T)x\tag{8} y=(I2uuT)x(8)

2. Householder 案例

2.1 Householder进行QR分解

A = Q R (9) A=QR\tag{9} A=QR(9)
A = [ 1 2 0 1 1 0 3 1 1 0 3 2 1 2 0 2 ] (10) A=\begin{bmatrix}1&2&0&1\\\\1&0&3&1\\\\1&0&3&2\\\\1&2&0&2\end{bmatrix}\tag{10} A= 1111200203301122 (10)
从矩阵A中取出第一列 a 1 ⃗ = [ 1 , 1 , 1 , 1 ] T \vec{a_1}=[1,1,1,1]^T a1 =[1,1,1,1]T ∥ α 1 ∥ 2 = 1 2 + 1 2 + 1 2 + 1 2 = 2 \lVert \alpha_1\rVert_2=\sqrt{1^2+1^2+1^2+1^2}=2 α12=12+12+12+12 =2
u 1 ⃗ = a 1 ⃗ − α 1 e 1 ⃗ ∥ a 1 ⃗ − α 1 e 1 ⃗ ∥ (11) \vec{u_1}=\frac{\vec{a_1}-\alpha_1\vec{e_1}}{\|\vec{a_1}-\alpha_1\vec{e_1}\|}\tag{11} u1 =a1 α1e1 a1 α1e1 (11)
e 1 ⃗ = [ 1 , 0 , 0 , 0 ] T (12) \vec{e_1}=[1,0,0,0]^T\tag{12} e1 =[1,0,0,0]T(12)

  • 带入可得:
    u 1 ⃗ = 1 2 [ − 1 , 1 , 1 , 1 ] T (13) \vec{u_1}=\frac{1}{2}[-1,1,1,1]^T\tag{13} u1 =21[1,1,1,1]T(13)
  • 根据householder 来定义矩阵 H 1 H_1 H1
    H 1 ⃗ = I ⃗ − 2 u 1 ⃗ ( u 1 ⃗ ) T (14) \vec{H_1}=\vec{I}-2\vec{u_1}(\vec{u_1})^T\tag{14} H1 =I 2u1 (u1 )T(14)
  • 带入可得:
    H 1 ⃗ = 1 2 [ 1 1 1 1 1 1 − 1 − 1 1 − 1 1 − 1 1 − 1 − 1 1 ] (15) \vec{H_1}=\frac{1}{2}\begin{bmatrix}1&1&1&1\\\\1&1&-1&-1\\\\1&-1&1&-1\\\\1&-1&-1&1\end{bmatrix}\tag{15} H1 =21 1111111111111111 (15)
  • 第一次householder变换 ,目的是保证第一列只有存在第一个元素,其他位置为0:
    H 1 ⃗ A = 1 2 [ 1 1 1 1 1 1 − 1 − 1 1 − 1 1 − 1 1 − 1 − 1 1 ] [ 1 2 0 1 1 0 3 1 1 0 3 2 1 2 0 2 ] (16) \vec{H_1}A=\frac{1}{2}\begin{bmatrix}1&1&1&1\\\\1&1&-1&-1\\\\1&-1&1&-1\\\\1&-1&-1&1\end{bmatrix}\begin{bmatrix}1&2&0&1\\\\1&0&3&1\\\\1&0&3&2\\\\1&2&0&2\end{bmatrix}\tag{16} H1 A=21 1111111111111111 1111200203301122 (16)
    H 1 ⃗ A = [ 2 2 3 3 0 0 0 − 1 0 0 0 0 0 2 − 3 0 ] (17) \vec{H_1}A=\begin{bmatrix}2&2&3&3\\\\0&0&0&-1\\\\0&0&0&0\\\\0&2&-3&0\end{bmatrix}\tag{17} H1 A= 2000200230033100 (17)
  • 我们重新第一新的矩阵 A 2 A_2 A2
    A 2 ⃗ = [ 0 0 − 1 0 0 0 2 − 3 0 ] (18) \vec{A_2}=\begin{bmatrix}0&0&-1\\\\0&0&0\\\\2&-3&0\end{bmatrix}\tag{18} A2 = 002003100 (18)
    从矩阵 A 2 A_2 A2中取出第一列 a 2 ⃗ = [ 0 , 0 , 2 ] T \vec{a_2}=[0,0,2]^T a2 =[0,0,2]T ∥ α 2 ∥ 2 = 0 2 + 0 2 + 2 2 = 2 \lVert \alpha_2\rVert_2=\sqrt{0^2+0^2+2^2}=2 α22=02+02+22 =2
    u 2 ⃗ = a 2 ⃗ − α 2 e 1 ⃗ ∥ a 2 ⃗ − α 2 e 1 ⃗ ∥ (19) \vec{u_2}=\frac{\vec{a_2}-\alpha_2\vec{e_1}}{\|\vec{a_2}-\alpha_2\vec{e_1}\|}\tag{19} u2 =a2 α2e1 a2 α2e1 (19)
    e 1 ⃗ = [ 1 0 0 ] T (20) \vec{e_1}=\begin{bmatrix}1&0&0\end{bmatrix}^T\tag{20} e1 =[100]T(20)
  • 带入相关参数可得:
    u 2 ⃗ = 2 2 [ − 1 0 1 ] T (21) \vec{u_2}=\frac{\sqrt{2}}{2}\begin{bmatrix}-1&0&1\end{bmatrix}^T\tag{21} u2 =22 [101]T(21)
    H 2 ~ = I ⃗ − 2 u 2 ⃗ ( u 2 ⃗ ) T (22) \tilde{H_2}=\vec{I}-2\vec{u_2}(\vec{u_2})^T\tag{22} H2~=I 2u2 (u2 )T(22)
  • 代入可得如下:
    H 2 ~ = [ 0 0 1 0 1 0 1 0 0 ] (23) \tilde{H_2}=\begin{bmatrix}0&0&1\\\\0&1&0\\\\1&0&0\end{bmatrix}\tag{23} H2~= 001010100 (23)
  • 同理可得 H 2 ~ A 2 ⃗ \tilde{H_2}\vec{A_2} H2~A2
    H 2 ~ A 2 ⃗ = [ 2 − 3 0 0 0 0 0 0 − 1 ] (24) \tilde{H_2}\vec{A_2}=\begin{bmatrix}2&-3&0\\\\0&0&0\\\\0&0&-1\end{bmatrix}\tag{24} H2~A2 = 200300001 (24)
    H 2 ⃗ = [ 1 H 2 ~ ] = [ 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 ] (25) \vec{H_2}=\begin{bmatrix}1&\\\\&\tilde{H_2}\end{bmatrix}=\begin{bmatrix}1&0&0&0\\\\0&0&0&1\\\\0&0&1&0\\\\0&1&0&0\end{bmatrix}\tag{25} H2 = 1H2~ = 1000000100100100 (25)
  • 依公式,我们定义R如下:
    R ⃗ = H 2 ⃗ ( H 1 ⃗ A ⃗ ) = [ 2 2 3 3 0 2 − 3 0 0 0 0 0 0 0 0 − 1 ] (26) \vec{R}=\vec{H_2}(\vec{H_1}\vec{A})=\begin{bmatrix}2&2&3&3\\\\0&2&-3&0\\\\0&0&0&0\\\\0&0&0&-1\end{bmatrix}\tag{26} R =H2 (H1 A )= 2000220033003001 (26)
  • 依公式,我们定义Q如下:
    Q ⃗ = H 1 ⃗ H 2 ⃗ = 1 2 [ 1 1 − 1 − 1 1 − 1 − 1 1 1 − 1 1 − 1 1 1 1 1 ] (27) \vec{Q}=\vec{H_1}\vec{H_2}=\frac{1}{2}\begin{bmatrix}1&1&-1&-1\\\\1&-1&-1&1\\\\1&-1&1&-1\\\\1&1&1&1\end{bmatrix}\tag{27} Q =H1 H2 =21 1111111111111111 (27)

3. 结论:

  • householder的意义是通过househoulder变换,可以将矩阵A 变成一个正交矩阵Q和上三角矩阵R
    A = Q R (28) A=QR\tag{28} A=QR(28)
    A = [ 1 2 0 1 1 0 3 1 1 0 3 2 1 2 0 2 ] (29) A=\begin{bmatrix}1&2&0&1\\\\1&0&3&1\\\\1&0&3&2\\\\1&2&0&2\end{bmatrix}\tag{29} A= 1111200203301122 (29)
    Q ⃗ = 1 2 [ 1 1 − 1 − 1 1 − 1 − 1 1 1 − 1 1 − 1 1 1 1 1 ] (30) \vec{Q}=\frac{1}{2}\begin{bmatrix}1&1&-1&-1\\\\1&-1&-1&1\\\\1&-1&1&-1\\\\1&1&1&1\end{bmatrix}\tag{30} Q =21 1111111111111111 (30)
    R ⃗ = [ 2 2 3 3 0 2 − 3 0 0 0 0 0 0 0 0 − 1 ] (31) \vec{R}=\begin{bmatrix}2&2&3&3\\\\0&2&-3&0\\\\0&0&0&0\\\\0&0&0&-1\end{bmatrix}\tag{31} R = 2000220033003001 (31)

4. Python code

  • 代码:
import numpy as np
np.set_printoptions(suppress=True,precision=3)

def householder_reflection(a):
    """
    计算给定向量a的Householder反射矩阵。
    """
    e = np.zeros_like(a)
    e[0] = np.linalg.norm(a)

    v = a - e
    v_norm = np.linalg.norm(v)

    # 避免除以零的情况
    if v_norm == 0:
        return np.eye(len(a))

    v = v / v_norm

    H = np.eye(len(a)) - 2 * np.outer(v, v)

    return H


def qr_decomposition(A):
    """
    使用Householder反射进行QR分解。
    参数:
        A: 输入矩阵 (m x n)
    返回:
        Q: 正交矩阵 (m x m)
        R: 上三角矩阵 (m x n)
    """
    m, n = A.shape
    Q = np.eye(m)
    R = A.copy()

    for i in range(n):
        # 从R的第i列开始,获取子向量
        x = R[i:, i]

        # 计算Householder反射矩阵
        H_i = np.eye(m)
        H = householder_reflection(x)
        H_i[i:, i:] = H

        # 更新R和Q
        R = H_i @ R
        Q = Q @ H_i

    return Q, R




A = np.array([[1,2,0,1],
              [1,0,3,1],
              [1,0,3,2],
              [1,2,0,2]])
Q, R = qr_decomposition(A)

print("Q:")
print(Q)
print("\nR:")
print(R)

# 验证 A = Q * R
print("\nQR Product (should equal A):")
print(Q @ R)
  • 结果:
Q:
[[ 0.5  0.5 -0.5 -0.5]
 [ 0.5 -0.5 -0.5  0.5]
 [ 0.5 -0.5  0.5 -0.5]
 [ 0.5  0.5  0.5  0.5]]

R:
[[ 2.  2.  3.  3.]
 [ 0.  2. -3. -0.]
 [ 0. -0.  0.  1.]
 [ 0. -0.  0.  0.]]

QR Product (should equal A):
[[1. 2. 0. 1.]
 [1. 0. 3. 1.]
 [1. 0. 3. 2.]
 [1. 2. 0. 2.]]

5. 创建househoulder矩阵

  • 通过给定一个任意一个单位向量u,可以创建一个单位正交矩阵,为Househoulder矩阵,具体如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :househoulder_vector.py
# @Time      :2024/10/18 20:26
# @Author    :Jason Zhang
import numpy as np

np.random.seed(2024)
np.set_printoptions(suppress=True, precision=3)

if __name__ == "__main__":
    run_code = 0
    N = 4
    for i in range(N):
        u_i = np.random.randn(N)
        u_i = u_i / (np.linalg.norm(u_i, ord=2))
        H_i = np.eye(N) - 2 * np.outer(u_i, u_i)
        result = H_i @ H_i.T
        print(f"\n")
        print("*" * 20)
        print(f"u_i={u_i}")
        print(f"H_{i}=\n{H_i}")
        print(f"HiNorm={round(np.linalg.norm(H_i, ord=2))}")
        print(f"result=\n{result}")
        print("*" * 20)
********************
u_i=[ 0.906  0.401 -0.109 -0.082]
H_0=
[[-0.642 -0.726  0.198  0.149]
 [-0.726  0.679  0.088  0.066]
 [ 0.198  0.088  0.976 -0.018]
 [ 0.149  0.066 -0.018  0.987]]
HiNorm=1
result=
[[ 1. -0.  0.  0.]
 [-0.  1.  0.  0.]
 [ 0.  0.  1. -0.]
 [ 0.  0. -0.  1.]]
********************


********************
u_i=[ 0.279  0.353 -0.797 -0.403]
H_1=
[[ 0.845 -0.197  0.444  0.225]
 [-0.197  0.751  0.563  0.285]
 [ 0.444  0.563 -0.27  -0.643]
 [ 0.225  0.285 -0.643  0.675]]
HiNorm=1
result=
[[ 1. -0.  0.  0.]
 [-0.  1.  0.  0.]
 [ 0.  0.  1. -0.]
 [ 0.  0. -0.  1.]]
********************


********************
u_i=[0.231 0.051 0.529 0.815]
H_2=
[[ 0.893 -0.024 -0.244 -0.376]
 [-0.024  0.995 -0.054 -0.084]
 [-0.244 -0.054  0.441 -0.862]
 [-0.376 -0.084 -0.862 -0.329]]
HiNorm=1
result=
[[ 1. -0. -0. -0.]
 [-0.  1. -0. -0.]
 [-0. -0.  1. -0.]
 [-0. -0. -0.  1.]]
********************


********************
u_i=[-0.708 -0.131  0.563  0.406]
H_3=
[[-0.001 -0.185  0.797  0.575]
 [-0.185  0.966  0.148  0.106]
 [ 0.797  0.148  0.366 -0.458]
 [ 0.575  0.106 -0.458  0.67 ]]
HiNorm=1
result=
[[ 1. -0.  0.  0.]
 [-0.  1.  0.  0.]
 [ 0.  0.  1. -0.]
 [ 0.  0. -0.  1.]]
********************
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值