Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rcpp: how to pass complex number from R to cpp

I want to pass complex numbers from R to my cpp code using Rcpp. I try to pass complex numbers analogously as one can pass doubles and integers:

#include <complex>
#include <Rcpp.h>

using namespace Rcpp;

RcppExport SEXP mandelC(SEXP s_c) {
    std::complex<double> c = ComplexVector(s_c)[0];
}

However, the code does not compile and complains about:

g++ -I/usr/share/R/include -DNDEBUG -I/usr/share/R/include -fopenmp  -I/home/siim/lib/R/Rcpp/include     -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c a.cpp -o a.o
a.cpp: In function ‘SEXPREC* mandelC(SEXP)’:
a.cpp:7:50: error: conversion from ‘Rcpp::traits::storage_type<15>::type {aka Rcomplex}’ to non-scalar type ‘std::complex<double>’ requested
std::complex<double> c = ComplexVector(s_c)[0];
                                              ^

Obviously, I do something wrong but I have been unable to find any examples. Anyone can point me to the correct path?

like image 992
Ott Toomet Avatar asked Oct 29 '16 18:10

Ott Toomet


1 Answers

You are missing some pretty simple things:

R> cppFunction("ComplexVector doubleMe(ComplexVector x) { return x+x; }")
R> doubleMe(1+1i)
[1] 2+2i
R> doubleMe(c(1+1i, 2+2i))
[1] 2+2i 4+4i
R> 

Remember that everything is a vector in a R, and scalars don't "really" exist: they are vectors of length one. So for a single complex number you (still) pass a ComplexVector which happens to be of length one.

Check out the two packages by Baptiste which do complex math via RcppArmadillo--that "proves" that some the RcppArmadillo interfaces work the way they should.

Edit: And if you really want a scalar, you can get it too:

R> cppFunction("std::complex<double> doubleMeScalar(std::complex<double> x) { 
+                                                   return x+x; }")
R> doubleMeScalar(1+1i)
[1] 2+2i
R> 
like image 52
Dirk Eddelbuettel Avatar answered Sep 17 '22 02:09

Dirk Eddelbuettel