2

I'm new for Rcpp, and in my code, I must call the R function "optim" from C++. I referred to many examples, but there is still a mistake: "static assertion failed: cannot convert type to SEXP". Here is my code, and the problem is the last function:

#include <RcppArmadillo.h>

using namespace Rcpp;
using namespace RcppArmadillo;
using namespace arma;
using namespace std;
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
double fr(arma::colvec x){
  double result = 100 * (x(2) - x(1) * x(1)) * (x(2) - x(1) * x(1)) + (1 -     x(1)) * (1 - x(1));
  return result;  
} 


typedef double (*funcPtr)(arma::colvec x);

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr(){
  return(XPtr<funcPtr>(new funcPtr(&fr)));
}


// [[Rcpp::export]]
arma::colvec callOptimFun(SEXP x) {

  RNGScope scope;

  Rcpp::Environment stats("package:stats");
  Rcpp::Function optim = stats["optim"];
  XPtr<funcPtr> xpfun = putFunPtrInXPtr();
  funcPtr fun = *xpfun;
  Rcpp::List y = optim(x, fun);
  arma::colvec r = y["par"];
  return r; 
}

Unfortunately, I have tried lots of methods for my last function, and all methods have the same error. These are my tries: 1.

// [[Rcpp::export]]
Rcpp::List callOptimFun(arma::colvec x) {

  \\....
  Rcpp::List y = optim(x, fun);
  return y; 
}

2.

// [[Rcpp::export]]
Rcpp::List callOptimFun(arma::colvec x) {

  \\....
  Rcpp::List y = optim(x, fun);
  return y; 
}

3.

// [[Rcpp::export]]
Rcpp::List callOptimFun(SEXP x) {

  \\....
  Rcpp::List y = optim(x, fun);
  return y; 
}

I am not familiar with C++. What may be the problem? Thanks!

1 Answer 1

4

In this case, the use of a functional pointer is problematic. Rcpp has a special type of wrapper that requires the C++ function to not be exported into R called Rcpp::InternalFunction. Under this implementation, you're able to easily incorporate R's optim with your C++ function from C++!

Also, I modified the element accessed indexes in fr function. The reason for this modification is you are hitting an out-of-bounds error because the indexes in C++ are on a zero-based starting system not a one-based system starting system like R. (e.g. x(0) is the same as x[1] in R)

#include<RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

double fr(arma::vec x){
  double result = 100 * (x(1) - x(0) * x(0)) * (x(1) - x(0) * x(0)) + (1 - x(0)) * (1 - x(0));
  return result;  
} 

// [[Rcpp::export]]
arma::vec optim_rcpp(const arma::vec& init_val){

  Rcpp::Environment stats("package:stats"); 
  Rcpp::Function optim = stats["optim"];    

  Rcpp::List opt_results = optim(Rcpp::_["par"]    = init_val,
                                 Rcpp::_["fn"]     = Rcpp::InternalFunction(&fr),
                                 Rcpp::_["method"] = "BFGS");

  // Extract and coerce from list.
  arma::vec out = Rcpp::as<arma::vec>(opt_results[0]);

  return out;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.