What is the R to C++ syntax for vectors? - c++

I am an R and C programmer trying to use Rcpp to create an R (and C++) wrapper for a program written in C. I'm not really familiar with C++.
Can someone help me understand the documentation on how to import an R object as a C++ vector? (I'm specifically trying to import an R list that includes a mixture of int, double, and numeric lists.)
The Rcpp-introduction.pdf states:
The reverse conversion from an R object to a C++ object is implemented by variations of
the Rcpp::as template whose signature is:
template <typename T> T as(SEXP x);
It offers less sexibility and currently handles conversion of R objects into primitive types (e.g., bool, int, std::string, ...), STL vectors of primitive types (e.g.,
std::vector<bool>, std::vector<double>, ...) and arbitrary types that offer a constructor that takes a SEXP.
I am confused as to what this means, i.e. what gets filled in for "template", "typename T", and "T". I've seen what appear to be lots of examples for the primitives, e.g.
int dx = Rcpp::as<int>(x);
but I don't understand how this syntax maps to the template documentation above, and (more importantly) don't understand how to generalize this to STL vectors.

Maybe you are making it too complicated. An R vector just becomes a C++ vector "because that is what Rcpp does for you".
Here it is using Rcpp::NumericVector:
R> library(Rcpp)
R> cppFunction('NumericVector ex1(NumericVector x) { return x + 2;}')
R> ex1(1:4) # adds two
[1] 3 4 5 6
R>
This uses the fact that we defined + for our NumericVector types. You can also pass a std::vector<double> in and out, but need to add some operations which is often more than one statement so I didn't here...
So in short, keep reading the documentation and ask on rcpp-devel or here if you need help.
Edit: For completeness, the same with a STL vector
R> cppFunction('std::vector<double> ex2(std::vector<double> x) { \
for (size_t i=0; i<x.size(); i++) x[i] = x[i] + 2; return x;}')
R> ex2(1:4)
[1] 3 4 5 6
R>

Related

How to pass in functions as arguments in Rcpp / C++?

I'm trying to write a function which can take in functions as its arguments in Rcpp. I have written an example function in R that shows the kind of functionality that I'm aiming for:
simulate_and_evaluate <- function(simulate, evaluate) {
y <- simulate(1)
eval <- evaluate(y)
return(eval)
}
simulate_fun <- function(n) rnorm(n, 0, 1)
evaluate_fun <- function(x) dnorm(x, 0, 1)
simulate_and_evaluate(simulate = simulate_fun,
evaluate = evaluate_fun)
In this function simulate_and_evaluate, this takes in two arguments which are both functions, one that simulates a number and one that evaluates a function with this simualted number. So as an example, we can simulate a value from a standard normal and evaluate the density of a standard normal at that point. Does anyone know if there's a way to do this in Rcpp?
Rcpp aims for seamless interfacing of R and C++ objects. As functions are first class R objects represented internally as a type a SEXP can take, we can of course also ship them with Rcpp. There are numerous examples.
So here we simply rewrite your function as a C++ function:
Rcpp::cppFunction("double simAndEval(Function sim, Function eval) {
double y = as<double>(sim(1));
double ev = as<double>(eval(y));
return(ev);
}")
And we can then set the RNG to the same value, run your R function and this C++ function and get the same value. Which is awesome.
R> set.seed(123)
R> simulate_and_evaluate(simulate = simulate_fun,
+ evaluate = evaluate_fun)
[1] 0.341
R> set.seed(123) # reset RNG
R> simAndEval(simulate_fun, evaluate_fun)
[1] 0.341
R>
But as #MrFlick warned you, this will not run any faster because we added no compiled execution of the actual functions we are merely calling them from C++ rathern than R.
The topic has been discussed before. Please search StackOverflow, maybe with a string [rcpp] Function to get some meaningful hits.

pass R complex object to armadillo C++

R uses, when interfacing with other languages, the header R_ext/Complex.h which includes the type Rcomplex which seems to be an implementation of std::complex<double>. The standard way of using it would be for a complex vector x_ in R:
Rcomplex *px = COMPLEX(x_);
However, since I need to pass it to armadillo I then do:
arma::cx_vec x(px, nrows(x_), false, false);
but armadillo does not accept Rcomplex types. I have tried doing instead:
std::complex<double> *px = COMPLEX(x_);
but get the following error: cannot convert ‘Rcomplex*’ to ‘std::complex<double>*’ in initialization
Do you have any clue for passing a complex vector in R to std::complex<double> type? I am aware of Rcpp but would like to have a direct solution relying on base R.
EDIT: Following one of the comments, I wanted to clarify that Rcomplex is of C type but that it is compatible with std::complex<double> according to the answer by #Stephen Canon.
EDIT2: Why does Dirk's answer have more votes than the accepted answer if it is not answering the "without dependencies" question. In addition, I have been downvoted apparently because if one wants preferably to use base R with C or C++ somebody does not like it. Anyway, I have better things to do but this is not the first time that I get no answer to my original question when asking something related to base R interfacing with C or C++ and get a Rcpp related answer that I have not asked for.
Complex numbers are less common in statistics so that has not been an initial focus. However there are use cases Baptiste has one or two packages which pushes to add features to the interface given the existing support in Armadillo and R.
So all the work is done for you in templates -- here is the simplest possibly example of passing complex-values matrix and returning its sum:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::cx_mat foo(const arma::cx_mat & C) {
return C + C;
}
/*** R
C <- matrix( (1+1i) * 1:4, 2, 2)
C
foo(C)
*/
It does what you'd expect:
R> sourceCpp("/tmp/armaComplex.cpp")
R> C <- matrix( (1+1i) * 1:4, 2, 2)
R> C
[,1] [,2]
[1,] 1+1i 3+3i
[2,] 2+2i 4+4i
R> foo(C)
[,1] [,2]
[1,] 2+2i 6+6i
[2,] 4+4i 8+8i
R>
So we start with complex values in R, pass them via Rcpp and RcppArmadillo to Armadillo and get them back to R. Without writing an additional line of code, and no discernible overhead.
One type can always be forced to another type using reinterpret_cast. Generally this is a bad idea, but if you can guarantee that the two complex types are indeed compatible, you can do:
Rcomplex* px = COMPLEX(x_);
arma::cx_vec x( reinterpret_cast<arma::cx_double*>(px), nrows(x_), false, false );
The type arma::cx_double is a shorthand for std::complex<double>

Three-dimensional array as a vector of arrays

I have 3-dim double array with two of its dimensions known at compile time.
So to make it efficient, I'd like to write something like
std::vector<double[7][19]> v;
v.resize(3);
v[2][6][18] = 2 * 7*19 + 6 * 19 + 18;
It's perfect except it does not compile because of "v.resize(3);"
Please don't recommend me using nested vectors like
std::vector<std::vector<std::vector<double>>> v;
because I don't want to set sizes for known dimensions each time I extend v by its first dimension.
What is the cleanest solution here?
Why not a std::vector of std::array of std::array of double?
std::vector<std::array<std::array<double, 19>, 7>> v;
This is a good example of when it's both reasonable and useful to inherit from std::vector, providing:
you can be sure they won't be deleted using a pointer to their vector base class (which would be Undefined Behaviour as the vector destructor's not virtual)
you're prepared to write a forwarding constructor or two if you want to use them
ideally, you're using this in a relatively small application rather than making it part of a library API with lots of distributed client users - the more hassle client impact could be, the more pedantic one should be about full encapsulation
template <typename T, size_t Y, size_t Z>
struct Vec_3D : std::vector<std::array<std::array<T, Y>, Z>>
{
T& operator(size_t x, size_t y, size_t z)
{
return (*this)[x * Y * Z + y * Y + z];
}
const T& operator(size_t x, size_t y, size_t z) const
{
return (*this)[x * Y * Z + y * Y + z];
}
};
So little effort, then you've got a nicer and less error prone v(a, b, c) notation available.
Concerning the derivation, note that:
your derived type makes no attempt to enforce different invariants on the object
it doesn't add any data members or other bases
(The lack of data members / extra bases means even slicing and accidental deletion via a vector* are likely to work in practice, even though they should be avoided it's kind of nice to know you're likely playing with smoke rather than fire.)
Yes I know Alexandrescu, Sutter, Meyers etc. recommend not to do this - I've read their reasons very carefully several times and if you want to champion them even for this usage, please bring relevant technical specifics to the table....

