对两个矩阵 (R) 之间的每个列组合进行高效的复杂运算

Posted

技术标签:

【中文标题】对两个矩阵 (R) 之间的每个列组合进行高效的复杂运算【英文标题】:Efficient complex operations on every combination of columns between two matrices (R) 【发布时间】:2022-01-19 20:22:52 【问题描述】:

给定两个矩阵,我想在每个列组合中的值之间执行复杂的运算(具体来说,我希望计算两个给定列中值的乘积的平方根之和)。

这听起来像是outer 的工作:

set.seed(123)
a <- matrix(abs(rnorm(12)),nrow=4)
a
           [,1]      [,2]      [,3]
[1,] 0.56047565 0.1292877 0.6868529
[2,] 0.23017749 1.7150650 0.4456620
[3,] 1.55870831 0.4609162 1.2240818
[4,] 0.07050839 1.2650612 0.3598138

b <- matrix(abs(rnorm(12)),nrow=4)
b
          [,1]      [,2]      [,3]
[1,] 0.4007715 0.4978505 1.0678237
[2,] 0.1106827 1.9666172 0.2179749
[3,] 0.5558411 0.7013559 1.0260044
[4,] 1.7869131 0.4727914 0.7288912

m <- outer (
  as.data.frame(a),
  as.data.frame(b),
  Vectorize(function (x, y)   sum(sqrt(x*y),na.rm=T))
)
m
         V1       V2       V3
V1 1.919315 2.429191 2.488925
V2 2.672994 3.432185 2.630920
V3 2.373466 2.859966 2.800881

...但是对于我正在使用的矩阵的大小来说,这被证明是非常缓慢的。最快的方法是什么?我不认为这种方法适当地利用了矢量化。

附: as.data.frame 调用是我不喜欢的这种方法的另一个方面,但没有它我不会得到所需的输出。相反,outer 返回一个数组:

dim(m)
[1] 4 3 4 3

【问题讨论】:

【参考方案1】:

sqrt a 和 b 中的每一个,然后使用 crossprod 给出与 m 相同的结果。 (请注意,问题使用了没有 set.seed 的随机数,所以这里的 m 与问题中的不同。)

crossprod(sqrt(a), sqrt(b))
##          [,1]     [,2]     [,3]
## [1,] 1.940283 1.957321 1.914920
## [2,] 2.740899 2.611588 2.564304
## [3,] 2.983868 2.957246 2.872090

m
##          V1       V2       V3
## V1 1.940283 1.957321 1.914920
## V2 2.740899 2.611588 2.564304
## V3 2.983868 2.957246 2.872090

【讨论】:

以上是关于对两个矩阵 (R) 之间的每个列组合进行高效的复杂运算的主要内容,如果未能解决你的问题,请参考以下文章

R - 给定一个矩阵和一个幂,生成多个矩阵,其中包含矩阵列的所有唯一组合

R - 给定一个矩阵和一个幂,生成多个矩阵,其中包含矩阵列的所有组合

R语言基础知识笔记

使用 Rcpp 的高效矩阵子集

如何识别两个数据矩阵之间的哪些列和行匹配?

R:循环矩阵对特定行单独排序列