Hi Romain,

thanks for this precise answer. So the suggested methods below will work 
without making a copy of the object. 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. 



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
>>>>>> 
>>>>>> --
>>>>>> Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>> --
>>>> 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
>> 
>> 
> 
> 
> -- 
> 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