Nesting Rcpp functions - r

Is it possible to nest Rcpp functions in each other?
I have a dummy example right here:
cppFunction(
'int add3(int x) {
return x+3;
}')
cppFunction(
'int add4(int x) {
return add3(x)+1;
}')
add3(2)
This does not work. How can I make this work?
Edit: Okay, so I followed Dirk's advice and now I have a test.cpp file:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int add3(int x) {
return x + 3;
}
// [[Rcpp::export]]
int add4(int x) {
return add3(x)+1;
}
Which I load in R with sourceCpp("test.cpp"). Now I can use both functions in R and they work although one function calls the other function.

The answers to your question get a little technical quickly, but are all provided in the Rcpp Attributes vignette, and have been for a long time.
First off, you are more-or-less misusing cppFunction(). It is made for quick and simple one-off function tests. Not for writing "infrastructure" or more complex code. For which you should use sourceCpp(), or better still, use a package.
If you switch you code to sourceCpp() and the [[Rcpp::export]] tag you will notice (in verbose=TRUE mode, or in package building) that the exported functions get 'transliterated' into other functions that R calls.
So yes you can nest functions, as you can in C / C++. Nothing is taken from you. But you cannot call the inner, nested function from R but that is possible with the API offered to us by R and which we use (and free you from interfacing directly). It only has SEXP .Call(functionanme, SEXP a, SEXP b,...) as an interface. I.e. a different signature.
But on the C / C++ you can nest, provided you compile your code differently.

Related

Rcpp Armadillo package compilation "error: incorrect or unsupported type" when trying to convert a

I have the latest version of R, RCppArmadillo and RStudio installed. I started a brand new R project using Rcpp with Armadillo, and created a single new cpp file called rcpparma_basic.cpp.
This is the content of that file:
#include "RcppArmadillo.h"
// [[Rcpp::export]]
arma::rowvec rcpparma_head(arma::rowvec x, int n) {
Rcpp::IntegerVector first_rcpp = Rcpp::IntegerVector::create(0,1,2);
arma::uvec first(first_rcpp); // instantiate the armadillo vec from the Rcpp vec
arma::rowvec out = x.elem(first);
return out;
}
I thought it would be possible for me to convert the integer vector obtained from Rcpp into an arma vec, based on the example Dirk Eddelbuettel provided in his answer on this page:
How can I multiply an Armadillo matrix with a NumericVector obtained from qnorm()?
The reason I was trying to convert Rcpp IntegerVector to arma vec is that I wanted to be able to use the Rcpp seq function, and related functions, along with arma objects.
But when I try to compile the package, it fails with an error at this line in Mat_meat.h:
static_assert( is_same_type< eT, rcpp_type >::value , "error: incorrect or unsupported type" );
I am not suggesting the error is in Mat_meat.h, I'm sure I've got something wrong in my code, but based on that error message I have no idea what that mistake might be. So any help would be greatly appreciated!
Thanks
Louise
I've got a partial answer to what I was doing wrong: when I wrap the output of the Rcpp seq function, then I stop getting the Mat_meat.h error and get more informative errors.
#include "RcppArmadillo.h"
// [[Rcpp::export]]
arma::rowvec rcpparma_head(arma::rowvec x, int n) {
Rcpp::IntegerVector first_rcpp = Rcpp::IntegerVector::create(0,1,2);
arma::uvec first(Rcpp::wrap(first_rcpp)); // instantiate the armadillo vec from the Rcpp vec
arma::rowvec out = x.elem(first);
return out;
}
Then the errors I get are both for that wrap line and say "No matching function for call to arma::Col ::Col(SEXP)" and "invalid conversion from 'SEXP' {aka 'SEXPREC*'} to 'arma::uword' {aka 'unsigned int'} [-fpermissive]".
So at least now I'm getting more useful errors.
I was only trying to recreate a head() function in Rcpp as a mini practice function to clarify some of the arma/Rcpp rules for myself before moving on to a more complex function I need for my package. Given the fact that there seem to be more useful functions for me in Rcpp than in Armadillo, and the fact that the latest version of my algorithm no longer uses matrix algebra because the inner model doesn't allow it, I think I'll just stop using Armadillo.

