3
SEXP callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  return res;
}

for(int i=0; i<(n_epochs); i++){
  NumericVector outputMatchTracker = history["output.match.tracker"];
  outputMatchTracker[i] = callFunction1(network, words, testWordContinuity);
}

The testWordContinuity function in R calls another function in R that returns a single numeric variable

All I'm doing with res is replacing values in a vector using the for loop. The first line after the beginning of the for loop is assigning outputMatchTracker to a vector of zeros (history["output.match.tracker"]) so I can loop over the zeros.

The error: "Cannot convert 'SEXP' to 'Rcpp::traits::storage_type<14>::type {aka double}' in assignment" occurs on the last line in the for loop above.

Is there a way to convert res from SEXP to float or double?

I realize a similar question has been asked here: Rcpp cannot convert ‘SEXP {aka SEXPREC*}’ to ‘double’ in initialization but that question was solved by using an Rcpp sugar function instead of an R function to avoid converting SEXP into a double.

If there is not a way to convert from SEXP to float or double, is there a common way to get around this problem besides just coding the R function in Rcpp?

Happy to provide more information if necessary,

Thank you.

Edit:

Minimum Reproducible Example:

In Rcpp:

// [[Rcpp::export]]
SEXP callFunction(Function func){
  SEXP res = func();
  return(res);
}

// [[Rcpp::export]]
NumericVector func1(Function func){
  for(int i=0; i<10; i++){
    NumericVector vect(10);
    vect[i] = callFunction(func);
  }
  return(vect);
}

Upon sourcing this code the error specified above will appear.

thposs
  • 318
  • 2
  • 15
  • 2
    Welcome to StackOverflow! There is a lot of verbiage in your question, but no [_minimal reproducible example_](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) and as such little we can say in response. Please edit to provide something minimal yet complete that triggers the error. – Dirk Eddelbuettel Mar 01 '18 at 18:19
  • Have you tried the `as<>` operator? @DirkEddelbuettel authored an article that is very thorough for these type of things. It can be found [here](http://gallery.rcpp.org/articles/custom-templated-wrap-and-as-for-seamingless-interfaces/). – Joseph Wood Mar 01 '18 at 23:57
  • _Psst_ @JosephWood Dirk has authored many wonderful _Rcpp_ articles; however, I wrote that one :) – coatless Mar 04 '18 at 02:01
  • @coatless, I feel like an idiot. That was super careless and unintentional. I'm in the Rcpp Galary on a daily basis and found that article very fast, copied the link, and didn't even bother to look at the author. I'm very sorry. I have huge respect for you and promote your work and websites often. – Joseph Wood Mar 04 '18 at 02:14
  • Seems like you put your results in a `NumericVector`, so why not always using `double` instead of `SEXP`? – F. Privé Mar 04 '18 at 10:26
  • @JosephWood no worries mate. 'Tis hard to see anything _Rcpp_-related without Dirk. :) – coatless Mar 04 '18 at 16:14
  • 1
    The as<> operator did the trick. I had tried that before, but apparently with the incorrect syntax. Thank you! – thposs Mar 05 '18 at 05:03

2 Answers2

0

I believe you are supposed to use the REAL macro, which returns a pointer to the start of a double array. See https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Attributes for an example.

Simon Byrne
  • 7,694
  • 1
  • 26
  • 50
  • 2
    Not needed in the Rcpp world. `cppFunction("double plusTwo(double x) { return x + 2.0; }")`. Ditto for `Rcpp::NumericVector` if you want a vector instead a (C/C++) scalar. – Dirk Eddelbuettel Mar 01 '18 at 18:49
0

As an extension of Simon Byrne's answer - there are 2 ways to achieve this that I am aware of:

  1. Remember that scalars in R are actually always vectors with a length of 1. Therefore convert an R SEXP object to an RCPP NumericVector and use index (square bracket) notation to reference the first element:
double callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  NumericVector dblVec(res)
  return dblVec[0];
}
  1. use the REAL macro and de-reference the pointer (to the first element). This may well be a micro-optimisation compared to approach 1 (untested), but the bottleneck will almost certainly be the testWordContinuity R function. There is also an asReal function in the <Rinternals.h> C library, but given the REAL macro is included in the <Rcpp.h> header file, it would seem to add unnecessary complexity to bother including <Rinternals.h>.
double callFunction1(List network, List words, Function testWordContinuity){
  SEXP res = testWordContinuity(network, words);
  return *REAL(res);
}
Brent
  • 4,611
  • 4
  • 38
  • 55