用 R 中的连续索引向量化向量和矩阵的叉积

Vectorising a cross product of vector and matrix with consecutive indices in R

一些上下文:我有一个维度为 n×1 的向量 e 和一个 n×n 的相关矩阵 R。我正在尝试有效地计算数量

在 R 中,没有循环。到目前为止,我已经能够使用以下代码通过单个循环完成此操作:

nom <- 0; denom <- 0
for(i in 1:n){
  nom <- nom + e[i]*(R[i,-(1:i)]%*%e[-(1:i)])
  denom <- denom + e[i]*sum(e[-(1:i)])
}
beta <- nom/denom

这行得通,实际上我的计算应该不会花很长时间,因为对于手头的任务,n 的大小最多为 11 或 12(因此改进可能不会对测量的时间性能产生巨大差异) .但是,我很好奇如何更有效地完成此操作,因为

a) R是对称的,计算只需要用到R主对角线上方(或下方)的部分,

b) 我打算在一些大型 MC 模拟中使用它,因此我可以节省的任何计算时间都可能对全局产生影响。


出于 replication/calculation 的目的,这里是一个可能的数值示例:

e <- c(0.4972,0.0902,0.02822,0.1688,0.0149,0.0028,0.01411,0.02733,0.0151,0.0391,0.01301,0.0894)
R <- matrix(data = c(1,0.9,0.4,0.75,0.5,0.3,0.4,0.4,0.25,0.25,0.5,0.4,0.9,1,0.5,0.9,0.5,0.3,0.4,0.35,0.2,0.2,0.5,0.3,0.4,0.5,1,0.3,0.5,0.4,0.25,0.2,0.2,0.2,0.3,0.3,0.75,0.9,0.3,1,0.3,0.3,0.4,0.25,0.25,0.2,0.3,0.75,0.5,0.5,0.5,0.3,1,0.5,0.35,0.8,0.8,0.3,0.7,0.45,0.3,0.3,0.4,0.3,0.5,1,0.3,0.4,0.3,0.2,0.45,0.35,0.4,0.4,0.25,0.4,0.35,0.3,1,0.3,0.3,0.2,0.5,0.5,0.4,0.35,0.2,0.25,0.8,0.4,0.3,1,0.8,0.2,0.6,0.8,0.25,0.2,0.2,0.25,0.8,0.3,0.3,0.8,1,0.3,0.7,0.8,0.25,0.2,0.2,0.2,0.3,0.2,0.2,0.2,0.3,1,0.25,0.3,0.5,0.5,0.3,0.3,0.7,0.45,0.5,0.6,0.7,0.25,1,0.7,0.4,0.3,0.3,0.75,0.45,0.35,0.5,0.8,0.8,0.3,0.7,1), nrow = 12, ncol = 12)

你可以这样做:

ee <- tcrossprod(e)
ee0 <- ee; diag(ee0) <- 0

sum(R*ee0)/sum(ee0)

对于您的示例数据:

> sum(R*ee0)/sum(ee0)
[1] 0.5647038

稍微节省一点计算:sum(ee0)等于

sum(e)^2 - sum(e^2)

这是另一种变体:

d <- diag(R)
diag(R) <- 0
sum(e*crossprod(e, R))/(sum(e)^2 - sum(e^2))