R: where to find the source code for all Rfast functions

I have just found an incredibly useful package called Rfast which uses Rcpp to perform routine operations. So I would like to extend my thanks to them for their work, as well as to the creators of Rcpp of course.
Might be a stupid question but does anyone know where I can get the source code for the Rfast rowOrder function? Doesn't seem to be on their github although the code for another function like Sort is there.
EDIT: I would like to see the actual cpp code of the underlying function that performs the operations, which in the end is called row_order_p
I see it here: https://github.com/RfastOfficial/Rfast/search?q=rowOrder
Which then leads to https://github.com/RfastOfficial/Rfast/blob/343808948622137707563425a2f5624b58ec19f0/R/Order.R
Found it, it was in the col/row utilities at this address: https://github.com/RfastOfficial/Rfast/blob/2cc0ddcaa1f6a4844733871b259ce44b9e48d279/src/col_row_utilities_p.cpp
IntegerMatrix row_order_p(NumericMatrix x,const bool stable,const bool descending){
const int ncl=x.ncol(),nrw=x.nrow();
IntegerMatrix f(nrw,ncl);
mat xx(x.begin(),nrw,ncl,false);
imat ff(f.begin(),nrw,ncl,false);
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i=0;i<nrw;++i){
ff.row(i)=Order<irowvec,rowvec>(xx.row(i),stable,descending,1);
}
return f;
}

Rcpp vs normal C++: header flag available?

I'm a beginner at Rcpp (though with a bit of experience in both R and C++) and am trying to write some code that can be used in both Rcpp and native C++.
As such, I am writing some wrapper functions that return data frames, numeric vectors and the like, that get created from various std containers.
I would like it so that I can set a flag somewhere, or have a flag that automatically detects whether the code is being used in native C++ or Rcpp.
I was wondering whether such a flag exists, or whether I should just go ahead and create one?
Finally, I was wondering whether this was the best way of doing what I wanted to achieve?
EDIT:
This is a very contrived example:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]
#include <vector>
#include <functional>
#include <algorithm>
#define RCPP
std::vector<double> multbyTwo(std::vector<double> input) {
std::transform(input.begin(), input.end(), input.begin(), std::bind(std::multiplies<double>(), std::placeholders::_1, 2));
return input;
}
#ifdef RCPP
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector input) {
return wrap(multbyTwo(as<std::vector<double> >(input)));
}
#endif // RCPP
/***R
print(timesTwo(10))
***/
This the kind of thing that I meant - wrapping a pure C++ function with an Rcpp one. (I know there are implicit conversions in this specific case, but there would not be for the kind of function that I would be building)

RcppEigen: there are no arguments to 'assert' that depend on a template parameter

In trying to run one of the rcppeigen examples from the rcpp Gallery on Windows 10 I got the following error message:
/R/winlibrary/3.5/RcppEigen/include/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h:137:60:
error: there are no arguments to 'assert' that depend on a template
parameter, so a declaration of 'assert' must be available
[-fpermissive] assert(degree >= minPadeDegree && degree <=
maxPadeDegree);
I'm not sure what this means (I am very new to the Eigen library). The code was taken from the Rcpp Gallery:
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::SelfAdjointEigenSolver;
// [[Rcpp::export]]
VectorXd getEigenValues(Map<MatrixXd> M) {
SelfAdjointEigenSolver<MatrixXd> es(M);
return es.eigenvalues();
}
I used sourceCpp() to compile a file saved as TestEigen.cpp. I'd appreciate any information on what the issue may be. I looked for similar questions here but did not find a clear answer.
Please feel free to delete my post if this question is a duplicate.
Kind regards

variable scope in c++ function called through R with sourceCpp

I have one function nested inside another in R. Since the deeper one is a bit slow, I decided to use sourceCpp to swap in some compiled code. However, that inner function uses variables defined in the outer function. In R I use environments. What's the c++ analog? Do I have to use the extern keyword? Would something like this work?
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
arma::mat myFunc(arma::mat a, arma::mat b){
extern arma::mat c;
return a + b + c;
}
You can pass R environments down to C++ just fine via Rcpp; and examples exists in the docs, here, and in other places. Just randomly tossing a C++ extern in there, however, does access an environment.

Resources