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>
Related
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.
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>
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.
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.
Since last night I have been trying out Rcpp and inline, and so far I am really enjoying it. But I am kinda new to C in general and can only do basic stuff yet, and I am having a hard time finding help online on things like functions.
Something I was working on was a function that finds the minimum of a vector in the global environment. I came up with:
library("inline")
library("Rcpp")
foo <- rnorm(100)
bar <- cxxfunction( signature(),
'
Environment e = Environment::global_env();
NumericVector foo = e["foo"];
int min;
for (int i = 0; i < foo.size(); i++)
{
if ( foo[i] < foo[min] ) min = i;
}
return wrap(min+1);
', plugin = "Rcpp")
bar()
But it seems like there should be an easier way to do this, and it is quite slower than which.max()
system.time(replicate(100000,bar()))
user system elapsed
0.27 0.00 0.26
system.time(replicate(100000,which.min(foo)))
user system elapsed
0.2 0.0 0.2
Am I overlooking a basic c++ or Rcpp function that does this? And if so, where could I find a list of such functions?
I guess this question is related to:
Where can I learn how to write C code to speed up slow R functions?
but different in that I am not really interested in how to incorporate c++ in R, but more on how and where to learn basic c++ code that is usable in R.
Glad you are finding Rcpp useful.
The first comment by Billy is quite correct. There is overhead in the function lookup and there is overhead in the [] lookup for each element etc.
Also, a much more common approach is to take a vector you have in R, pass it to a compiled function you create via inline and Rcpp, and have it return the result. Try that. There are plenty of examples in the package and scattered over the rcpp-devel mailing list archives.
Edit: I could not resist trying to set up a very C++ / STL style answer.
R> src <- '
+ Rcpp::NumericVector x(xs);
+ Rcpp::NumericVector::iterator it = // iterator type
+ std::min_element(x.begin(), x.end()); // STL algo
+ return Rcpp::wrap(it - x.begin()); '
R> minfun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp")
R> minfun(c(7:20, 3:5))
[1] 14
R>
That is not exactly the easiest answer but it shows how by using what C++ offers you can find a minimum element without an (explicit) loop even at the C++ level. But the builtin min() function is still faster.
*Edit 2: Corrected as per Romain's comment below.