Rcpp中动态更新的列表仅存储最后一个值

wkyowqbh  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(114)

我有一个NumericMatrix,它的值在循环的每次迭代中都会更新。我想在每次迭代中将矩阵存储在List中。下面的代码给出了一个最小可重复的例子。然而,当我在R中编译和运行它时,列表的每个元素都与最终矩阵相同,而不是存储每个矩阵。为什么会这样,我如何修复它?这似乎是一个很简单的问题,但我还没能找到解决办法。
范例程式码:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List updatingList(int n) {
  // Create a NumericMatrix that will be updated every step
  NumericMatrix mat(n, 2);
  for (int i=0; i < n; i++) { // set the initial state of the susceptible hosts
    mat(i,0) = 0; // initial Th1 
    mat(i,1) = 1; // initial Th2
  }
  // create a List that will store mat every step
  List list(n);
  
  for (int j=0; j < n; j++) {
    // store the value of mat
    list(j) = mat;
    // update mat
    for (int i=0; i < n; i++) { 
      mat(i,0) += 1; 
      mat(i,1) += 1; 
    }
  }
  return(list);  
}

/*** R
updatingList(3)
*/

字符串
输出示例:

> updatingList(3)
[[1]]
     [,1] [,2]
[1,]    3    4
[2,]    3    4
[3,]    3    4

[[2]]
     [,1] [,2]
[1,]    3    4
[2,]    3    4
[3,]    3    4

[[3]]
     [,1] [,2]
[1,]    3    4
[2,]    3    4
[3,]    3    4

hfwmuf9z

hfwmuf9z1#

在使用R语言几年之后,你会熟悉“写时复制”的习惯用法。你在这里所拥有的,实际上,只是矩阵的 * 一个 * 示例,因此你所支持的总是相同的。因为它是相同的矩阵。也就是说,来想想它,一个 * 特性 *。
这里你想要的是把矩阵值“密封”起来。所以我们只需要修改一行:

// store a deep copy of mat
    list(j) = clone(mat);

字符串
通过在每次循环运行时请求深度副本,您实际上可以获得所需的 distinct 示例。

输出

> Rcpp::sourceCpp("answer.cpp")

> updatingList(3)
[[1]]
     [,1] [,2]
[1,]    0    1
[2,]    0    1
[3,]    0    1

[[2]]
     [,1] [,2]
[1,]    1    2
[2,]    1    2
[3,]    1    2

[[3]]
     [,1] [,2]
[1,]    2    3
[2,]    2    3
[3,]    2    3

>

相关问题