0

我正在尝试将对角矩阵传递W给 Rcpp 函数。问题是它W的大小为 1,000,000 x 1,000,000,(我认为)远远超出 Armadillo 允许的限制(即使使用启用了 ARMA_64BIT_WORD 的 C++11 编译器)。

由于W是对角矩阵,因此非常稀疏。出于这个原因,我首先生成了一个密集表示W(使用 Matrix 包函数对角线)。然后我将这些压缩表示传递W给我的函数。我认为这将解决任何内存问题。这是一个小例子:

C++ 代码:

#define ARMA_64BIT_WORD 1
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]

using namespace Rcpp;
using namespace arma;


// [[Rcpp::export]]
int test(sp_mat W){
  
  return 0;
  
}

代码:

# define the diagonal matrix
nrows <- 1e6
W <- Matrix::Diagonal(nrows)

# call Rcpp function
test(W)

但是,尽管使用了压缩表示,我仍然收到此错误。

error: SpMat::init(): requested size is too large; suggest to compile in C++11 mode and/or enable ARMA_64BIT_WORD

有什么方法可以处理W,以便我可以将它传递到test并执行矩阵运算?

此处提出了类似的问题。但是,我认为@Dirk 提供的解决方案在这种情况下有效,因为与我的W.

4

1 回答 1

1

最初发布的代码实际上是正确的,但不知何故,它运行的机器不是——有关详细信息,请参阅上面的讨论。

作为一个附加组件,这里是一个稍微编辑过的代码版本,没有全局命名空间,实际访问矩阵(传递就足够了,这更明确)并返回void. 我们还添加了常用的“为我从 R 调用它”技巧,可以使用 Rcpp 属性来完成。

代码

// lightly edited version of question, working fine for me
#define ARMA_64BIT_WORD 1
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
void spmatTest(arma::sp_mat M) {
  // show a simple access of matrix,
  // here we just sum elements on diagonal
  Rcpp::Rcout << "Sum of diag is "
              << arma::as_scalar(arma::sum(M.diag()))
              << std::endl;
}

/*** R
spmatTest( Matrix::Diagonal( 1e6 ))
spmatTest( Matrix::Diagonal( 1e7 ))
spmatTest( Matrix::Diagonal( 1e8 ))
*/

输出

R> Rcpp::sourceCpp("~/git/stackoverflow/64428776/answer.cpp")

R> spmatTest( Matrix::Diagonal( 1e6 ))
Sum of diag is 1e+06

R> spmatTest( Matrix::Diagonal( 1e7 ))
Sum of diag is 1e+07

R> spmatTest( Matrix::Diagonal( 1e8 ))
Sum of diag is 1e+08
R> 
于 2020-10-20T13:41:46.477 回答