[Rd] coerce SEXP type to C++ matrix class and back

Antonio Perez antonio.pv.gs at gmail.com
Mon Jan 11 00:14:22 CET 2016


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.



More information about the R-devel mailing list