避免顺序过程的循环

时间:2014-09-13 01:40:38

标签: r for-loop

我有以下顺序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循环非常耗时。任何提高效率的想法都是一个顺序过程,我认为并行化也是不可能的。

感谢。

1 个答案:

答案 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包。