使用Rcpp在C ++中调用R的optim函数 [英] Calling R's optim function from within C++ using Rcpp

查看:171
本文介绍了使用Rcpp在C ++中调用R的optim函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Rcpp的新手,在我的代码中,我必须从C ++调用R函数 optim。我提到了许多示例,但是仍然存在一个错误:静态断言失败:无法将类型转换为SEXP。这是我的代码,问题是最后一个函数:

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

不幸的是,我为上一个函数尝试了很多方法,所有方法有相同的错误。这些是我的尝试:
1。

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

我对C ++不熟悉。可能是什么问题?谢谢!

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

推荐答案

在这种情况下,使用函数指针是有问题的。 Rcpp 具有特殊的包装类型,要求将 C ++ 函数不导出到名为 Rcpp :: InternalFunction的 R 中。 。在此实现下,您可以轻松地将 R optim 中的 C ++ 函数合并C ++

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++!

我还修改了 fr 函数中的元素访问索引。进行此修改的原因是您遇到越界错误,因为 C ++ 中的索引位于基于零的启动系统上,而不是基于单一系统的系统,如 R 。 (例如, x(0) R 中的 x [1] 相同)

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

这篇关于使用Rcpp在C ++中调用R的optim函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