Question

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, you could loop over each element and fill an empty Rcpp matrix, but this seems error prone and possibly needless if a more convenient approach is possible.

The reason I'm asking is I would like to utilize OpenMP in some existing C++ code, but storing element in the Rcpp matrix object directly in an OpenMP loop doesn't appear to work well (whereas loading a std::vector object and converting to a matrix after the OpenMP loop is complete seems to be a decent approach to the problem).

Any help would be greatly appreciated!

Was it helpful?

Solution 2

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>    

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top