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