Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rcpp-使用较大的列表加速嵌套列表操作_R_Rcpp - Fatal编程技术网

Rcpp-使用较大的列表加速嵌套列表操作

Rcpp-使用较大的列表加速嵌套列表操作,r,rcpp,R,Rcpp,Rcpp列表操作 // [[Rcpp::export]] vec cf_shallowstrict_i(const Rcpp::List & inlist){ NumericVector ave = inlist["a"]; NumericMatrix bma = inlist["b"]; arma::vec avec(ave.begin(), ave.size(), false, true); arma::mat bmat(bma.begin(), bma.rows

Rcpp列表操作

// [[Rcpp::export]]
vec cf_shallowstrict_i(const Rcpp::List & inlist){
  NumericVector ave =  inlist["a"];
  NumericMatrix bma =  inlist["b"];
  arma::vec avec(ave.begin(), ave.size(), false, true);
  arma::mat bmat(bma.begin(), bma.rows(), bma.cols(), false, true);
  return( vectorise(trans(trans(avec) * bmat)));
}


// [[Rcpp::export]]
mat cf_shallowstrict(const Rcpp::List & outerlist){
  int outerlistsize =outerlist.size();
  mat outmatrix(outerlistsize,4);
  for(int ll=0; ll<outerlistsize; ll++){
    Rcpp::List innerlist = outerlist[ll];
    outmatrix.row(ll)= trans(cf_shallowstrict_i(innerlist));
  }
  return(outmatrix);
}
注:这篇文章是根据最初的反馈进行编辑的

Rcpp和列表操作-这是这里的热门话题。当对象较大时,列表中对象的复制与浅复制确实很重要。下面我用一个简单的例子来说明这一点

问题

有没有其他加快访问嵌套循环元素的方法

设置

首先,让我介绍一下数据结构:嵌套列表,其中内部列表包含一个向量和一个矩阵。一个嵌套列表将填充包含小向量/矩阵的列表,另一个填充大向量/矩阵的列表。这种结构与许多层次模型是一致的,在层次模型中,对每个i在i级进行某种计算

R 假设我们想对这些列表中的每一个做一个简单的矩阵乘法。一个简单的R版本:

rfun=function(outerlist){
  outerlistsize=length(outerlist)
  outmatrix=matrix(NA,outerlistsize,4)

  for(ll in 1:outerlistsize){
    outmatrix[ll,]= outerlist[[ll]]$a %*% outerlist[[ll]]$b
  }
}
Rcpp 现在让我们在Rcpp中执行此操作。不同版本:

  • 香草犰狳(复制对象)
  • 浅拷贝犰狳
  • 具有浅拷贝和固定尺寸的犰狳
  • 香草结构
  • 具有初始浅复制的结构(但最终结构创建会复制对象)
犰狳

    #include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;

// [[Rcpp::depends("RcppArmadillo")]]


// [[Rcpp::export]]
vec cf_copy_i(Rcpp::List inlist){
  vec avec =  Rcpp::as<arma::vec>(inlist["a"]);
  mat bmat =  Rcpp::as<arma::mat>(inlist["b"]);
  return( vectorise(trans(trans(avec) * bmat)));
}

// [[Rcpp::export]]
mat cf_copy(Rcpp::List outerlist){
  int outerlistsize =outerlist.size();
  mat outmatrix(outerlistsize,4);
  for(int ll=0; ll<outerlistsize; ll++){
    Rcpp::List innerlist = outerlist[ll];
    outmatrix.row(ll)= trans(cf_copy_i(innerlist));
  }
  return(outmatrix);
}
。。。和大数据

##                    test replications elapsed relative
## 3       cf_shallow(bgd)          100    3.47    1.000
## 4 cf_shallowstrict(bgd)          100    3.54    1.020
## 1             rfun(bgd)          100   11.28    3.251
## 2          cf_copy(bgd)          100   17.52    5.049
## 6 cf_structshallow(bgd)          100   51.51   14.844
## 5        cf_struct(bgd)          100   64.82   18.680

