Rcpp 和 R:通过引用传递

Rcpp and R: pass by reference

在使用 Rcpp 和 RI 时,我观察到以下行为,目前我还不明白。考虑以下用 Rcpp

编写的简单函数
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix hadamard_product(NumericMatrix & X, NumericMatrix & Y){
   unsigned int ncol = X.ncol();
   unsigned int nrow = X.nrow();
   int counter = 0;
   for (unsigned int j=0; j<ncol; j++) {
     for (unsigned int i=0; i<nrow; i++)  {
        X[counter++] *= Y(i, j);
     }
   }
   return X;
}

这只是 returns 两个矩阵的分量乘积。现在我知道这个函数的参数是通过引用传递的,即调用

M <- matrix(rnorm(4), ncol = 2)
N <- matrix(rnorm(4), ncol = 2)
M_copy <- M
hadamard_product(M, N)

会覆盖原来的M。但是,它也会覆盖M_copy,我不明白。我认为 M_copy <- M 复制了对象 M 并将其保存在内存中的某个位置,而不是这个赋值指向 M_copy 到 M,这将是执行

时的行为
x <- 1
y <- x
x <- 2

例如。这不会改变 y 而只会改变 x。

那么为什么会出现上述行为呢?

不,R 不会立即复制,只有在必要时才会复制,即 copy-on-modify:

x <- 1
tracemem(x)
#[1] "<0000000009A57D78>"
y <- x
tracemem(x)
#[1] "<0000000009A57D78>"
x <- 2
tracemem(x)
#[1] "<00000000099E9900>"

由于您在R 之外通过引用修改了M,因此R 不知道需要一个副本。如果要确保复制,可以使用 data.table::copy。或者避免 C++ 代码中的副作用,例如,在那里进行深拷贝(通过使用 clone)。