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) << "nn";

其中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]) << "nn";
++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

问题是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));

最新更新