我试图将对角矩阵W传递给Rcpp函数。问题是W的大小为1,000,000×1,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000W的大小,这是(我认为)远远超出Armadillo允许(即使当使用C++11编译器启用ARMA_64BIT_WORD )。
由于W是对角矩阵,所以它非常稀疏。因此,我首先生成了W的密集表示(使用矩阵包函数对角)。然后,我将这些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;
}R码:
# 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并执行矩阵操作吗?
here也问了一个类似的问题。但是,我认为@Dirk提供的解决方案在这种情况下是可行的,因为与我的W相比,输入矩阵仍然很小。
发布于 2020-10-20 13:41:46
最初发布的代码实际上是正确的,但不知怎么的,它运行的机器并不是-请参阅上面的讨论。
作为附加,这里有一个没有全局命名空间的稍微编辑过的代码版本,对矩阵的实际访问(传递就足够了,这就是更显式的)并返回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> https://stackoverflow.com/questions/64428776
复制相似问题