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