我需要加快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
不是正方形,还有其他技巧吗?
答案 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))})