How to read C++ code or: What to do without documentation?

The question might sound a bit weird: I want to do numeric matrix calculations using Boost's ublas and ATLAS/Lapack. I am using the Boost numeric bindings to interface between those two libraries. However, either I just cannot find it or there is no proper documentation on how to use these bindings. Also, I am new to Boost (and actually C++ in general) so I have a hard time finding out how I can use functions provided by Lapack in my code.
The problem I want to solve in the end, is finding the Eigenvalues and -vectors of a symmetric banded matrix. As far as I understood it, I would be using lapack::steqr for this. The thing is, I don't know, how to properly call the function. In the code of the numeric bindings, I can see something like this:
template <typename D, typename E, typename Z, typename W>
inline
int steqr( char compz, D& d, E& e, Z& z, W& work ) {
int const n = traits::vector_size (d);
assert( traits::vector_size (e) == n-1 );
assert( traits::matrix_size1 (z) == n );
assert( traits::matrix_size2 (z) == n );
assert( compz=='N' || compz=='V' || compz=='I' );
...
Now, how do I handle that? I tried steqr<double, double, double, double>(...) and double arrays, which didn't work. Then, to find out the proper arguments to use, I picked one of the asserts and tried to find anything that works with traits::matrix_size1(...) - Even that I couldn't get to compile, neither with a double array nor with a ublas::matrix.
So my question is, in general: When I find such a library without complete documentation, how do I find out how to call functions? I am coming from C mainly and am extremely confused with all these templates. Is the only way really to track down everything in the code? Or are there little tricks? Or can I probably draw information from the error messages?
One example of such an error message is, for the following code:
ublas::matrix<double> empty(N,N);
std::cout << traits::matrix_size1<ublas::matrix>(empty) << std::endl;
Then I get during compilation:
eigenvalues.cpp:40:85: error: no matching function for call to ‘matrix_size1(boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >&)’
eigenvalues.cpp:40:85: note: candidate is:
/usr/include/boost/numeric/bindings/traits/matrix_traits.hpp:148:18: note: template<class M> std::ptrdiff_t boost::numeric::bindings::traits::matrix_size1(M&)
It is probably useful, that the candidate is listed there, but I just don't know, how to read this line and adjust my code accordingly.
Again: This question is a bit more general, on how to deal with stuff like this. I know the basic concept of classes and templates, but this is just a bit too abstract for my knowledge.
Since I am not too proficient in templated c++, I personally find it much easier to use the cblas interface which is only a thin wrapper over the original Fortran code.
In this approach, you'll have to make your own class for matrices, which would be compatible to the Fortran understanding of what a matrix is. The easiest way is probably to inherit from std::vector or std::valarray and provide your own indexing operation.
Yes, it's a bit of work. But it's not as bad as it sounds :-).
And by the way, beware of using the single-precision routines (ssteqr) with double precision arguments. LAPACK will not report any error, but the result is going to be plain wrong.

