thposs
thposs

Reputation: 328

Rcpp: Converting SEXP to float/double

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.

Upvotes: 3

Views: 2998

Answers (2)

Brent
Brent

Reputation: 4906

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);
}

Upvotes: 0

Simon Byrne
Simon Byrne

Reputation: 7874

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.

Upvotes: 0

Related Questions