【问题标题】:Calculating column-wise dot product between two matrices计算两个矩阵之间的按列点积
【发布时间】:2016-04-12 22:28:59
【问题描述】:

我想确定一个矩阵中第 i 列与第二个矩阵中第 i 列之间的点积。最终结果将是一个包含 i 点积的数组。

这是我想做的一个可重复的例子:

#Generate two matrices with 10 columns each with 5 rows (thus i in this case is 10)
m1 <- replicate(10, rnorm(5)) 
m2 <- replicate(10, rnorm(5)) 

#Inefficiently calculate dot product of ith column in m1 with ith column in m2
d1 <- t(m1[,1]) %*% m2[,1]
d2 <- t(m1[,2]) %*% m2[,2]
...
d10 <- t(m1[,10]) %*% m2[,10]

#End with all dot products in array
d.final <- c(d1, d2, d10)

我们将不胜感激!

肯

【问题讨论】:

  • @user20650 啊,我误读了他的 qn。将删除评论

标签: r matrix matrix-multiplication dot-product


【解决方案1】:

这里有几个选项

最明确的选择(imo)是使用循环

out1 <- sapply(1:10, function(i) crossprod(m1[,i], m2[,i]))

或计算全矩阵叉积

out2 <- diag(crossprod(m1, m2))

或通过对元素乘法求和

out3 <- colSums(m1*m2)

检查

all.equal(out1, out2)
all.equal(out3, out2)

一个小基准

f1 <- function() sapply(1:ncol(m1), function(i) crossprod(m1[,i], m2[,i]))
f2 <- function() diag(crossprod(m1, m2))
f3 <- function() colSums(m1*m2)

# on your data
microbenchmark::microbenchmark(f1(), f2(), f3())
#  Unit: microseconds
#  expr    min      lq     mean median      uq     max neval cld
#  f1() 62.508 65.2325 69.46337 66.873 70.9945 123.271   100   b
#  f2()  8.312  9.4290 12.05529  9.778 10.2670 229.708   100   a 
#  f3() 11.385 12.4325 16.14248 12.921 13.5500 310.235   100   a 

# on bigger data
m1 <- replicate(1000, rnorm(1000)) 
m2 <- replicate(1000, rnorm(1000)) 
all.equal(f1(), f2())
all.equal(f2(), f3())

microbenchmark::microbenchmark(f1(), f3()) #f2 took too long
#  Unit: milliseconds
#  expr       min        lq     mean   median       uq      max neval cld
#  f1() 35.181220 38.065454 41.59141 39.93301 42.17569 82.13914   100   b
#  f3()  8.349807  9.220799 11.13763 10.19330 11.21829 53.57050   100   a 

【讨论】:

  • 做到了!非常感谢。
猜你喜欢
  • 2022-01-13
  • 1970-01-01
  • 2012-02-07
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 2018-12-02
  • 2017-03-06
相关资源
最近更新 更多