I have a NumericMatrix whose values are updated every iteration of a loop. I want to store the matrix in a List every iteration. The code below gives a minimal reproducible example. However, when I compile and run this in R, every element of the list is identical to the final matrix, rather than storing each matrix. Why would this be the case, and how can I fix it? This seems like a very simple problem, but I haven't been able to find a solution.
Example code:
#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)
*/
Example output:
> 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
CodePudding user response:
Welcome to StackOverflow, and what a gnarly question :) After a few years with R you become familiar with the 'copy-on-write' idiom. What you have here is, really, just one instance of the matrix so what you back is consequently always the same. As it is the same matrix. And that is, come to think (a bit) about it, a feature.
What you want here is so 'seal' the matrix value away. So all we need to change is one line:
// store a deep copy of mat
list(j) = clone(mat);
By requesting deep copies at each loop run you actually get distinct instances as you desire.
Output
> 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
>