Convert std::vector to Rcpp matrix

后端 未结 2 1755
南笙
南笙 2020-12-31 05:48

This is an Rcpp conversion related Q. I\'m looking to convert a long std::vector into a Rcpp matrix object, but want to know if there is an easy conversion format. Naturally

相关标签:
2条回答
  • 2020-12-31 06:09

    You chose a good approach. In the OpenMP context, you have to stay away from the single-threaded R. So std::vector is good.

    And yes, we have constructors from std::vector to Rcpp::NumericVector and Rcpp::NumericMatrix (which is after all just a vector with a dimensions attribute) as well as the Rcoo:Integer* variants, as well as the usual as<> and wrap converters.

    There should be plenty of examples in the Rcpp unit tests, the Rcpp examples, and of course on the Rcpp Gallery site.

    Edit: Here is an overly simple example:

     R> cppFunction('NumericVector phil(int n) { std::vector<double> x(n);
     +              return wrap(x); }') 
     R> phil(4)  
     [1] 0 0 0 0    
     R>    
    
    0 讨论(0)
  • 2020-12-31 06:25

    To expand on Dirk's answer; R matrices are really just vectors with a dim attribute set

    > x <- 1
    > y <- as.matrix(x)
    > .Internal( inspect(x) )
    @7f81a6c80568 14 REALSXP g0c1 [MARK,NAM(2)] (len=1, tl=0) 1 ## data
    > .Internal( inspect(y) )
    @7f81a3ea86c8 14 REALSXP g0c1 [NAM(2),ATT] (len=1, tl=0) 1 ## data
    ATTRIB:
      @7f81a3e68e08 02 LISTSXP g0c0 [] 
        TAG: @7f81a30013f8 01 SYMSXP g1c0 [MARK,LCK,gp=0x4000] "dim" (has value) 
        @7f81a3ea8668 13 INTSXP g0c1 [NAM(2)] (len=2, tl=0) 1,1
    

    Notice how the 'data' component of x and y are just REALSXPs, but you have this extra dim component on the matrix. Using this, we can easily convert a NumericVector to a matrix in Rcpp.

    (Note: in the example below, I use SEXP in the attributes just so the conversions between types are explicit):

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    SEXP vec_to_mat(SEXP x_) {
      std::vector<double> x = as< std::vector<double> >(x_);
      /* ... do something with x ... */
      NumericVector output = wrap(x);
      output.attr("dim") = Dimension(x.size(), 1);
      return output;
    }
    
    /*** R
    m <- c(1, 2, 3)
    vec_to_mat(m)
    */
    

    gives me

    > m <- c(1, 2, 3)
    
    > vec_to_mat(m)
         [,1]
    [1,]    1
    [2,]    2
    [3,]    3
    

    So, you can use the Dimension class and assign it to the dim attribute of a vector to make a matrix 'by hand' in Rcpp.

    0 讨论(0)
提交回复
热议问题