扫描 R 中的矩阵运算未按预期工作
Sweep in matrix operations in R not working as intended
我目前正在尝试有效地实现一个新的方阵 M,作为两个相同维度的方阵 W 和 V[ 的函数=62=],如下: Fij = Wii·V ji。即,ith 行 F 是 ith W 乘以 ith 的对角线元素V.
列
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 操作来完成:我想乘以 [= 的列 (FUN="*"
) 38=]V乘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 中哪些实现是错误的,我将不胜感激!
你只是忘了转置其中一个矩阵,两种实现方式都有效:
identical(Fij, t(Fij2))
# [1] TRUE
使用扫描的实现给出了转置结果。如果您使用更简单的输入矩阵,您可以很容易地看到这一点:
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)
。
我目前正在尝试有效地实现一个新的方阵 M,作为两个相同维度的方阵 W 和 V[ 的函数=62=],如下: Fij = Wii·V ji。即,ith 行 F 是 ith W 乘以 ith 的对角线元素V.
列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 操作来完成:我想乘以 [= 的列 (FUN="*"
) 38=]V乘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 中哪些实现是错误的,我将不胜感激!
你只是忘了转置其中一个矩阵,两种实现方式都有效:
identical(Fij, t(Fij2))
# [1] TRUE
使用扫描的实现给出了转置结果。如果您使用更简单的输入矩阵,您可以很容易地看到这一点:
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)
。