R中矩阵逆的高效计算

机器算法验证 r 矩阵分解 逆矩阵 数字
2022-01-25 14:37:02

我需要计算矩阵逆并且一直在使用solve函数。虽然它在小矩阵上运行良好,但solve在大矩阵上往往非常慢。我想知道是否有任何其他函数或函数组合(通过 SVD、QR、LU 或其他分解函数)可以给我更快的结果。

2个回答

您是否尝试过 cardinal 的建议并探索了一些计算逆的替代方法?让我们考虑一个具体的例子:

library(MASS)

k   <- 2000
rho <- .3

S       <- matrix(rep(rho, k*k), nrow=k)
diag(S) <- 1

dat <- mvrnorm(10000, mu=rep(0,k), Sigma=S) ### be patient!

R <- cor(dat)

system.time(RI1 <- solve(R))
system.time(RI2 <- chol2inv(chol(R)))
system.time(RI3 <- qr.solve(R))

all.equal(RI1, RI2)
all.equal(RI1, RI3)

所以,这是一个相关矩阵的例子,我们想要逆矩阵。在我的笔记本电脑(Core-i5 2.50Ghz)上,需要 8-9 秒,需要 4 秒多一点,需要 17-18 秒(建议多次运行代码以获得稳定的结果)。2000×2000solvechol2inv(chol())qr.solve()

因此,通过 Choleski 分解的逆运算速度大约是 的两倍solve当然可能有更快的方法来做到这一点。我只是在这里探索了一些最明显的。正如评论中已经提到的,如果矩阵具有特殊的结构,那么可能可以利用它来提高速度。

如果您正在使用协方差矩阵或任何可以使用的正定矩阵,pd.solve则速度会更快。

以沃尔夫冈为例:

library(MASS)
library(mnormt)

k   <- 2000
rho <- .3

S       <- matrix(rep(rho, k*k), nrow=k)
diag(S) <- 1

dat <- mvrnorm(10000, mu=rep(0,k), Sigma=S) ### be patient!

R <- cor(dat)

system.time(RI1 <- solve(R))
system.time(RI2 <- chol2inv(chol(R)))
system.time(RI3 <- qr.solve(R))

> system.time(RI1 <- solve(R))
  usuário   sistema decorrido 
    13.21      0.03     13.76 
> system.time(RI2 <- chol2inv(chol(R)))
  usuário   sistema decorrido 
     5.62      0.05      5.80 
> system.time(RI3 <- qr.solve(R))
  usuário   sistema decorrido 
    20.42      0.09     21.10 
> system.time(RI4 <- pd.solve(R))
  usuário   sistema decorrido 
     5.53      0.00      5.61