R List of numeric vectors -> C++ 2d array with Rcpp

I mainly use R, but eventually would like to use Rcpp to interface with some C++ functions that take in and return 2d numeric arrays. So to start out playing around with C++ and Rcpp, I thought I'd just make a little function that converts my R list of variable-length numeric vectors to the C++ equivalent and back again.
require(inline)
require(Rcpp)
test1 = cxxfunction(signature(x='List'), body =
'
using namespace std;
List xlist(x);
int xlen = xlist.size();
vector< vector<int> > xx;
for(int i=0; i<xlen; i++) {
vector<int> test = as<vector<int> > (xlist[i]);
xx.push_back(test);
}
return(wrap(xx));
'
, plugin='Rcpp')
This works like I expect:
> test1(list(1:2, 4:6))
[[1]]
[1] 1 2
[[2]]
[1] 4 5 6
Admittedly I am only part way through the very thorough documentation, but is there a nicer (i.e. more Rcpp-like) way to do the R -> C++ conversion than with the for loop? I am thinking possibly not, since the documentation mentions that (at least with the built-in methods) as "offers less flexibility and currently handles conversion of R objects into primitive types", but I wanted to check because I'm very much a novice in this area.
I will give you bonus points for a reproducible example, and of course for using Rcpp :) And then I will take those away for not asking on the rcpp-devel list...
As for converting STL types: you don't have to, but when you decide to do it, the as<>() idiom is correct. The only 'better way' I can think of is to do name lookup as you would in R itself:
require(inline)
require(Rcpp)
set.seed(42)
xl <- list(U=runif(4), N=rnorm(4), T2df=rt(4,2))
fun <- cxxfunction(signature(x="list"), plugin="Rcpp", body = '
Rcpp::List xl(x);
std::vector<double> u = Rcpp::as<std::vector<double> >(xl["U"]);
std::vector<double> n = Rcpp::as<std::vector<double> >(xl["N"]);
std::vector<double> t2 = Rcpp::as<std::vector<double> >(xl["T2df"]);
// do something clever here
return(R_NilValue);
')
Hope that helps. Otherwise, the list is always open...
PS As for the two-dim array, that is trickier as there is no native C++ two-dim array. If you actually want to do linear algebra, look at RcppArmadillo and RcppEigen.