Everything seems to work in my package, but I wanted to check if the steps to make it were correct and about memory use using "Map". (It's a simple example, somewhere in-between the inline examples and the fastLm()
example.)
Here is an inline function that takes the maximum over each column of a matrix:
library(Rcpp);
library(inline);
library(RcppEigen);
maxOverColCpp <- '
using Eigen::Map;
using Eigen::MatrixXd;
// Map the double matrix AA from R
const Map<MatrixXd> A(as<Map<MatrixXd> >(AA));
// evaluate and columnwise maximum entry of A
const MatrixXd Amax(A.colwise().maxCoeff());
return wrap(Amax);
'
rcppeigen_max_over_columns <- cxxfunction(signature(AA = "matrix"), maxOverColCpp, plugin = "RcppEigen")
Then to change the function to include it in an existing R package, I rewrote the code as follows, saved it in rcppeigen_max_over_columns.cpp
in a new src
folder in an existing R package:
// we only include RcppEigen.h which pulls Rcpp.h in for us
#include <RcppEigen.h>
// via the depends attribute we tell Rcpp to create hooks for
// RcppEigen so that the build process will know what to do
//
// [[Rcpp::depends(RcppEigen)]]
// via the exports attribute we tell Rcpp to make this function
// available from R
//
// [[Rcpp::export]]
Eigen::MatrixXd rcppeigen_max_over_columns(const Eigen::MatrixXd & A){
Eigen::MatrixXd Amax = A.colwise().maxCoeff();
return Amax;
}
(In fact it was a bit longer as I also needed to include finding the maximum over rows.)
Then:
modified the DESCRIPTION FILE with the lines:
Imports: Rcpp (>= 0.11.3), RcppEigen (>= 0.3.2.2.0)
LinkingTo: Rcpp, RcppEigen
modified the NAMESPACE file with the lines:
useDynLib(toyRpackage)
import(RcppEigen)
importFrom(Rcpp, evalCpp)
in R terminal, typed this, which I assume glues the R and C++:
Rcpp::compileAttributes(pkgdir="toyRpackage", verbose=getOption("verbose"))
Then as for a regular package, I did R CMD check
and R CMD build
.
First question is whether this process for including an RcppEigen function into an existing R package is correct? (I completely ignored any
Makevars
files or any.h
files -- I don't really know what they do... Also don't really understand the changes to the NAMESPACE file. I tried to copy theRcppEigen.package.skeleteon()
set-up but I am adding my function to an existing package. So it would be good to know if it's okay in case I missed something that could be a problem later.)Second question is whether I need a "Map" somewhere in
rcppeigen_max_over_columns.cpp
so that the matrix isn't copied when it's passed from R to C++?
I know it's a beginner question, but I'm having some trouble understanding the syntax in .cpp files as I don't know any C++. I thought maybe this question might help someone else who is also trying to add a simple function to their package. :)
Also, if you have any strong feelings about using RcppEigen over RcppArmadillo, please let me know. I read http://thread.gmane.org/gmane.comp.lang.r.rcpp/3522 which was useful. For my example of taking max over columns, RcppEigen seems much faster, not sure why.