Dear all, I am testing a simple C++ function that takes a double matrix as argument and which uses routines provided by the C++ Armadillo package. I am aware of the nice capabilities of Rcpp and RcppArmadillo which helps simplifying a lot and that I have already successfully tested. However, I had a hard time trying to figure out how the coercion from a REALSPX matrix to an arma::mat = arma::Mat<double> matrix (double matrix in Armadillo) is done. In this particular case, because of the simplicity of my function, I would like to use base R only. Since both, Armadillo and R matrix elements, are stored with column-major ordering I have tried the following silly example: #include <R.h> #include <Rdefines.h> #include <Rinternals.h> #include <Rmath.h> #include <R_ext/BLAS.h> #include <R_ext/Lapack.h> #include <armadillo> #define IDX(i,j,dim0) (i) + (j) * (dim0) extern "C" SEXP Symm(SEXP RA) { int m = INTEGER(GET_DIM(RA))[0]; int n = INTEGER(GET_DIM(RA))[1]; double *A; A = REAL(RA); arma::mat C(m, n), D(m, n); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) C[IDX(i, j, m)] = A[IDX(i, j, m)]; D = arma::symmatu(C); SEXP B = PROTECT(allocMatrix(REALSXP, m, n)); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) REAL(B)[IDX(i, j, m)] = D[IDX(i, j, m)]; UNPROTECT(1); return(B); } but it fails to compile: ~$ R CMD SHLIB example.cpp g++ -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c example.cpp -o example.o In file included from /usr/include/c++/4.9/fstream:40:0, from /usr/include/armadillo:21, from example.cpp:7: /usr/include/c++/4.9/bits/codecvt.h:215:45: error: macro "length" passed 4 arguments, but takes just 1 const extern_type* __end, size_t __max) const ^ In file included from /usr/include/c++/4.9/fstream:939:0, from /usr/include/armadillo:21, from example.cpp:7: /usr/include/c++/4.9/bits/fstream.tcc:826:60: error: macro "length" passed 4 arguments, but takes just 1 this->gptr() - this->eback()); ^ /usr/include/c++/4.9/bits/fstream.tcc:943:39: error: macro "length" passed 4 arguments, but takes just 1 this->gptr() - this->eback()); ^ In file included from /usr/include/c++/4.9/fstream:40:0, from /usr/include/armadillo:21, from example.cpp:7: /usr/include/c++/4.9/bits/codecvt.h:214:7: error: expected ?;? at end of member declaration length(state_type& __state, const extern_type* __from, ^ /usr/include/c++/4.9/bits/codecvt.h:216:7: error: expected unqualified-id before ?{? token { return this->do_length(__state, __from, __end, __max); } ^ /usr/lib/R/etc/Makeconf:137: recipe for target 'example.o' failed make: *** [example.o] Error 1 Many thanks for your help.
Dirk Eddelbuettel
2016-Jan-11 12:53 UTC
[Rd] coerce SEXP type to C++ matrix class and back
I don't want to sound disrespectful, but why not use RcppArmadillo if simplicity is you goal? It is hard to beat the _fully automatic_ conversion: R> cppFunction("arma::mat doubleUp(const arma::mat & x) { return 2*x; }", depends="RcppArmadillo") R> doubleUp(matrix(1:9,3,3)) [,1] [,2] [,3] [1,] 2 8 14 [2,] 4 10 16 [3,] 6 12 18 R> You can of course do all that by hand too, but why do you think both Rcpp and RcppArmadillo have, respectively, tens of thousands of lines of code? Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Dirk, I am sorry if it sounded disrespectful. On the contrary, as I said, your packages Rcpp and RcppArmadillo work very well, and use both of them in more "complex" applications. However, in this particular case in which I have just one object of one type (matrix double) with its elements stored column-major similarly to R I though that could find a reasonable method to coerce my SEXP matrix into a Matrix double in armadillo without using two packages for this. I hope this is understood. I though that there might beI ptough that might result which I insist has similar and , a matrix with one typeit seems veryas we say literally in Spanishother 2016-01-11 13:53 GMT+01:00 Dirk Eddelbuettel <edd at debian.org>:> > I don't want to sound disrespectful, but why not use RcppArmadillo if > simplicity is you goal? > > It is hard to beat the _fully automatic_ conversion: > > R> cppFunction("arma::mat doubleUp(const arma::mat & x) { return 2*x; }", depends="RcppArmadillo") > R> doubleUp(matrix(1:9,3,3)) > [,1] [,2] [,3] > [1,] 2 8 14 > [2,] 4 10 16 > [3,] 6 12 18 > R> > > You can of course do all that by hand too, but why do you think both Rcpp and > RcppArmadillo have, respectively, tens of thousands of lines of code? > > Dirk > > -- > http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
perhaps you don't need this anymore but now after extract the dimension m, n, we can simply generate arma matrix as mat an_arma_mat(REAL(RA), m, n); similarly you can convert RB to an arma matrix pointer, operate on it then return directly RB to R. I am testing a simple C++ function that takes a double matrix as argument and which uses routines provided by the C++ Armadillo package. I am aware of the nice capabilities of Rcpp and RcppArmadillo which helps simplifying a lot and that I have already successfully tested. However, I had a hard time trying to figure out how the coercion from a REALSPX matrix to an arma::mat = arma::Mat<double> matrix (double matrix in Armadillo) is done. In this particular case, because of the simplicity of my function, I would like to use base R only. -- Sent from: http://r.789695.n4.nabble.com/R-devel-f909078.html