2017-08-22 26 views
2

RcppとRとの作業次のような動作が観察されますが、現時点ではわかりません。これは、単に二つの行列の成分ごとの製品を返すRcppとR:参照渡し

#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; 
} 

Rcpp

で書かれた次の簡単な関数を考えてみましょう。今、私はこの関数の引数は、すなわち、しかし、元のM.が上書きされます

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

を呼び出し、参照渡しされていることを知って、それはまた、私は理解していないM_copyは、上書きされます。私はM_copy <- Mは、例えば

x <- 1 
y <- x 
x <- 2 

を実行したときの動作となりMへのこの割り当てポイントM_copy、そのオブジェクトMのコピーを作成し、どこかにメモリに保存していないと思いました。これはyを変更するのではなくxだけ変更します。

なぜ上記の動作が発生しますか?

+0

ああ、ありがとう、それは多くの助けになる! – jfiedler

+0

[cppFunctionに引数を渡す方法](https://stackoverflow.com/questions/41083921/how-arguments-are-passed-into-a-cppfunction)の可能な複製 – coatless

答えて

3

いいえ、Rは、すなわち、それが必要な場合にのみ、すぐにコピー・オン・変更コピーを作成しません:あなたはR外に参照することによってMを変更するので、Rはできない、

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

をコピーが必要であることを確認してください。コピーが確実に行われるようにするには、data.table::copyを使用できます。あるいは、C++コードの副作用を避けてください(例えば、cloneを使用して)。