Rcpp:处理包含列表的列表

时间:2014-01-21 05:10:38

标签: c++ r rcpp armadillo

让我们首先生成一些包含列表的列表:

lappend <- function(lst, ...){
  lst <- c(lst, list(...))
  return(lst)
}

scalarList <- list()
vectorList <- list()
MatrixList <- list()

for (i in 1:3){
  scalarList <- lappend(scalarList,i)
  vectorList <- lappend(vectorList,0:i)
  MatrixList <- lappend(MatrixList, diag(i + 1))
}

myRList <- list(scalarList = scalarList, vectorList = vectorList, 
  MatrixList = MatrixList)

既然我们的myRList已经准备就绪,我想用C ++编写一个函数,如下所示:

1)输入:1)myRList,2)1到3的id

2)输出:该函数应分别打印与输入id对应的标量,矢量和矩阵。

3)编写此功能的方法可能有很多种。我特别想要读入列表,将其分配给相应的arma对象然后打印它。原因是我写了这个简化的例子,向大家学习如何在Rcpp中的另一个列表中提取列表的元素并将其分配给arma对象。

这是我的C ++代码:

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

// [[Rcpp::export]]
double myListExtractor( Rcpp::List aList_In_R, int id){
int myScalar = Rcpp::as<double>(aList_In_R["scalarList"][id]); //? what to do ?
arma::vec myVector = Rcpp::as<arma::vec>(aList_In_R["vectorList"[id]]); //???
arma::mat myMatrix = Rcpp::as<arma::mat>(aList_In_R["MatrixList"[id]]); //???

// If I manage to do the three assignments above, then printing is easy:

Rcpp::Rcout << "myScalar = " << myScalar << std::endl;
Rcpp::Rcout << "myVector = " << myVector << std::endl; 
Rcpp::Rcout << "myMatrix = " << myMatrix << std::endl;

return 1; // we don't care about the return for now
}

同样,我100%同意不需要将它们分配给arma对象然后打印。在我自己的代码中,我使用arma对象做了很多代数,这就是为什么我要强调这个任务来学习如何修复我的代码/

非常感谢您的帮助。此外,我花了3个小时浏览网络,我没有找到任何答案。

1 个答案:

答案 0 :(得分:4)

由于List个对象对它们包含的对象类型一无所知,因此在每个子集级别都必须as。例如:

int myScalar = Rcpp::as<double>( Rcpp::as<Rcpp::List>(aList_In_R["scalarList"])[id] );

这样,我们可以向编译器发出信号,我们从aList_In_R中提取的广告位是List,我们为List提供的所有方法都应该适用于此处。这很丑陋,但使用静态类型语言操作动态类型语言中使用的对象是一个不幸的后果。

将模板化列表容器放入Rcpp可能有助于解决这种情况;例如而不是List你可能有一个ListOf< List >,子集运算符会“知道”在子集化后它应该返回List,这可能会更好一些。也许它可以像ListOf< ListOf< double > >等一样深......