动态增加Rcpp中列表的大小

Sac*_*amp 5 r list rcpp

我试图在Rcpp中实现"耦合到过去"的算法.为此,我需要存储一个随机数矩阵,如果算法没有收敛,则创建一个新的随机数矩阵并存储它.这可能需要做10次以上才能收敛.

我希望我可以使用List并动态更新它,就像我在R中一样.我实际上非常惊讶它有点工作但是每当列表大小变大时我就会出错.这似乎有意义,因为我没有为其他列表元素分配所需的内存,虽然我不熟悉C++并且不确定这是否是问题.

这是我尝试过的一个例子.但请注意,这可能会导致您的R会话崩溃:

library("Rcpp")

cppFunction(
includes = ' 
NumericMatrix RandMat(int nrow, int ncol)
 {
  int N = nrow * ncol;
  NumericMatrix Res(nrow,ncol);
  NumericVector Rands  = runif(N);
   for (int i = 0; i < N; i++) 
  {
    Res[i] = Rands[i];
  }
  return(Res);
 }',

code = '
void foo()
{
  // This is the relevant part, I create a list then update it and print the results:
  List x;
  for (int i=0; i<10; i++)  
  {
   x[i] = RandMat(100,10);
   Rf_PrintValue(wrap(x[i]));
  }
}
')


foo()
Run Code Online (Sandbox Code Playgroud)

有没有人知道这样做的方法而不会崩溃R?我想我可以在这里以固定数量的元素启动列表,但在我的应用程序中,元素的数量是随机的.

Rom*_*ois 6

您必须为列表"分配"足够的空间.也许你可以使用类似resize函数的东西:

List resize( const List& x, int n ){
    int oldsize = x.size() ;
    List y(n) ;
    for( int i=0; i<oldsize; i++) y[i] = x[i] ;
    return y ;
}
Run Code Online (Sandbox Code Playgroud)

并且只要您希望列表比现在更大,您就可以:

x = resize( x, n ) ;
Run Code Online (Sandbox Code Playgroud)

您的初始列表大小为0,因此预计在循环的第一次迭代时会出现不可预测的行为.

  • 您还可以执行诸如“x.push_back(newElement)”之类的操作,但通常需要注意的是,它会在下面执行完整的复制。这些实际上是下面的向量,您*必须*首先预留空间。或者,增加 STL 数据类型(他们在这方面做得更好)并在返回之前转换为 R / Rcpp 类型。 (2认同)