我有以下顺序R代码:
w.1 <- diag(seq(1:7))
ut.mat <- cbind(diag(3), -1*rbind(c(1,1,1,1),c(1,1,0,0), c(0,0,1,1)))
x <- matrix(rnorm(7), 7, 1)
lhs.l <- ut.mat %*% w.1 %*% t(ut.mat)
rhs.l <- ut.mat %*% x
p.0 <- r.0 <- rhs.l
l.0 <- matrix(0, 3, 1)
for(i in 1:3)
{
a.0 <- (t(r.0) %*% r.0) / (t(p.0) %*% lhs.l %*% p.0)
l.0 <- l.0 + (a.0[1,1] * p.0)
r.1 <- r.0 - (a.0[1,1] * lhs.l %*% p.0)
b.0 <- (t(r.1) %*% r.1) / (t(r.0) %*% r.0)
p.0 <- r.1 + (b.0[1,1] * p.0)
r.0 <- r.1
}
这是一个简单的案例。但实际上,ut.mat,x,p.0,l.0的尺寸很大,我也很大。
使用for循环非常耗时。任何提高效率的想法都是一个顺序过程,我认为并行化也是不可能的。
感谢。
答案 0 :(得分:0)
除了像flodel建议的那样只计算 lhs.1%*%p.0 之外,您可以使用矩阵运算替换,例如(t(r.0)%*%r.0 )计算两个向量的内积,其和(r.0 * r.0)为2. - 2.5倍。您也可以将b.0作为单独的变量消除,但这不会改变时间。修改后的代码看起来像
shani_faster <- function() {
w.1 <- diag(seq(1:7))
ut.mat <- cbind(diag(3), -1*rbind(c(1,1,1,1),c(1,1,0,0), c(0,0,1,1)))
x <- matrix(rnorm(7), 7, 1)
lhs.l <- ut.mat %*% w.1 %*% t(ut.mat)
rhs.l <- ut.mat %*% x
p.0 <- r.0 <- rhs.l
l.0 <- matrix(0, 3, 1)
r.1 <- numeric(3)
for(i in 1:3)
{
lhs.p <- lhs.l %*% p.0
a.0 <- sum(r.0^2)/sum(p.0*lhs.p)
l.0 <- l.0 + (a.0 * p.0)
r.1 <- r.0 - a.0 * lhs.p
p.0 <- r.1 + sum(r.1^2)/sum(r.0^2) * p.0
r.0 <- r.1
}
}
我使用原始代码创建了一个名为shani的函数,并调用了修改后的版本shani_faster。两个版本10000次执行的执行时间是
microbenchmark(shani(), shani_faster(), times=10000)
Unit: microseconds
expr min lq median uq max neval
shani() 112.352 116.345 118.626 121.191 23799.475 10000
shani_faster() 52.469 55.606 56.747 58.172 1132.928 10000
因此,大部分减少是由于内部产品计算的变化导致的两倍改进。我希望你能看到更大的载体的这个改进因素。我同意其他评论,在此之后,您对代码的处理能力不高。您可以尝试搜索实现算法的R包。