[英]Calling R's optim function from within C++ using Rcpp
我是 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++ 不熟悉。 可能是什么问题? 谢谢!
在这种情况下,函数指针的使用是有问题的。 Rcpp有一种特殊类型的包装器,它要求C++函数不能被导出到R 中,称为Rcpp::InternalFunction
。 在此实现下,您可以轻松地将R的optim
与您的C++函数从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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.