【问题标题】:Vectorising a cross product of vector and matrix with consecutive indices in R向量化向量和矩阵的叉积与 R 中的连续索引
【发布时间】:2019-09-17 09:40:58
【问题描述】:

一些上下文:我有一个维度为 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 模拟中使用它,因此我可以节省的任何计算时间都可能会对全局产生影响。


出于复制/计算目的,以下是可能数值的示例:

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)

【问题讨论】:

    标签: r matrix-multiplication cross-product


    【解决方案1】:

    你可以这样做:

    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))
    

    【讨论】:

    • 这是一个很好的答案,并且代码尽可能简洁。非常感谢!
    • @Emil 我添加了另一个变体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2016-05-18
    • 1970-01-01
    • 2018-10-10
    • 2014-02-22
    • 2018-02-20
    相关资源
    最近更新 更多