Hi Jouni, On 22 September 2016 at 19:39, Helske, Jouni wrote: | Hi, | | I was recently hunting down a bug in my code, and stumbled upon a slightly | incoherent behaviour in Rcpp/RcppArmadillo. In my real application I have a | class which data members are initialized in initialization list from the Rcpp | List using as<arma::cube>. For example, I have a member y which I initialize by | y(as<arma::cube>(xlist["y"])). This caused some headaches if I later modified | data member y, as the y in the list on R side was modified as well. I then | realized that I need to use Rcpp::clone in order to make a deep copy of xlist | object. But, this does not need to be done when initializing arma::vec or | arma::mat. Is this purposeful or am I missing something?
arma::vec and arma::mat went through a few iterations and now use the 'advanced constructors' (see arma docs) in what we think is the correct way. | Simple example: | | void test1(const NumericVector& x) { | arma::cube ycube(as<arma::cube>(x)); | ycube(0) = 0.5; | } | | > y <- array(1:4, c(2,2,1)) #y is integer type, using automatic copy | > test1(y) | > y | , , 1 | | [,1] [,2] | [1,] 1 3 | [2,] 2 4 | | > y <- array(as.numeric(1:4), c(2,2,1)) #y is numeric, no copy | > test1(y) | > y | , , 1 | | [,1] [,2] | [1,] 0.5 3 | [2,] 2.0 4 The copy due to the casting is unavoidable. The non-copy on numeric is on purpose. | But in case of arma::vec (or arma::mat), copying is always done: | | void test2(const NumericVector& x) { | arma::vec yvec(as<arma::vec>(x)); | yvec(0) = 0.5; | } But here you force the copy by using NumericVector and using as<>. That was an older access pattern. Try void test2(const arma::vec & x) { x(0) = 0.5; } This is now a proxy object so the 'outside value' should be changed too: R> cppFunction("void test2(arma::vec & x) { x(0) = 0.5; }", R> depends="RcppArmadillo") R> v <- sqrt(9:16) R> v [1] 3.00000 3.16228 3.31662 3.46410 3.60555 3.74166 3.87298 4.00000 R> test2(v) R> v [1] 0.50000 3.16228 3.31662 3.46410 3.60555 3.74166 3.87298 4.00000 R> | > y <- as.numeric(1:8) | > test2(y) | > y | [1] 1 2 3 4 5 6 7 8 You are such a long-time user that you may have stuck with as<>() for too long here :) We can now do better. Hope this helps, Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel