在RcppArmadillo中处理极大的稀疏矩阵 [英] Handling extremely large and sparse matrices in RcppArmadillo

查看:38
本文介绍了在RcppArmadillo中处理极大的稀疏矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

因为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相比,输入矩阵仍然很小。

推荐答案

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

作为一个附加组件,以下是略微编辑过的代码版本,没有全局命名空间、对矩阵的实际访问(传递就足够了,这只是更显式),并返回void。我们还添加了可以使用RCPP属性执行的常见的"Call It from R For Me"技巧。

代码

// 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> 

这篇关于在RcppArmadillo中处理极大的稀疏矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