我有一个上三角矩阵,我想快速计算它的逆。我尝试了qr.solve()
,但我觉得它等同于solve()
,并且它没有利用输入矩阵的三角形特性。最好的方法是什么?
答案 0 :(得分:2)
尝试backsolve()
并使用具有适当维度的单位矩阵作为右手值。
library(microbenchmark)
n <- 2000
n.cov <- 1000
X <- matrix(sample(c(0L, 1L), size = n * n.cov, replace = TRUE),
nrow = n, ncol = n.cov)
R <- chol(crossprod(X))
rm(X)
microbenchmark(
backsolve = backsolve(r = R, x = diag(ncol(R))),
solve = solve(R),
times = 10)
Unit: milliseconds
expr min lq mean median uq max neval
backsolve 467.2802 467.5142 469.4457 468.1578 468.6501 482.2431 10
solve 748.2351 748.8318 750.0764 750.3319 750.9583 751.5005 10
答案 1 :(得分:1)
如果您希望获得矩阵M
的倒数,则可以使用backsolve(M, diag(dim(M)[1]))
。例如:
M <- matrix(rnorm(100), 10, 10) # random matrix
M[lower.tri(M)] <- 0 # make it triangular
Minv <- backsolve(M, diag(dim(M)[1]))
M%*%Minv
运行此代码时,由于数值近似,您可能会看到M%*%Minv
系数非常低(~10 ^ -15)。
答案 2 :(得分:1)
最近,我遇到了同样的问题。我的解决方案是加载Matrix程序包,然后定义以下两个R函数作为该任务的包装器:
my.backsolve <- function(A, ...) solve(triu(A), ...)
my.forwardsolve <- function(A, ...) solve(tril(A), ...)
这些需要Matrix程序包,因为其中定义了triu
和tril
。然后my.backsolve(A)
(分别为my.forwardsolve(A)
)计算大写(分别为小写)三角格的A
的逆。
但是,一个较小的问题可能是上述两个R函数中每个函数的结果都属于Matrix
类。如果对此有疑问,请根据r.h.s是否适用as.vector
或as.matrix
应用于结果。是向量或矩阵(在代数意义上)。
答案 3 :(得分:0)
似乎solve
的执行速度比qr.solve
略快,但qr.solve
更强大。
n <- 50
mymatrix <- matrix(0, nrow=n, ncol=n)
fun1 <- function() {
for (i in 1:n) {
mymatrix[i, i:n] <- rnorm(n-i+1)+3
}
solve(mymatrix)
}
fun2 <- function() {
for (i in 1:n) {
mymatrix[i, i:n] <- rnorm(n-i+1)+3
}
qr.solve(mymatrix)
}
> system.time(for (i in 1:1000) fun1())
user system elapsed
1.92 0.03 1.95
> system.time(for (i in 1:1000) fun2())
user system elapsed
2.92 0.00 2.92
请注意,如果我们在编辑矩阵单元格时删除+3
,solve
几乎总会失败,qr.solve
通常仍会给出答案。
> set.seed(0)
> fun1()
Error in solve.default(mymatrix) :
system is computationally singular: reciprocal condition number = 3.3223e-22
> set.seed(0)
> fun2()
[returns the inverted matrix]
答案 4 :(得分:-1)
R基函数chol2inv
可能正在做反转三角矩阵的技巧。从其Choleski decomposition
反转对称的正定方阵。等价地,从(X'X)^(-1)
的(R部分)计算QR decomposition of X
。
更一般地,给定上三角矩阵R,计算(R'R)^(-1)
。
见https://stat.ethz.ch/R-manual/R-devel/library/base/html/chol2inv.html
我通过microbenchmark方法测试了它的速度:qr.solve是最慢的,解决速度排名第3,backsolve在速度上排名第2,chol2inv是最快的。
cma&lt; - chol(ma < - cbind(1,1:3,c(1,3,7)))
microbenchmark(qr.solve(ma),solve(ma),cma&lt; -chol(ma),chol2inv(cma),invcma&lt; -backsolve(cma,diag(nrow(cma))),backinvma&lt; -tcrossprod (invcma))