在 R 中进行矩阵元素乘法和矩阵标量乘法的更快方法

问题描述 投票:0回答:1

我正在对大型矩阵进行元素级乘法,所以我想知道是否有任何方法比使用 de R Base 中的 * 运算符更快。我一直在试图找出答案,但大多数问题和信息都是面向矩阵乘法的。

我们可以尝试下一个例子

A<- matrix(rnorm(10000),ncol =100 )
B<- matrix(rnorm(10000),ncol =100 )
A*B # Is there a faster way for this operation?
A*5000 # Is there a faster way for escalar multiplication?
r matrix scalar elementwise-operations
1个回答
0
投票

我能够使用 Rcpp 显着加速矩阵标量乘法,但使用 Rcpp 代码进行元素矩阵乘法仍然比基本 R 慢。我不确定是否有更快的方法使用 C++ 代码来执行此操作。也许如果你将它与 RcppParallel(我不知道如何使用)结合起来,它可能能够比基本 R 更快地进行元素乘法。但是它还不够快吗?在我下面的测试中,A 和 B 有 1,000,000 行和 100 列,并且使用基本 R 元素乘法仍然只需要大约五分之一秒。

library(Rcpp)

cppFunction('
NumericMatrix matrix_multiplication_elementwise(NumericMatrix A, NumericMatrix B) {
  int nrow = A.nrow(), ncol = A.ncol();
  NumericMatrix C(nrow, ncol);
  
  double* ptrA = A.begin();
  double* ptrB = B.begin();
  double* ptrC = C.begin();
  
  for (int i = 0; i < nrow * ncol; i++) {
    ptrC[i] = ptrA[i] * ptrB[i];
  }
  
  return C;
}
')


cppFunction('
NumericMatrix matrix_scalar_multiplication(NumericMatrix A, double scalar) {
  // Get the number of rows and columns in the matrix
  int nrow = A.nrow(), ncol = A.ncol();
  int n = nrow * ncol;
  
  // Get pointers to the beginning of the matrix data
  double* ptrA = A.begin();
  
  // Loop over each element of the matrix using pointer arithmetic
  for (int i = 0; i < n; i++) {
    ptrA[i] *= scalar;
  }
  
  // Return the modified matrix
  return A;
}
')


A <- matrix(rnorm(10^8),ncol =100 )
B <- matrix(rnorm(10^8),ncol =100 )

#Shows the results are identical
print(identical(A * B, matrix_multiplication_elementwise(A, B)))
print(identical(A * 5, matrix_scalar_multiplication(A, 5)))

microbenchmark::microbenchmark(A*B, 
                               matrix_multiplication_elementwise(A, B),
                               A*5,
                               matrix_scalar_multiplication(A, 5),
                               times = 5)

benchmark results

© www.soinside.com 2019 - 2024. All rights reserved.