“但是当里面的对象更大时,Rcpp实际上会使事情变慢”——乍一看,这可能是因为您转换为
arma::
类型。当您从Rcpp类型转换为,例如,
arma::vec
arma::mat
等时,必须执行深度复制,对于较大的对象,这可能需要相当长的时间。您是否仅使用Rcpp类型测试了您的声明?请注意,有一些方法可以实例化arma对象,而无需复制,这就是我们在接口上所做的。但是@nrussell是正确的,这是你要尝试的第一件事。一旦你做到了这一点,尝试零成本arma转换。听起来似乎有道理。这个简单的例子在普通的Rcpp中很容易实现,而其他得益于Armadillo易用性的代码片段则不然。德克:有关于零成本arma转换的指导吗?看看arma文档中的高级构造函数;有两个布尔开关承诺不改变dims,并重用内存。谢谢!这确实加快了速度。不过,strict=true参数似乎没有影响。有什么评论吗?
// [[Rcpp::export]]
vec cf_shallowstrict_i(const Rcpp::List & inlist){
  NumericVector ave =  inlist["a"];
  NumericMatrix bma =  inlist["b"];
  arma::vec avec(ave.begin(), ave.size(), false, true);
  arma::mat bmat(bma.begin(), bma.rows(), bma.cols(), false, true);
  return( vectorise(trans(trans(avec) * bmat)));
}


// [[Rcpp::export]]
mat cf_shallowstrict(const Rcpp::List & outerlist){
  int outerlistsize =outerlist.size();
  mat outmatrix(outerlistsize,4);
  for(int ll=0; ll<outerlistsize; ll++){
    Rcpp::List innerlist = outerlist[ll];
    outmatrix.row(ll)= trans(cf_shallowstrict_i(innerlist));
  }
  return(outmatrix);
}
// [[Rcpp::export]]
vec cf_nolist_i(const vec & avec, const mat & bmat){
  vec outvec= vectorise(trans(trans(avec) * bmat));
  return(outvec);
}


struct stuff{
  vec a;
  mat b;
};

// [[Rcpp::export]]
mat cf_struct(const Rcpp::List & outerlist){
  int outerlistsize =outerlist.size();
  std::vector<stuff> list_vector;
  stuff listi_struct;
  List listi;

  for(int ij=0; ij<outerlistsize; ij++){
    listi = outerlist[ij];
    listi_struct.a = as<vec>(listi["a"]);
    listi_struct.b = as<mat>(listi["b"]);
    list_vector.push_back(listi_struct);  
  }

  mat outmatrix(outerlistsize,4);
  for(int ll=0; ll<outerlistsize; ll++){
    outmatrix.row(ll)= trans(cf_nolist_i(list_vector[ll].a, list_vector[ll].b));
  }
  return(outmatrix);
}
// [[Rcpp::export]]
mat cf_structshallow(const Rcpp::List & outerlist){
  int outerlistsize =outerlist.size();
  std::vector<stuff> list_vector;
  stuff listi_struct;
  List listi;

  for(int ij=0; ij<outerlistsize; ij++){
    listi = outerlist[ij];
     NumericVector ave =  listi["a"];
     NumericMatrix bma =  listi["b"];
     arma::vec avec(ave.begin(), ave.size(), false, true);
     arma::mat bmat(bma.begin(), bma.rows(), bma.cols(), false, true);
    listi_struct.a = avec;
    listi_struct.b = bmat;
    list_vector.push_back(listi_struct);  
  }

  mat outmatrix(outerlistsize,4);
  for(int ll=0; ll<outerlistsize; ll++){
    outmatrix.row(ll)= trans(cf_nolist_i(list_vector[ll].a, list_vector[ll].b));
  }
  return(outmatrix);
}
library(rbenchmark)
smd=outerlist_smalldata
bgd=outerlist_bigdata

bench_small=benchmark(rfun(smd),cf_copy(smd),cf_shallow(smd),cf_shallowstrict(smd),cf_struct(smd),cf_structshallow(smd), order="relative")
print(bench_small[,1:4])

##                    test replications elapsed relative
## 3       cf_shallow(smd)          100    0.03    1.000
## 4 cf_shallowstrict(smd)          100    0.03    1.000
## 2          cf_copy(smd)          100    0.08    2.667
## 1             rfun(smd)          100    0.14    4.667
## 6 cf_structshallow(smd)          100    0.39   13.000
## 5        cf_struct(smd)          100    0.40   13.333
##                    test replications elapsed relative
## 3       cf_shallow(bgd)          100    3.47    1.000
## 4 cf_shallowstrict(bgd)          100    3.54    1.020
## 1             rfun(bgd)          100   11.28    3.251
## 2          cf_copy(bgd)          100   17.52    5.049
## 6 cf_structshallow(bgd)          100   51.51   14.844
## 5        cf_struct(bgd)          100   64.82   18.680