coerce SEXP type to C++ matrix class and back

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

coerce SEXP type to C++ matrix class and back

Antonio
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.

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: coerce SEXP type to C++ matrix class and back

Dirk Eddelbuettel

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 | [hidden email]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: coerce SEXP type to C++ matrix class and back

Antonio
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 <[hidden email]>:

>
> 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 | [hidden email]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: coerce SEXP type to C++ matrix class and back

kklot
In reply to this post by Antonio

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

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel