Hi Romain,

I considered the implicit use of Rcpp::as<>() inside of the arma::mat() 
constructor. My target was to reuse memory and try to use a very simple 
setting, i.e. (at least in my opinion) not too much lines of code. 

You answered to my question

"On the other side I then assume, that the Rcpp:as<class M>() function makes a 
cast and therefore creates a copy with new allocated memory of the type 
included in M? Therefore a reuse of memory with this function is not possible":

Depends what is M, but most of the time yes, as<> copies data.

What I then tried, was this:

setClass("myclass", representation(par = "list"))
l <- list(lambda = array(0, dim = c(10,2)))
mclass <- new("myclass", par = l)
cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4 
myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat 
armaPar(Rcpp::as<Rcpp::NumericMatrix>(parL["lambda"]).begin(), 10, 2, false, 
true); armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);', plugin = 
"RcppArmadillo")
cfunction(mclass)
An object of class "myclass"
Slot "par":
$lambda
      [,1] [,2]
 [1,]  1.2    0
 [2,]  0.0    0
 [3,]  0.0    0
 [4,]  0.0    0
 [5,]  0.0    0
 [6,]  0.0    0
 [7,]  0.0    0
 [8,]  0.0    0
 [9,]  0.0    0
[10,]  0.0    0

So, it seems, that calling Rcpp::as<>() implicitly inside the arma::mat() 
constructor, enables the reuse of memory with only a few lines of code, which 
is pretty nice. So in case of M being Rcpp::NumericMatrix, Rcpp::as<>() seems 
not to copy data. But it also could be, that I misunderstood your answer above, 
or that we were talking about two different things there. In this case please 
apologize my confusion.


Best

Simon


On Jun 8, 2013, at 8:08 AM, Romain Francois <rom...@r-enthusiasts.com> wrote:

> Le 07/06/13 16:07, Simon Zehnder a écrit :
>> Hi Romain,
>> 
>> thanks for this precise answer. So the suggested methods below will work 
>> without making a copy of the object.
> 
> yes
> 
>> What is about the implicit call of Rcpp::as<>() inside arma::mat()? It is a 
>> very convenient way to create an arma object reusing memory and it seems to 
>> work just fine.
> 
> I don't know what you are talking about.
> 
>> Best
>> 
>> Simon
>> On Jun 7, 2013, at 3:47 PM, Romain Francois <rom...@r-enthusiasts.com> wrote:
>> 
>>> Le 07/06/13 15:14, Simon Zehnder a écrit :
>>>> Hi Romain, hi Dirk,
>>>> 
>>>> sorry for posting here again, but I found something in some way connected 
>>>> to this discussion - and pretty interesting concerning the Rcpp::as<>() 
>>>> function:
>>>> 
>>>> 1. I create a class containing a list:
>>>> 
>>>> setClass("myclass", representation(par = "list"))
>>>> 
>>>> l <- list(lambda = array(0, dim = c(10,2)))
>>>> 
>>>> mclass <- new("myclass", par = l)
>>>> 
>>>> 2. I compile a C++ function, that should reuse the memory of 'lambda' 
>>>> inside the list:
>>>> 
>>>> library(inline)
>>>> cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4 
>>>> myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat 
>>>> armaPar(parL["lambda"].begin(), 10, 2, false, true); armaPar(0,0) = 1.2 
>>>> ;return Rcpp::wrap(myclass);', plugin = "RcppArmadillo")
>>>> 
>>>> I get an error:
>>>> 
>>>> Error in compileCode(f, code, language = language, verbose = verbose) :
>>>>   Compilation ERROR, function(s)/method(s) not created! 
>>>> file6fc2ab39965.cpp: In function ‘SEXPREC* file6fc2ab39965(SEXP)’:
>>>> file6fc2ab39965.cpp:30:109: error: ‘Rcpp::Vector<19>::NameProxy’ has no 
>>>> member named ‘begin’
>>>>  Rcpp::S4 myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); 
>>>> arma::umat armaPar(parL["lambda"].begin(), 100, 10, false, true); 
>>>> armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);
>>> 
>>> What you get from doing parL["lambda"] is an object of class NameProxy, it 
>>> will be converted to the appropioate class later. NameProxy have no .begin 
>>> method.
>>> 
>>> Do this:
>>> 
>>> NumericVector tmp = parL["lambda"] ;
>>> arma::mat armaPar(tmp.begin(), 10, 2, false, true);
>>> 
>>> This will not make copies of the data.
>>> 
>>> If thius feels like too much to type, just stuff this into a function:
>>> 
>>> inline arma::mat convert( SEXP x ){
>>>   NumericVector tmp = parL["lambda"] ;
>>>   return arma::mat(tmp.begin(), 10, 2, false, true);
>>> }
>>> 
>>> and call :
>>> 
>>> arma::mat armaPar = convert( parL["lambda"] ) ;
>>> 
>>> There is a chance convert won't make a copy thanks to RVO.
>>>                              ^
>>>> make: *** [file6fc2ab39965.o] Error 1
>>>> In addition: Warning message:
>>>> running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB 
>>>> file6fc2ab39965.cpp 2> file6fc2ab39965.cpp.err.txt' had status 1
>>>> 
>>>> -----------------------------------------------------------
>>>> 
>>>> It seems, that the SEXP inside the List is not yet an Rcpp::NumericMatrix, 
>>>> so I make it explicit to the arma::mat() constructor:
>>>> 
>>>> cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4 
>>>> myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat 
>>>> armaPar(Rcpp::as<Rcpp::NumericMatrix>(parL["lambda"]).begin(), 100, 10, 
>>>> false, true); armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);', plugin = 
>>>> "RcppArmadillo")
>>>> 
>>>> That compiles.
>>>> 
>>>> If we let it run it gives us:
>>>> 
>>>> cfunction(mclass)
>>>> An object of class "myclass"
>>>> Slot "par":
>>>> $lambda
>>>>       [,1] [,2]
>>>>  [1,]  1.2    0
>>>>  [2,]  0.0    0
>>>>  [3,]  0.0    0
>>>>  [4,]  0.0    0
>>>>  [5,]  0.0    0
>>>>  [6,]  0.0    0
>>>>  [7,]  0.0    0
>>>>  [8,]  0.0    0
>>>>  [9,]  0.0    0
>>>> [10,]  0.0    0
>>>> 
>>>> So, we can see, that implicitly calling Rcpp::as<>() inside the 
>>>> constructor arma::mat() avoids a copy by Rcpp::as<>() - which is just 
>>>> beautiful!
>>>> 
>>>> 
>>>> Best
>>>> 
>>>> Simon
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On Jun 7, 2013, at 1:19 PM, Simon Zehnder <szehn...@uni-bonn.de> wrote:
>>>> 
>>>>> Thank you Romain!
>>>>> 
>>>>> All clear now!
>>>>> 
>>>>> 
>>>>> Best
>>>>> 
>>>>> Simon
>>>>> 
>>>>> On Jun 7, 2013, at 1:13 PM, Romain Francois <rom...@r-enthusiasts.com> 
>>>>> wrote:
>>>>> 
>>>>>> Le 07/06/13 13:09, Simon Zehnder a écrit :
>>>>>>> HI Dirk, hi Romain,
>>>>>>> 
>>>>>>> allright, this is now clear to me, if I want to reuse memory, the 
>>>>>>> allocated memory from R (so implicitly in C) must of course have the 
>>>>>>> same type - otherwise the memory has a different size.
>>>>>> 
>>>>>> so far, this is obvious.
>>>>>> 
>>>>>>> On the other side I then assume, that the Rcpp:as<class M>() function 
>>>>>>> makes a cast and therefore creates a copy with new allocated memory of 
>>>>>>> the type included in M? Therefore a reuse of memory with this function 
>>>>>>> is not possible.
>>>>>> 
>>>>>> Depends what is M, but most of the time yes, as<> copies data.
>>>>>> 
>>>>>>> Best
>>>>>>> 
>>>>>>> Simon
>>>>>>> 
>>>>>>> 
>>>>>>> On Jun 6, 2013, at 8:31 PM, Dirk Eddelbuettel <e...@debian.org> wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> On 6 June 2013 at 13:17, Dirk Eddelbuettel wrote:
>>>>>>>> |
>>>>>>>> | On 6 June 2013 at 19:05, Simon Zehnder wrote:
>>>>>>>> | | sorry I had overseen this message from you. Okay, so the explicit 
>>>>>>>> cast to SEXP together with the assignment operator makes the deal. But 
>>>>>>>> it still includes the reuse of memory right, i.e. the '=' does not 
>>>>>>>> call the copy constructor?
>>>>>>>> |
>>>>>>>> | But how could an _unsigned int_ from Armadillo possibly have the 
>>>>>>>> same value
>>>>>>>> | as a _signed int_ in R?
>>>>>>>> |
>>>>>>>> | Either you are efficient (no copy), or you are correct (with a 
>>>>>>>> copy). I do
>>>>>>>> | not see how you could have both.
>>>>>>>> 
>>>>>>>> Sorry -- please ignore this message.
>>>>>>>> 
>>>>>>>> I had mistakenly assumed that you were still thinking about arma::umat 
>>>>>>>> to
>>>>>>>> integer.  For direct int-to-int this is indeed efficient just like the
>>>>>>>> double-to-double is for arma::mat to NumericMatrix (and dito for 
>>>>>>>> vectors).  I
>>>>>>>> though that was a given -- maybe need to make this (even) more 
>>>>>>>> explicit in
>>>>>>>> the documentation.
>>>>>>>> 
>>>>>>>> So in sum: you get correct and efficient behaviour if and only if you 
>>>>>>>> stick
>>>>>>>> with the types natively supported in Armadillo and R.
>>>>>>>> 
>>>>>>>> Dirk
>>>>>>>> 
> 
> 
> -- 
> Romain Francois
> Professional R Enthusiast
> +33(0) 6 28 91 30 30
> 
> R Graph Gallery: http://gallery.r-enthusiasts.com
> 
> blog:            http://blog.r-enthusiasts.com
> |- http://bit.ly/Zs97qg  : highlight 0.4.1
> `- http://bit.ly/10X94UM : Mobile version of the graph gallery
> 

_______________________________________________
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

Reply via email to