【问题标题】:Sweep in matrix operations in R not working as intended扫描 R 中的矩阵运算未按预期工作
【发布时间】:2018-07-31 04:29:14
【问题描述】:

我目前正在尝试有效地实现一个新的方阵 M,它是两个相同维度的方阵 WV 的函数,如下所示: Fij = Wii·Vji。即Fith行是ith的对角元素W 乘以 Vith 列。

R 中有一个函数sweep,它允许在数组的边缘扫描统计数据。即,做

mean.att <- apply(attitude, 2, mean)
sweep(data.matrix(attitude), 2, mean.att)

将对attitude 矩阵(取自帮助)的列(第 2nd 维)进行贬义。此外,还可以提供一个函数,例如FUN="*"。在这种情况下,attitude 矩阵的列将乘以各自的中位数。

所以生成矩阵 F 的预期代码是

Fij <- matrix(NA, ncol=N, nrow=N)
for (i in 1:N) {
  Fij[i, ] <- w[i, i] * v[, i]
}

显然,由于 R 的长处是矢量化,这可以通过 sweep 操作来完成:我想将 V 的列 (FUN="*") 乘以W的对角线,即

Fij2 <- sweep(v, 2, diag(w), FUN="*")

但是,每当我检查 Fij==Fij2 时,它们都不是!

MWE:

set.seed(1)
w <- matrix(rnorm(16), nrow=4)
v <- matrix(rnorm(16), nrow=4)
Fij <- matrix(NA, ncol=4, nrow=4)
for (i in 1:4) { # This loop can and should be vectorised
  Fij[i, ] <- w[i, i] * v[, i]
}
Fij2 <- sweep(v, 2, diag(w), FUN="*")
Fij
Fij2

对角元素相等,但非对角元素不相等。

如果有人澄清 Fij 的哪些实现是错误的,我将不胜感激!

【问题讨论】:

    标签: arrays r matrix vectorization matrix-multiplication


    【解决方案1】:

    使用扫描的实现给出了转置的结果。如果您使用更简单的输入矩阵,您可以很容易地看到这一点:

    w <- matrix(1:4, nrow = 2)
    v <- matrix(5:8, nrow = 2)
    Fij <- matrix(NA, ncol=2, nrow=2)
    for (i in 1:2) {
      Fij[i, ] <- w[i, i] * v[, i]
    }
    Fij2 <- sweep(v, 2, diag(w), FUN="*")
    Fij
    #>      [,1] [,2]
    #> [1,]    5    6
    #> [2,]   28   32
    Fij2
    #>      [,1] [,2]
    #> [1,]    5   28
    #> [2,]    6   32
    t(Fij2)
    #>      [,1] [,2]
    #> [1,]    5    6
    #> [2,]   28   32
    

    所以Fij 与您的描述相符,t(Fij2) 也是如此。

    【讨论】:

    • 啊,谢谢!当然,从 Vji = t(Vij) 的角度来考虑会更容易!真是个不注意的地方……
    【解决方案2】:

    您只是忘记转置其中一个矩阵,两种实现都有效:

    identical(Fij, t(Fij2))
    # [1] TRUE
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 2019-06-20
      • 2021-04-13
      • 1970-01-01
      相关资源
      最近更新 更多