我试图用双循环编写一个函数,因为我必须模拟一个双和。这段代码我的代码有效,但速度很慢,我怎样才能加快速度呢?
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)
但我肯定是错的。
答案 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)))