Skip to content

[Rcpp-devel] Initialize a matrix with a vector and the dimensions

3 messages · Peng Yu, Davor Cubranic

#
Hi,

The closest thing that I can find to initialize a NumericMatrix with a
NumericVector is the following constructor from Rcpp/vector/Matrix.h.
But I need to see an example on how to use it. Does anybody have any
example to share with me? Thanks!

    template <typename Iterator>
    Matrix( const int& nrows_, const int& ncols, Iterator start ) :
#
On Tue, Aug 28, 2012 at 4:17 PM, Peng Yu <pengyu.ut at gmail.com> wrote:
Just to clarify my original question, I want to convert from native R
vector to matrix directly (not through NumericVector). The following
code involves NumericVector. Does it result in extra copying of a
NumericVector?
+   , body='
+   Rcpp::NumericVector v(mx);
+   Rcpp::NumericMatrix mat(2, 3, v.begin());
+   return mat;
+   '
+   , plugin='Rcpp'
+   )
[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
#
On 12-08-28 02:23 PM, Peng Yu wrote:
> Just to clarify my original question, I want to convert from native R
 > vector to matrix directly (not through NumericVector). The following
 > code involves NumericVector. Does it result in extra copying of a
 > NumericVector?
 >
 >> suppressPackageStartupMessages(library(inline))
 >> fun=cxxfunction(signature(mx='numeric')
 > +   , body='
 > +   Rcpp::NumericVector v(mx);
 > +   Rcpp::NumericMatrix mat(2, 3, v.begin());
 > +   return mat;
 > +   '
 > +   , plugin='Rcpp'
 > +   )

As I understand it, 'v' will be just a wrapper around mx that gives you 
a C++ type. No copying of actual contents will happen. (As an aside, not 
making v a 'const' will let you change the original argument to the 
function, something that will cause you no end of trouble if you 
accidentally do it. You should always make the wrappers around the 
argument SEXPs 'const's.)

I don't know whether constructing the 'mat' NumericMatrix entails a 
copy, though. I think that it does, because that constructor's source is 
as follows (see vector/Matrix.h):

    Matrix( const int& nrows_, const int& ncols, Iterator start ) :
         VECTOR( start, start + (nrows_*ncols) ),
         nrows(nrows_)
     {
         VECTOR::attr( "dim" ) = Dimension( nrows, ncols ) ;
     }

So this delegates to Vector(InputIterator, InputIterator) and then sets 
the dimension attribute on the matrix object. The Vector call ends up in:

     void assign( InputIterator first, InputIterator last){
         /* FIXME: we can do better than this r_cast to avoid
            allocating an unnecessary temporary object
         */
         SEXP x = PROTECT( r_cast<RTYPE>( wrap( first, last ) ) );
         RObject::setSEXP( x) ;
         UNPROTECT(1) ;
     }

Somebody with a better understanding of R internals will have to comment 
on whether this causes a memory allocation. I think it does, but don't 
know for sure.

I'm curious why you can't do the conversion to matrix on the R side, 
just prior to the .Call.

Davor