3

I checked many examples about how to pass by reference using Rcpp. I see for instance this very great. However I have one question. Suppose that I have a matrix as an object in R and I want to add 1 to the entry [1,1]. The examples i saw work if the matrix is in Cpp but i want to return the update in R without using return statement.

This is an example i did with a list and it works very well

//[[Rcpp::export]]
void test(List& a){
 a(0)=0;
}

I need to do similarely with a matrix. something like :

//[[Rcpp::export]]
 void test(arma::mat& a){
  a(0,0)=0;
 }

The second does not update my matrix in R but updates the list.

Can anyone help me ?

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
Ari.stat
  • 463
  • 4
  • 13
  • 1
    I could probably help you but I need to see the matrix you pass to `test`. Can you edit? – F. Privé Sep 07 '17 at 06:03
  • Every function in R has a return value. You can of course return an invisible `NULL` is desired. However, it would be more sensible to return the matrix invisibly. – Roland Sep 07 '17 at 06:50
  • Thanks you Privé and Roland. Help me with any matrix. Let's suppose that I have a matrix 2*2 and i want to change the value [1,1] without using return statement. In fact, i want to use the solution in a more complicate case. My function takes 2 lists and 3 matrix and returns the same objects after updating. For now, i put the updates in a list (so i built a list of 5) and i return the list. But the list is very heavy because it contains large matrix and lists. Thus i want to pass by reference and update the objects without building a list of them as return variable. – Ari.stat Sep 07 '17 at 13:55

1 Answers1

3

Let's start by reiterating that this is probably bad practice. Don't use void, return your changed object -- a more common approach.

That said, you can make it work in either way. For RcppArmadillo, pass by (explicit) reference. I get the desired behaviour

> sourceCpp("/tmp/so.cpp")

> M1 <- M2 <- matrix(0, 2, 2)

> bar(M1)

> M1
     [,1] [,2]
[1,]   42    0
[2,]    0    0

> foo(M2)

> M2
     [,1] [,2]
[1,]   42    0
[2,]    0    0
> 

out of this short example:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
void bar(Rcpp::NumericMatrix M) {
  M(0,0) = 42;
}

// [[Rcpp::export]]
void foo(arma::mat M) {
  M(0,0) = 42;
}

/*** R
M1 <- M2 <- matrix(0, 2, 2)

bar(M1)
M1

foo(M2)
M2
*/
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Thank you Sir! I get it and it works very well. In fact i want to use the solution in a more complicate case where there are many large matrix to update. One solution is to put the updates in a list and return the list. I did that but the returned list is very heavy because it contains many large matrix and another lists. So i want to pass by reference the lists and the matrix and update them. Else is there another way to return many object without putting them together (as in a tuple or a list) ? – Ari.stat Sep 07 '17 at 14:05
  • Welcome to StackOverflow. When an answer addresses the question you posed, it is common courtesy to "accept" the question (click on the tick-mark) and/or "up-vote" the question (click on the up-triangle). – Dirk Eddelbuettel Sep 07 '17 at 14:07
  • Thank you. I accepted the answer. I did not know but i know i can up-vote. It seems that I can not up vote for the moment. I have not 15 reputations. For my last question, is it necessary to create another post for that ? Thank you again – Ari.stat Sep 07 '17 at 14:12
  • "It depends" Sometimes it makes sense to edit an original question, sometimes a new one is better. Here I encourage to _experiment_ and _measure_ (ie profile) and based on that ask a new question. – Dirk Eddelbuettel Sep 07 '17 at 14:16
  • Thank you very much – Ari.stat Sep 07 '17 at 14:18