[Rcpp-devel] Filling NumericMatrix with NumericVectors with apply by row/column?

Romain Francois romain at r-enthusiasts.com
Tue Sep 21 11:20:11 CEST 2010


Le 21/09/10 10:57, Christian Gunning a écrit :
> On Tue, Sep 7, 2010 at 11:40 PM, Romain Francois
> <romain at r-enthusiasts.com>  wrote:
>>>
>>> In the first case, could I conceivably turn an input 3D SEXP array
>>> into, e.g., NumericVector( Dimension(2,3,4) ), create an arma::cube
>>> out of it, process it and return?
>>
>> I think so. I have not tried though ... have you ?
>
> Here we go - it works under certain circumstances:
>
> fx_flat<- cxxfunction( signature(x = "integer", y = "array" ) ,
>    '
>      NumericVector ret(Dimension(2,2,2));
>      ret = NumericVector(y);
>      ret = ret * as<int>(x);  // this "squishes" ret back to 1D
>      return ret;
>    ', plugin = "RcppArmadillo" )

Ah. We should implement NumericVector::operator*= etc ...

You can always attach dimensions later:

ret.attr( "dim" ) = Dimension( 2, 2, 2) ;

I'll try to think of some ways to keep the dimensions. Perhaps we do 
need some sort of Rcpp::Array class


>> fx_flat( 2L, array(1:8, dim=c(2,2,2)) )
> [1]  2  4  6  8 10 12 14 16
>
> fx_cube<- cxxfunction( signature(x = "integer", y = "array" ) ,
>    '
>        // note - NumericVector ret(y) is flat
>      NumericVector ret(Dimension(2,2,2));
>        // use copy constructor to keep dimension
>      ret = NumericVector(y);
>        // copy_aux_mem = false is the only way to return retcube?
>      arma::cube retcube(ret.begin(), 2, 2, 2, false);
>      retcube = retcube * as<int>(x);
>      return ret;
>    ', plugin = "RcppArmadillo" )
>
>> fx_cube( 2L, array(1:8, dim=c(2,2,2)) )
> , , 1
>       [,1] [,2]
> [1,]    2    6
> [2,]    4    8
> , , 2
>       [,1] [,2]
> [1,]   10   14
> [2,]   12   16

Yes. Armadillo has a separate class for cubes, which makes all this 
work. That's why I think we need Rcpp::Array too.

> A few points stand out to me -
>
> * If i'm not doing pointer-magic and/or only using Rcpp/Armadillo
> operators, is copy_aux_mem = false a reasonable way to return retcube
> after processing?  I don't see any other way to get an SEXP out of an
> arma::cube, but i'm skeptical of "can be dangerous unless you know",
> since i don't.

I think this is fine. You essentially tell armadillo that the memory is 
yours and no to mess with it, it won't.

You can however Rcpp::wrap a cube. It is safer because the memory gets 
copied, but less efficient, because the memory is copied.

> * It seems to me that row/column/slice indexer semantics, rather than
> linearArray[ thisrow + thiscol*(ncol-1) ] semantics (which i always
> seem to mess up) is one reason these mailing list questions about
> arrays keep popping up.

Sure. I need to think a little bit more about how to do Rcpp::Array, etc 
... because an Array could have an arbitrary number of dimensions.
Perhaps embedding information into the class would work.

// make an array of 3 dimensions, etc ...
Rcpp::Array<3> ret( y ) ;

I have very little time to devote to this right now.

> * What about "ret = ret * as<int>(x);" causes ret to lose it's dimension?

Omission, lack of time, I'm not using arrays all that much personally, 
etc ...

> best,
> Christian


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/cCmbgg : Rcpp 0.8.6
|- http://bit.ly/bzoWrs : Rcpp svn revision 2000
`- http://bit.ly/b8VNE2 : Rcpp at LondonR, oct 5th




More information about the Rcpp-devel mailing list