【问题标题】:Calling R's optim function from within C++ using Rcpp使用 Rcpp 从 C++ 中调用 R 的 optim 函数
【发布时间】:2017-09-28 16:18:23
【问题描述】:

我是 Rcpp 的新手,在我的代码中,我必须从 C++ 调用 R 函数“optim”。我参考了很多例子,但还是有一个错误:“静态断言失败:无法将类型转换为 SEXP”。这是我的代码,问题出在最后一个函数:

#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.

// [[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++。可能是什么问题?谢谢!

【问题讨论】:

    标签: c++ r rcpp


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多