【问题标题】:More general or efficient approach for this matrix multiplication?这种矩阵乘法的更通用或更有效的方法?
【发布时间】:2019-06-29 13:08:26
【问题描述】:

在 R 中,是否有更有效和/或更通用的方法来从下面的两个矩阵产生所需的输出?我怀疑我所做的只是一些我不知道的深奥的矩阵乘法运算。

ff <- matrix(1:6,ncol=2)
# [,1] [,2]
# [1,]    1    4
# [2,]    2    5
# [3,]    3    6

bb <- matrix(7:10,ncol=2)
# [,1] [,2]
# [1,]    7    9
# [2,]    8   10

# DESIRE:
#  7 36
# 14 45
# 21 54
#  8 40
# 16 50
# 24 60

这可行,但不是我正在寻找的一般解决方案:

rr1 <- t(t(ff) * bb[1,])
rr2 <- t(t(ff) * bb[2,])
rbind(rr1,rr2)
# [,1] [,2]
# [1,]    7   36
# [2,]   14   45
# [3,]   21   54
# [4,]    8   40
# [5,]   16   50
# [6,]   24   60

下一个代码块看起来非常高效且通用。但是有更好的方法吗? 像kronecker(ffa,bba) 这样的东西? (在这种情况下显然不起作用)

ffa <- matrix(rep(t(ff),2), ncol=2, byrow=T)
bba <- matrix(rep(bb,each=3), ncol=2)
ffa * bba
# [,1] [,2]
# [1,]    7   36
# [2,]   14   45
# [3,]   21   54
# [4,]    8   40
# [5,]   16   50
# [6,]   24   60

这与我的其他问题有关:

  1. Using apply function over the row margin with expectation of stacked results,我试图了解apply 本身的行为,并且:

  2. Is this an example of some more general matrix product?,我在这里特别询问理论数学。

【问题讨论】:

  • 这不是你之前发过的类似帖子吗here
  • 之前,我想具体了解apply 函数在解决这个特定问题时发生了什么。在这里,我想知道是否有更通用/更有效的方法来获得所需的输出,而不必使用apply
  • 也许你需要do.call(rbind, lapply(seq_len(nrow(bb)), function(i) t(t(ff) * bb[i, ])))
  • 您是否在寻找计算效率?在什么大小的矩阵上?与大型矩阵相比,对于本示例中的小型矩阵,不同的解决方案可能最快。
  • 对于那些感兴趣的人,我对我的实际数据进行了微基准测试:1. 我的解决方案(在原始问题中),2. Grothendieck 的 kronecker 解决方案,3. Grothendieck 的 mapply 解决方案,以及 4. Langsrud 的KhatriRao 解决方案。我发现运行时间中位数为 36、200、20、314(以纳秒为单位,每次运行 10 次)。所以,mapply 是速度赢家。

标签: r linear-algebra matrix-multiplication


【解决方案1】:

使用克罗内克产品并选择适当的列:

kronecker(bb, ff)[, c(diag(ncol(bb))) == 1]

或使用 kronecker 的中缀运算符:

(bb %x% ff)[, c(diag(ncol(bb))) == 1]

另一种方法是将参数转换为数据帧和mapplykronecker。对于问题中的情况,这将执行cbind(bb[, 1] %x% ff[, 1], bb[, 2] %x% ff[, 2]) 的计算,但以更一般的方式而不诉诸索引:

mapply(kronecker, as.data.frame(bb), as.data.frame(ff))

或使用kronecker 的中缀运算符:

mapply(`%x%`, as.data.frame(bb), as.data.frame(ff))

【讨论】:

  • 我最终使用了您的mapply 解决方案,因为它是最快的、易于解释的,并且不需要加载额外的包。这与 Langsrud 的 KhatriRao 解决方案之间的密切联系
【解决方案2】:

您正在寻找的功能在 Matrix 包中作为函数 KhatriRao 提供。由于函数在 Matrix 中,因此输出是类“dgCMatrix”(稀疏矩阵)的矩阵。您可以通过 as.matrix 将其转换为“矩阵”类的普通矩阵。

library(Matrix)
as.matrix(KhatriRao(bb, ff))

【讨论】:

  • 不鼓励使用纯代码的答案。请单击edit 并添加一些词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。 From Review
猜你喜欢
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 2018-07-05
  • 2013-09-14
  • 2021-11-27
  • 1970-01-01
  • 2021-07-17
  • 2018-12-05
相关资源
最近更新 更多