创建Rcpp矩阵列表

时间:2018-05-17 06:22:03

标签: r rcpp

我想创建一个矩阵列表,我在循环中更新并将其返回给R.我有

std::vector<IntegerMatrix> zb_list;

IntegerMatrix tb(J,nmax), zb(J,nmax);
在循环之前

。在循环内部,我更新zb,然后

zb_list.push_back(zb);

我也有

Rcout <<  (zb_list[itr]) << "\n";
Rcout <<  (zb) << "\n\n";

其中itr计算迭代次数。这两个都确认zb正在循环中发生变化,而zb_list会跟踪它。

然后我在循环后返回zb_list。在R中访问结果时,列表包含相同zb的副本,这是循环中计算的最后一个副本。我怀疑有一些参考传递继续...但无法弄明白。我对正在发生的事情没有很好的理解(试图在没有运气的情况下使用return(wrap(zb_list))),但显然有些不对劲。还使用List zb_list;来定义它没有帮助。有什么建议吗?

EDiT:这是最小的工作示例:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List test_weird(int ITRmax=2) {

  IntegerMatrix  zb(2,2);
  std::vector<IntegerMatrix> zb_list;

  int itr = 0;
  while (itr < ITRmax) {

   zb( (1+itr)%2 ,(1+itr)%2 ) ++ ;
   zb_list.push_back(zb);


   Rcout << (zb) <<   (zb_list[itr]) << "\n\n";
    ++itr; 
  }

  return List::create(_["zb"] = zb,
                      _["zb_list"] = zb_list);
}


/*** R
res <- test_weird()
res$zb_list
*/

外观运行时的输出:

0 0
0 1
0 0
0 1


1 0
0 1
1 0
0 1

...这是R:

的输出
> res$zb_list
[[1]]
     [,1] [,2]
[1,]    1    0
[2,]    0    1

[[2]]
     [,1] [,2]
[1,]    1    0
[2,]    0    1

正如您所看到的,列表中的两个项目都是循环中的最后一个zb

1 个答案:

答案 0 :(得分:1)

问题是push_back(something)制作了something的副本。但是如果something是指针,则后续更改将影响该指针的所有副本。在普通的C ++中:

#include <vector>
#include <iostream>

int main() {
  std::vector<int*> v;
  int* p = new int; 
  for (int i = 0; i < 2; ++i) {
    *p = i;
    v.push_back(p);
    std::cout << *p << " " << *v[i] << std::endl;
  }
  std::cout << *v[0] << " " << *v[1] << std::endl;
  return 0;
}

产生

$ ./pointer_fun 
0 0
1 1
1 1

因此,如果something是一个指针(如对象),这是所有Rcpp对象的情况,那么你需要对象的深层复制/克隆,即

zb_list.push_back(clone(zb));