LDL分解并对厄而米特矩阵求逆(python仿真)

1. LDL分解

1.1. 原理

直接参考链接:https://blog.csdn.net/wanghu213/article/details/83963950这里不赘述。

1.2. python仿真

import numpy as np
np.set_printoptions(linewidth=np.inf)

M = 4

A = np.array([[3,      2+4j,   4+2.5j,   2+7.2j], 
              [2-4j,   4   ,   7+0.4j,   22+4j], 
              [4-2.5j, 7-0.4j, 5,        42+0.22j],
              [2-7.2j, 22-4j,  42-0.22j, 6]])

U = np.zeros_like(A)
L = np.zeros_like(A)
D = np.zeros_like(A)

for i in range(M):
    L[i, i] = 1

for j in range(M):
    tmp_sum = 0
    for m in range(j):
        tmp_sum += U[j, m] * L[j, m].conj()
    D[j, j] = A[j, j] - tmp_sum
    tmp_sum = 0
    for i in range(j+1, M):
        tmp_sum = 0
        for m in range(j):
            tmp_sum += U[i, m] * L[j, m].conj()
        U[i, j] = A[i, j] - tmp_sum
        L[i, j] = U[i, j] / D[j, j]

print('L:')
print(L)

print('D:')
print(D)

print('origin:')
print(A)

print('LDLH:')
print(np.dot(L, np.dot(D, L.conj().T)))

结果:

L:
[[ 1.        +0.j          0.        +0.j          0.        +0.j          0.        +0.j        ]
 [ 0.66666667-1.33333333j  1.        +0.j          0.        +0.j          0.        +0.j        ]
 [ 1.33333333-0.83333333j -0.375     +1.525j       1.        +0.j          0.        +0.j        ]
 [ 0.66666667-2.4j        -4.15      +0.7j         9.69471154+5.74278846j  1.        +0.j        ]]
D:
[[   3.        +0.00000000e+00j    0.        +0.00000000e+00j    0.        +0.00000000e+00j    0.        +0.00000000e+00j]
 [   0.        +0.00000000e+00j   -2.66666667+0.00000000e+00j    0.        +0.00000000e+00j    0.        +0.00000000e+00j]
 [   0.        +0.00000000e+00j    0.        +0.00000000e+00j    4.16      +0.00000000e+00j    0.        +0.00000000e+00j]
 [   0.        +0.00000000e+00j    0.        +0.00000000e+00j    0.        +0.00000000e+00j -493.56293269+2.84217094e-14j]]
origin:
[[ 3.+0.j    2.+4.j    4.+2.5j   2.+7.2j ]
 [ 2.-4.j    4.+0.j    7.+0.4j  22.+4.j  ]
 [ 4.-2.5j   7.-0.4j   5.+0.j   42.+0.22j]
 [ 2.-7.2j  22.-4.j   42.-0.22j  6.+0.j  ]]
LDLH:
[[ 3.+0.00000000e+00j  2.+4.00000000e+00j  4.+2.50000000e+00j  2.+7.20000000e+00j]
 [ 2.-4.00000000e+00j  4.+0.00000000e+00j  7.+4.00000000e-01j 22.+4.00000000e+00j]
 [ 4.-2.50000000e+00j  7.-4.00000000e-01j  5.+0.00000000e+00j 42.+2.20000000e-01j]
 [ 2.-7.20000000e+00j 22.-4.00000000e+00j 42.-2.20000000e-01j  6.+2.84217094e-14j]]**加粗样式**

可以看出,原始矩阵和 L D L H LDL^H LDLH结果一致。

2. Hermitian矩阵求逆

主要思路是已知:
L D L H A − 1 = I LDL^HA^{-1}=I LDLHA1=I; 设 D L H A − 1 = B DL^HA^{-1}=B DLHA1=B,则 L B = I LB=I LB=I; 求解 B B B, 其

2.1. 仿真代码

import numpy as np
import time
np.set_printoptions(linewidth=np.inf)
np.set_printoptions(precision=8,suppress=True)

M = 4

def LDLH(A):
    U = np.zeros_like(A)
    L = np.zeros_like(A)
    D = np.zeros_like(A)

    for i in range(M):
        L[i, i] = 1

    for j in range(M):
        tmp_sum = 0
        for m in range(j):
            tmp_sum += U[j, m] * L[j, m].conj()
        D[j, j] = A[j, j] - tmp_sum
        tmp_sum = 0
        for i in range(j+1, M):
            tmp_sum = 0
            for m in range(j):
                tmp_sum += U[i, m] * L[j, m].conj()
            U[i, j] = A[i, j] - tmp_sum
            L[i, j] = U[i, j] / D[j, j]

    return L, D

def LDL_solve(L, D):
    M = L.shape[0]
    B = np.zeros_like(L)
    V = np.zeros_like(L)
    for i in range(M):
        B[i, i] = 1
    for j in range(M-1):
        B[j+1, j] = -L[j+1, j]
        for i in range(j+2, M):
            tmp_sum = 0
            for m in range(j+1, i):
                tmp_sum += B[m, j] * L[i, m]
            B[i, j] = -L[i, j] - tmp_sum

    for j in range(M):
        V[M-1, j] = B[M-1, j] / D[M-1, M-1]
        V[j, M-1] = V[M-1, j].conj()
        for i in range(M-2, j-1, -1):
            tmp_sum = 0
            for m in range(i+1, M):
                tmp_sum += L[m, i].conj() * V[m, j]
            V[i, j] = B[i, j] / D[i, i] - tmp_sum
            V[j, i] = V[i, j].conj()

    return V

A = np.array([[3,      2+4j,   4+2.5j,   2+7.2j], 
              [2-4j,   4   ,   7+0.4j,   22+4j], 
              [4-2.5j, 7-0.4j, 5,        42+0.22j],
              [2-7.2j, 22-4j,  42-0.22j, 6]])


V_np = np.linalg.inv(A)

L, D = LDLH(A)
V = LDL_solve(L, D)


print('v_np - v:')
print(V_np - V)

print('AV')
print(np.dot(A, V))

结果:

v_np - v:
[[-0.+0.j  0.-0.j -0.+0.j  0.+0.j]
 [ 0.+0.j -0.-0.j -0.-0.j -0.+0.j]
 [ 0.-0.j -0.+0.j -0.+0.j  0.-0.j]
 [-0.-0.j -0.-0.j  0.+0.j -0.+0.j]]
AV
[[ 1.-0.j  0.+0.j -0.+0.j  0.-0.j]
 [-0.-0.j  1.-0.j  0.+0.j -0.-0.j]
 [-0.-0.j  0.-0.j  1.+0.j -0.-0.j]
 [-0.+0.j  0.-0.j  0.+0.j  1.-0.j]]

可以看出求逆的结果和numpy的计算结果一致,且原始矩阵和求逆矩阵乘积为单位阵。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值