R中的矢量化矩阵和数组乘法

时间:2021-10-05 21:20:39

I could not figure out, how to write a vectorized version of the following matrix and array multiplication:

我想不通,如何编写以下矩阵和数组乘法的矢量化版本:

v = rep(0.1, 2)
v2 = matrix(0, nrow = 2, ncol = 3)
A = matrix(0.25, nrow = 2, ncol = 3)
R = matrix(- 1, nrow = 2, ncol = 3)  
P = array(1:12, dim = c(2, 2, 3))
for (i in 1:3) {
  v2[, i] = A[, i] * (R[, i] + P[, , i] %*%  v)
}
v = rowSums(v2)

Can someone help?

有人可以帮忙吗?

1 个解决方案

#1


3  

The problem that we are faced with is that we want to do matrix multiplication over P, a 3d array. As this is not efficiently possible, it is better to transform this array to a 2d column matrix.

我们面临的问题是我们想要在P(3d数组)上进行矩阵乘法。由于这不可能有效,最好将此数组转换为2d列矩阵。

P <- array(1:12, dim = c(2, 2, 3))
P <- matrix(P, nrow = 2)

The A and R matrices don't have to be adjusted for this to work

A和R矩阵不需要调整就可以工作

A <- matrix(0.25, nrow = 2, ncol = 3)
R <- matrix(-1, nrow = 2, ncol = 3) 

Matrix multiplication with the v vector can then be accomplished by transforming the column vector into a sparse block diagonal matrix with the bdiag(...) function from the Matrix package.

然后可以通过使用来自Matrix包的bdiag(...)函数将列向量变换为稀疏块对角矩阵来实现与v向量的矩阵乘法。

library(Matrix)

v <- rep(0.1, 2)
v <- bdiag(v, v, v)

## [1,] 0.1 .   .  
## [2,] 0.1 .   .  
## [3,] .   0.1 .  
## [4,] .   0.1 .  
## [5,] .   .   0.1
## [6,] .   .   0.1

This gives the same result as before, however, this time in a vectorized manner.

这给出了与之前相同的结果,但这次是以矢量化的方式。

v <- rowSums(A * (R + (P %*% v)))
## [1] 0.15 0.30

Edit: In the above equation I use two types of multiplication: *, the dot-product, which computes the element-wise products between two matrices of equal size, and %*%, the ordinary matrix product, which computes the matrix product of two conformable matrices, or in other words, the number of columns of the first, and the number of rows of the second matrix should be equal.

编辑:在上面的等式中我使用两种类型的乘法:*,点积,它计算两个相同大小矩阵之间的元素乘积和%*%,普通矩阵乘积,它计算矩阵乘积两个适形矩阵,或换句话说,第一个列的列数和第二个矩阵的行数应该相等。

Edit2: As requested I have included how to transform the given P array to a matrix.

Edit2:根据要求,我已经包括了如何将给定的P数组转换为矩阵。

Edit3: This method can be generalized by introducing a variable n for the number of groups. The key adjustment is in the declaration of the block diagonal matrix, as next to individual matrices, this function also takes a list of matrices as input. This results in the following solution

编辑3:可以通过为组数引入变量n来推广此方法。关键调整是在块对角矩阵的声明中,作为单个矩阵的旁边,该函数还将矩阵列表作为输入。这导致以下解决方案

library(Matrix)
n <- 3
P <- array(1:12, dim = c(2, 2, n))
P <- matrix(P, nrow = 2)
A <- matrix(0.25, nrow = 2, ncol = n)
R <- matrix(-1, nrow = 2, ncol = n) 
v <- rep(0.1, 2)
v <- bdiag(rep(list(v),n))
v <- rowSums(A * (R + (P %*% v)))
## [1] 0.15 0.30

#1


3  

The problem that we are faced with is that we want to do matrix multiplication over P, a 3d array. As this is not efficiently possible, it is better to transform this array to a 2d column matrix.

我们面临的问题是我们想要在P(3d数组)上进行矩阵乘法。由于这不可能有效,最好将此数组转换为2d列矩阵。

P <- array(1:12, dim = c(2, 2, 3))
P <- matrix(P, nrow = 2)

The A and R matrices don't have to be adjusted for this to work

A和R矩阵不需要调整就可以工作

A <- matrix(0.25, nrow = 2, ncol = 3)
R <- matrix(-1, nrow = 2, ncol = 3) 

Matrix multiplication with the v vector can then be accomplished by transforming the column vector into a sparse block diagonal matrix with the bdiag(...) function from the Matrix package.

然后可以通过使用来自Matrix包的bdiag(...)函数将列向量变换为稀疏块对角矩阵来实现与v向量的矩阵乘法。

library(Matrix)

v <- rep(0.1, 2)
v <- bdiag(v, v, v)

## [1,] 0.1 .   .  
## [2,] 0.1 .   .  
## [3,] .   0.1 .  
## [4,] .   0.1 .  
## [5,] .   .   0.1
## [6,] .   .   0.1

This gives the same result as before, however, this time in a vectorized manner.

这给出了与之前相同的结果,但这次是以矢量化的方式。

v <- rowSums(A * (R + (P %*% v)))
## [1] 0.15 0.30

Edit: In the above equation I use two types of multiplication: *, the dot-product, which computes the element-wise products between two matrices of equal size, and %*%, the ordinary matrix product, which computes the matrix product of two conformable matrices, or in other words, the number of columns of the first, and the number of rows of the second matrix should be equal.

编辑:在上面的等式中我使用两种类型的乘法:*,点积,它计算两个相同大小矩阵之间的元素乘积和%*%,普通矩阵乘积,它计算矩阵乘积两个适形矩阵,或换句话说,第一个列的列数和第二个矩阵的行数应该相等。

Edit2: As requested I have included how to transform the given P array to a matrix.

Edit2:根据要求,我已经包括了如何将给定的P数组转换为矩阵。

Edit3: This method can be generalized by introducing a variable n for the number of groups. The key adjustment is in the declaration of the block diagonal matrix, as next to individual matrices, this function also takes a list of matrices as input. This results in the following solution

编辑3:可以通过为组数引入变量n来推广此方法。关键调整是在块对角矩阵的声明中,作为单个矩阵的旁边,该函数还将矩阵列表作为输入。这导致以下解决方案

library(Matrix)
n <- 3
P <- array(1:12, dim = c(2, 2, n))
P <- matrix(P, nrow = 2)
A <- matrix(0.25, nrow = 2, ncol = n)
R <- matrix(-1, nrow = 2, ncol = n) 
v <- rep(0.1, 2)
v <- bdiag(rep(list(v),n))
v <- rowSums(A * (R + (P %*% v)))
## [1] 0.15 0.30