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