Another way is to leverage our RCPP_RETURN_VECTOR macro, and use it with a functor instead of a function. The idea is to encapsulate the information (nrow and ncol) in the functor class:

#include <Rcpp.h>
using namespace Rcpp ;

class Vec2Matrix {
public:
    Vec2Matrix(int nrow_, int ncol_): nrow(nrow_), ncol(ncol_){}

    template <int RTYPE>
    Matrix<RTYPE> operator()( Vector<RTYPE> x){
        return Matrix<RTYPE>(nrow, ncol, x.begin());
    }

private:
    int nrow, ncol ;
} ;

// [[Rcpp::export]]
SEXP vec2matrix(SEXP x, int nrow, int ncol){
    Vec2Matrix transformer(nrow, ncol) ;
    RCPP_RETURN_VECTOR( transformer, x) ;
}


/*** R
    vec2matrix( 1:10, 2, 5 )
    vec2matrix( rnorm(10), 2, 5 )
***/

Romain


Le 31/05/13 11:37, Romain Francois a écrit :
Ah ok, so you want to use this from R, I would suggest to Rcpp::export a
dispatcher, something like this:

#include <Rcpp.h>
using namespace Rcpp ;

// the template
template <int RTYPE>
Matrix<RTYPE> vec2matrix__impl(Vector<RTYPE> x, int nrow, int ncol) {
   return Matrix<RTYPE>(nrow, ncol, x.begin());
}

// the exported dispatcher,used from R
// [[Rcpp::export]]
SEXP vec2matrix(SEXP x, int nrow, int ncol){
     switch( TYPEOF(x) ){
         case REALSXP: return vec2matrix__impl( NumericVector(x), nrow,
ncol ) ;
         case INTSXP:  return vec2matrix__impl( IntegerVector(x), nrow,
ncol ) ;
         // ... add other cases you want to handle
     default:
         return R_NilValue ;
         // .. or do whatever
     }
}


/*** R
     vec2matrix( 1:10, 2, 5 )
     vec2matrix( rnorm(10), 2, 5 )
***/

Romain


Le 31/05/13 11:30, Søren Højsgaard a écrit :
Romain,

I actually already tried this in my file util.cpp but can't get it to
work:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix vec2matrix(NumericVector x, int nrow, int ncol) {
   return NumericMatrix(nrow, ncol, x.begin());
}

// [[Rcpp::export]]
template <int RTYPE>
Matrix<RTYPE> vec2matrix2(Vector<RTYPE> x, int nrow, int ncol) {
   return Matrix<RTYPE>(nrow, ncol, x.begin());
}

Any thoughts?

Don't Rcpp::export templates.


Søren



Rcpp::sourceCpp('./util.cpp')
g++ -m64 -I"C:/programs/R/current/include" -DNDEBUG
-I"C:/programs/R/current/library/Rcpp/include"
-I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall
-mtune=core2 -c util.cpp -o util.o util.cpp: In function 'SEXPREC*
sourceCpp_50379_vec2matrix2(SEXP, SEXP, SEXP)': util.cpp:75:12: error:
'RTYPE' was not declared in this scope util.cpp:75:17: error: template
argument 1 is invalid util.cpp:75:21: error: invalid type in
declaration before '=' token util.cpp:75:44: error: could not convert
template argument 'RTYPE' to 'int' util.cpp:75:53: error: no matching
function for call to 'as(SEXPREC*&)' util.cpp:75:53: note: candidate
is: C:/programs/R/current/library/Rcpp/include/Rcpp/as.h:125:29: note:
template<class T> T Rcpp::as(SEXP) util.cpp:78:5: error: a template
declaration cannot appear at block scope util.cpp:79:5: error:
expected ';' before 'return' util.cpp:75:19: warning: unused variable
'x' [-Wunused-variable] util.cpp:76:9: warning: unused variable 'nro
w' [-Wunu
sed-variable] util.cpp:77:9: warning: unused variable 'ncol'
[-Wunused-variable] make: *** [util.o] Error 1
Error in Rcpp::sourceCpp("./util.cpp") :
   Error 1 occurred building shared library.






-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of
Romain Francois
Sent: 31. maj 2013 11:22
To: [email protected]
Subject: Re: [Rcpp-devel] Turning a vector into a matrix

Hello Søren,

This is easy templating:

template <int RTYPE>
Matrix<RTYPE> vec2matrix(Vector<RTYPE> x, int nrow, int ncol) {
    return Matrix<RTYPE>(nrow, ncol, x.begin()); }

will work for NumericVector, IntegerVector, CharacterVector, ...

Romain

Le 31/05/13 11:08, Søren Højsgaard a écrit :
Dear all,

Dirk: Thanks for the reply :).

I shall dare to ask a "bonus question": I've played around with
templating so that I get the right output type. I know (thanks to an
earlier reply by Romain) how to do so using SEXP's but if I am
constructing a utility function to be used on c++ objects, I can't
that to work. What I am after should mimic the following such that
the output type is determined by the input type:

NumericMatrix vec2matrix(NumericVector x, int nrow, int ncol) {
    return NumericMatrix(nrow, ncol, x.begin()); }

IntegerMatrix vec2matrix(IntegerVector x, int nrow, int ncol) {
    return IntegerMatrix(nrow, ncol, x.begin()); }

Any help would be more than welcome.

Best regards
Søren





-----Original Message-----
From: Dirk Eddelbuettel [mailto:[email protected]]
Sent: 31. maj 2013 03:01
To: Søren Højsgaard
Cc: [email protected]
Subject: Re: [Rcpp-devel] Turning a vector into a matrix


Soren,

You missed the most appropriate constructor:

      template <typename Iterator>
      Matrix( const int& nrows_, const int& ncols, Iterator start ) ;

With that we just do this:

    R> Rcpp::sourceCpp('/tmp/soren.cpp')
    R> soren(1:4,2,2)
         [,1] [,2]
    [1,]    1    3
    [2,]    2    4
    R>

and the file soren.cpp is below.

Dirk


#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix soren(NumericVector x, int n, int k) {
    return NumericMatrix(n, k, x.begin()); }




--
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
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to