r语言 - 计算二次形式的有效方法:避免 for 循环



我想计算N(N很大)二次形式。 我正在使用R包"模拟器"中的命令"quad.form"。如何在不使用 for 循环的情况下实现这一点?

到目前为止,我正在使用

library(emulator)
A = matrix(1,ncol=5,nrow=5) # A matrix
x = matrix(1:25,ncol=5,nrow=5) # The vectors of interest in the QF
# for loop
QF = vector()
for(i in 1:5){
QF[i] = quad.form(A,x[,i])
}

有没有更直接、更有效的方法来计算这些二次型?

人寻味的是,

quad.form(A,x)

比 for 循环快(10 倍),但我只需要这个结果的对角线。因此,它仍然是计算兴趣的N二次形式的低效方法。

怎么样

colSums(x * (A %*% x))

? 至少得到这个例子的正确答案...而且应该快得多!

library("rbenchmark")
A <- matrix(1, ncol=500, nrow=500)
x <- matrix(1:25, ncol=500, nrow=500)
library("emulator")
aa <- function(A,x) apply(x, 2, function (y) quad.form(A,y))
cs <- function(A,x) colSums(x * (A %*% x))
dq <- function(A,x) diag(quad.form(A,x))
all.equal(cs(A,x),dq(A,x))  ## TRUE
all.equal(cs(A,x),aa(A,x))  ## TRUE
benchmark(aa(A,x),
          cs(A,x),
          dq(A,x))
##       test replications elapsed relative user.self sys.self
## 1 aa(A, x)          100  13.121    1.346    13.085    0.024
## 2 cs(A, x)          100   9.746    1.000     9.521    0.224
## 3 dq(A, x)          100  26.369    2.706    25.773    0.592

使用 apply 函数:

apply(x, 2, function (y) quad.form(A,y))

如果使矩阵变大(500x500),很明显,使用apply的速度大约是使用quad.form(A,x)的两倍:

A <- matrix(1, ncol=500, nrow=500)
x <- matrix(1:25, ncol=500, nrow=500)
system.time(apply(x, 2, function (y) quad.form(A,y)))
# user  system elapsed 
# 0.183   0.000   0.183 
system.time(quad.form(A,x))
# user  system elapsed 
# 0.314   0.000   0.314 

编辑

@Ben博尔克的回答比apply快了大约 1/3:

system.time(colSums(x * (A %*% x)))
# user  system elapsed 
# 0.123   0.000   0.123 

最新更新