使用 List 将 R 矩阵转换为 arma::mat

Posted

技术标签:

【中文标题】使用 List 将 R 矩阵转换为 arma::mat【英文标题】:Converting R matrix to arma::mat with List 【发布时间】:2019-08-15 22:01:05 【问题描述】:

我想使用 arma::mat 作为我的矩阵列表。

将 R 矩阵转换为 arma::mat 与 const 配合得很好。

但是当我使用 List 和矩阵作为参数时,它需要很长时间。

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
int check1(List X)

   int i;
   for (i = 0; i < 10; i ++)
      arma::mat y = as<arma::mat>(X[i]);
   return 0;

// [[Rcpp::export]]
int check2(const List& X)

   int i;
   for (i = 0; i < 10; i ++)
      arma::mat y = as<arma::mat>(X[i]);
   return 0;

// [[Rcpp::export]]
int check3(List X)

   int i;
   for (i = 0; i < 10; i ++)
      NumericMatrix y = X[i];
   return 0;

matlist = lapply(1:10, function(x) matrix(rnorm(10000), 2000, 50))
microbenchmark::microbenchmark(
   arma = check1(matlist),
   carma = check2(matlist),
   nm = check3(matlist)
)
Unit: microseconds
  expr     min       lq      mean  median      uq      max neval
  arma 558.081 597.6485 622.13757 614.702 625.928 1303.494   100
 carma 551.950 600.4425 658.33583 612.761 626.683 1749.153   100
    nm   2.288   4.3590   5.57801   5.123   5.901   39.743   100

【问题讨论】:

【参考方案1】:

似乎发生了一些副本,这会减慢您的代码速度。

为了在创建犰狳矩阵时防止复制,一种解决方案是:

// [[Rcpp::export]]
int check4(List X)

  int i;
  for (i = 0; i < 10; i ++) 
    NumericMatrix x = X[i];
    arma::mat y = arma::mat(x.begin(), x.nrow(), x.ncol(), false);
  
  return 0;

基准测试:

Unit: microseconds
    expr     min       lq      mean   median       uq      max neval
    arma 599.669 606.5465 634.41683 610.4185 632.4370 1519.262   100
   carma 600.506 606.0975 624.18013 609.8885 629.5135 1327.891   100
      nm   2.100   2.5030  10.88695   3.5180   4.2670  743.220   100
 nm_arma   2.949   3.3160  11.48330   4.7625   5.3195  685.302   100

PS:const&amp; 不会对您的 Rcpp 代码进行任何更改。请参阅https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-FAQ.pdf 的第 5.1 节。

【讨论】:

使用advanced constructors 是要走的路。 const arma::mat&amp; 参数会自动发生这种情况! 您对 Rcpp FAQ 的第 5.1 节的阅读不太正确。由于代理模型,&amp; 是多余的,const 可以通过从所谓的const 创建一个新的SEXP 来解决,但const 会阻止您修改原始SEXP。尝试以下函数:void const_mod(const Rcpp::IntegerVector&amp; x) x = x + 1; 对诸如 x &lt;- 1:5 之类的数据(注意您必须使用 -fpermissive 进行编译)。你会看到x 没有被修改。

以上是关于使用 List 将 R 矩阵转换为 arma::mat的主要内容,如果未能解决你的问题,请参考以下文章

如何将矩阵转换为R中的列向量列表?

需要帮助将 BMP 图像转换为 [R] 中的矩阵吗?

67-R中dataframe与list的转换

R语言中怎样将数据框转换成矩阵?

r 将简单三元组矩阵(tm包)转换为R中的稀疏矩阵

R:将二进制文件转换为矩阵