R中加权最小二乘协方差矩阵的加速逆

时间:2014-06-12 23:36:39

标签: r performance matrix

我需要加快R中WLS协方差矩阵的逆的计算,其中矩阵wls.cov.matrix由(下面的完整示例)给出:

n = 10000
X = matrix(c(rnorm(n,1,2), sample(c(1,-1), n, replace = TRUE), rnorm(n,2,0.5)), nrow = 1000, ncol = 3)
Q = diag(rnorm(n, 1.5, 0.3))
wls.cov.matrix = solve(t(X)%*%diag(1/diag(Q))%*%X)

是否可以加快计算速度?

与最终目标非常相关的更多信息: 这仍然是一些信息,让我更多地解释我的目标,如果有办法加快我的代码,我会更清楚 我运行了1,0000次wls.cov.matrix所以我需要它更快。

然而,每次我运行它时我使用相同的X,唯一改变的矩阵是Q,这是一个对角矩阵。

如果X是方阵,与Q相同,我可以预先计算X^-1(X^T)^(-1)

X.inv = solve(X)
X.inv.trans = solve(t(X))

然后为每次迭代运行:

Q.inv = diag(1/diag(Q))
wls.cov.matrix = X.inv%*%Q.inv%*%X.inv.trans

但我的X不是正方形,还有其他技巧吗?

2 个答案:

答案 0 :(得分:1)

嗯,Q是一个对角矩阵,所以它的倒数只是由对角线项的倒数给出的。你可以这样做

X = matrix(c(rnorm(n,1,2), sample(c(1,-1), n, replace = TRUE), rnorm(n,2,0.5)), nrow = 1000, ncol = 3)
Qinv = diag(1/rnorm(n, 1.5, 0.3))
wls.cov.matrix = solve(t(X)%*%Qinv%*%X)

事实上,这会使事情加快20倍。

答案 1 :(得分:1)

这里主要耗时的部分是t(X)%*%diag(1/diag(Q))%*%X,而不是其倒数的计算。

一个很好的技巧是将其计算为

crossprod(X / sqrt(diag(Q)));

确认:

all.equal( (t(X) %*% diag(1/diag(Q)) %*% X) , crossprod(X / sqrt(diag(Q))) );

[1] TRUE

比较时间运行:

Qdiag = diag(Q);
system.time({(t(X) %*% diag(1/Qdiag) %*% X)})
system.time({crossprod(X / sqrt(Qdiag))})