加速嵌套for循环

时间:2016-03-04 07:31:07

标签: r

我试图用双循环编写一个函数,因为我必须模拟一个双和。这段代码我的代码有效,但速度很慢,我怎样才能加快速度呢?

a& y是向量,x是矩阵。它们的长度都相同,即100. X是100x4(100行,4列)

X1 <- matrix(rnorm(4*100), ncol=4)
y1 <- sign(X1[,1] + X1[,2] > 0)*2 - 1

fn <- function (a,x,y){
  dsum <-0
  for(i in 1:length(y)){
    for(j in 1:length(y)){
      dsum <- dsum + a[j]*a[i]*y[j]*y[i]*(t(x)[,j])%*%x[i,]
    }
  }
  res <- sum(a)-.5*dsum
  return (res)
}

我试图做sum(a)-.5%*%sum(a%o%X%o%y*a%o%t(X)%o%y)但我肯定是错的。

2 个答案:

答案 0 :(得分:5)

试试这个:

fn2<-function(a,x,y) {
   one<-outer(a*y,a*y)
   two<-rowSums(x[rep(1:nrow(x),nrow(x)),]*x[rep(1:nrow(x),each=nrow(x)),])
   sum(a)-.5*sum(one*two)
}

一个例子:

set.seed(1)
a<-runif(100)
y<-runif(100)
x<-matrix(runif(400),nrow=100)
fn(a,x,y)
#[1,] -303.6947
fn2(a,x,y)
#[1] -303.6947

答案 1 :(得分:2)

dsum <- sum(tcrossprod(x*(a*y), x*(a*y)))

给出与循环中的计算相同的结果。简短版本是:

dsum <- sum(tcrossprod(x*(a*y)))

我认为这个解决方案很快。如果你想把它放在你的功能中,你可以这样做:

fn <- function (a,x,y) sum(a) - 0.5*sum(tcrossprod(x*(a*y)))

示例:

x <- matrix(1, 6, 2)
a <- 1:6
y <- 11:16

dsum <- 0
for(i in 1:length(y)) {
  for(j in 1:length(y)) {
    dsum <- dsum + a[j]*a[i]*y[j]*y[i]*(t(x)[,j])%*%x[i,]
  }
}
dsum

sum(tcrossprod(x*(a*y), x*(a*y)))
sum(tcrossprod(x*(a*y)))
相关问题