我可以从矩阵的逆中得到 Cholesky 分解吗?

机器算法验证 线性代数
2022-03-18 12:51:32

我有一个巨大的协方差矩阵的逆矩阵,我想从中绘制随机实例。

我知道如何做到这一点的方法是对协方差矩阵进行 Cholesky 分解,并使用它来变换独立高斯向量。所以直接的过程是反转巨矩阵,然后进行 Cholesky 分解。

由于首先可以使用 Cholesky 分解来获得逆,因此似乎有一种方法可以在没有反演步骤的情况下获得我需要的东西(这需要很长时间)。

问题:有没有办法在不反转矩阵的情况下使用 Cholesky 分解来做到这一点?

1个回答

您可以通过特征分解方法生成绘图来避免反转矩阵。按照这个方法,抽奖是通过做这个乘积产生的:

(VD)X,

其中是矩阵的特征向量,是包含特征值平方根的对角矩阵, 是包含从标准单变量 分布中抽取的矩阵。VDXN(0,1)

通过使用这些结果可以直接调整此方法并避免恢复原始协方差矩阵:1)矩阵的特征值是其逆的特征值的倒数;2) 矩阵 A 的特征向量也是其逆的特征向量。AA1A1


例子:

假设原始协方差矩阵如下:

A=[10.80.40.820.30.40.33].
但是你有这个矩阵的逆矩阵,B=A1
A1=B=[1.6990.7250.2990.7250.8170.1780.2990.1780.391].

基于原始矩阵的特征分解方法 为抽签样本生成以下协方差矩阵:A

A <- rbind(c(1,0.8,-0.4), c(0.8,2,0.3), c(-0.4,0.3,3))
e1 <- eigen(A, symmetric=TRUE)
set.seed(1)
X <- matrix(rnorm(5000*ncol(A)), ncol=ncol(A))
draws1 <- t(e1$vectors %*% sqrt(diag(e1$values)) %*% t(X))
draws1.cov <- cov(draws1)
draws1.cov
#           [,1]      [,2]       [,3]
#[1,]  0.9765023 0.8030752 -0.3970233
#[2,]  0.8030752 1.9941052  0.3229827
#[3,] -0.3970233 0.3229827  3.1689348

使用您拥有的矩阵(的倒数A),您只需反转特征值:

B <- solve(A)
e2 <- eigen(B, symmetric=TRUE)
e2$values <- 1/e2$values
draws2 <- t(e2$vectors %*% sqrt(diag(e2$values)) %*% t(X))
draws2.cov <- cov(draws2)
draws2.cov
#           [,1]      [,2]       [,3]
#[1,]  0.9765023 0.8030752 -0.3970233
#[2,]  0.8030752 1.9941052  0.3229827
#[3,] -0.3970233 0.3229827  3.1689348

获得了与原始协方差矩阵非常匹配的协方差矩阵,我们不需要B为了恢复原始协方差矩阵而求逆A


一个小模拟来检查这种方法的有效性:

set.seed(3)
niter <- 1000
m <- matrix(0, nrow=ncol(A), ncol=ncol(A))
for (i in seq_len(niter))
{
    X <- matrix(rnorm(5000*ncol(A)), ncol=ncol(A))
    draws2 <- t(e2$vectors %*% sqrt(diag(e2$values)) %*% t(X))
    m <- m + cov(draws2)
}
m/niter
# average covariance matrix
#           [,1]      [,2]       [,3]
#[1,]  1.0005129 0.7995872 -0.4005644
#[2,]  0.7995872 1.9993231  0.2990850
#[3,] -0.4005644 0.2990850  2.9957277
# original covariance matrix 'A'
#    [,1] [,2] [,3]
#[1,]  1.0  0.8 -0.4
#[2,]  0.8  2.0  0.3
#[3,] -0.4  0.3  3.0

我们可以看到,平局的协方差矩阵平均非常接近原始协方差矩阵A