r语言 - 一个矩阵的每一行与另一个矩阵的对应行的叉乘



假设我有以下两个矩阵

A <- matrix(nrow = 5, ncol = 3, byrow = TRUE, c(
5, 1, 2, 
3, 1, 5, 
5, 1, 3, 
7, 2, 8, 
2, 4, 2
))
B <- matrix(nrow = 5, ncol = 2, byrow = TRUE, c(
2, 1,
3, 5,
1, 4,
3, 3,
3, 4
))
我想创建一个数组
arr <- array(NA, dim = c(ncol(A), ncol(B), nrow(A))) 

存储矩阵Ai行与矩阵B的同一行i的叉乘。例如,arr的切片2将是

A[2, ] %*% t(B[2, ]
[,1] [,2]
[1,]    9   15
[2,]    3    5
[3,]   15   25
使用for循环,我可以执行
for (i in 1:nrow(A)) {
arr[, , i] <- A[i, ] %*% t(B[i, ])
}

或者使用sapply函数

temp <- sapply(1:nrow(A), function(i) A[i, ] %*% t(B[i, ]), simplify = FALSE)
arr <- array(unlist(temp), dim = c(ncol(A), ncol(B), nrow(A))) 

我想知道在这种情况下是否有更聪明的方法使用矩阵乘积或内置函数。非常感谢。

我们可以尝试base R选项与mapply+tcrossprod,如下图

array(
mapply(tcrossprod, asplit(A, 1), asplit(B, 1)),
c(ncol(A), ncol(B), nrow(A))
)

1) einsum使用爱因斯坦求和符号

library(einsum)
arr1 <- einsum("ij,ik->jki", A, B)
identical(arr1, arr)
## [1] TRUE

2) Khatri Rao产品所讨论的产品与列式Khatri Rao产品有关有时也被称为Khatri Rao产品。请注意,Matrix是R自带的,所以不需要安装。

library(Matrix)
arr2 <- array(KhatriRao(t(B), t(A)), c(ncol(A), rev(dim(B))))
identical(arr2, arr)
## [1] TRUE

3)克罗内克产品如果X和Y是列数相同的矩阵,并且Im和In是m = nrow(X)和n = nrow(B)元素的列向量,那么我们可以使用恒等式X⊙Y = (X⊗In)°(Im⊗Y)表示Kronecker积和Hadamard积的Khatri Rao列积,即元素积的°来推导出另一个基解。

arr3 <- array( (t(B) %x% rep(1, ncol(A)) ) * 
( rep(1, ncol(B)) %x% t(A)), c(ncol(A), rev(dim(B))))
identical(arr3, arr)
## [1] TRUE

相关内容

最新更新