首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Rcpp中将数据传递给nlopt?

在Rcpp中将数据传递给nlopt?
EN

Stack Overflow用户
提问于 2018-07-09 07:42:20
回答 1查看 242关注 0票数 0

这是一个相当简单的问题,但我还没能在网上找到答案。

希望我最近的尝试,这里是最新的编译器输出:注意:候选函数不可行:对于第二个参数,没有已知的从'double (unsigned int,const double *,void )‘到'nlopt_func’的转换(也就是'double (),const *,double *,void *‘)。

从这个错误中,我推测我现在正在正确地包装或‘类型转换’数据参数以及参数向量。第三个输入之间的差异,梯度,使我感到困惑。因为我正在调用一个梯度自由优化例程。

下面是一个具有常数和变量的简单线性回归:

代码语言:javascript
运行
复制
#include "RcppArmadillo.h"

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(nloptr)]]
//#include <vector>
#include <nloptrAPI.h>
using namespace arma;
using namespace Rcpp;

typedef struct {
  arma::mat data_in;
} *my_func_data;

typedef struct {
  double a, b;
} my_theta;

double myfunc(unsigned n, const double *theta, void *grad, void *data){

  my_func_data &temp = (my_func_data &) data;
  arma::mat data_in = temp->data_in;

  my_theta *theta_temp = (my_theta *) theta;
  double a = theta_temp->a, b = theta_temp->b;

  int Len = arma::size(data_in)[0];
  arma::vec Y1 = data_in(span(0, Len-1), 1);
  arma::vec Y2 = data_in(span(0, Len-1), 2);
  arma::vec res = data_in(span(0, Len-1), 0) - a*Y1 - b*Y2 ;
  return sum(res);
}


// [[Rcpp::export]]
void test_nlopt_c() {

  arma::mat data_in(10,3);
  data_in(span(0,9),0) = arma::regspace(40, 49);
  data_in(span(0,9),1) = arma::ones(10);
  data_in(span(0,9),2) = arma::regspace(10, 19);

  my_func_data &temp = (my_func_data &) data_in;

  double lb[2] = { 0, 0,}; /* lower bounds */
  nlopt_opt opt;
  opt = nlopt_create(NLOPT_LN_NELDERMEAD, 2); /* algorithm and dimensionality */
  nlopt_set_lower_bounds(opt, lb);

  nlopt_set_min_objective(opt, myfunc, &data_in );

  nlopt_set_xtol_rel(opt, 1e-4);
  double minf; /* the minimum objective value, upon return */
  double x[2] = {0.5, 0.5};  /* some initial guess */
  nlopt_result result = nlopt_optimize(opt, x, &minf);
  Rcpp::Rcout << "result:" << result;
    return;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-10 09:47:28

搞清楚了,愚蠢的答案是正确的,只要把“空虚”改为“加倍”,就不知道原因了。无论如何,示例代码需要一些改进,但它可以工作。

代码语言:javascript
运行
复制
#include "RcppArmadillo.h"

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(nloptr)]]
//#include <vector>
#include <nloptrAPI.h>
using namespace arma;
using namespace Rcpp;

typedef struct {
  arma::mat data_in;
} *my_func_data;

typedef struct {
  double a, b;
} my_theta;

double myfunc(unsigned n, const double *theta, double *grad, void *data){

  my_func_data &temp = (my_func_data &) data;
  arma::mat data_in = temp->data_in;

  my_theta *theta_temp = (my_theta *) theta;
  double a = theta_temp->a, b = theta_temp->b;

  int Len = arma::size(data_in)[0];
  arma::vec Y1 = data_in(span(0, Len-1), 1);
  arma::vec Y2 = data_in(span(0, Len-1), 2);
  arma::vec res = data_in(span(0, Len-1), 0) - a*Y1 - b*Y2 ;
  return sum(res);
}


// [[Rcpp::export]]
void test_nlopt_c() {

  arma::mat data_in(10,3);
  data_in(span(0,9),0) = arma::regspace(40, 49);
  data_in(span(0,9),1) = arma::ones(10);
  data_in(span(0,9),2) = arma::regspace(10, 19);

  my_func_data &temp = (my_func_data &) data_in;

  double lb[2] = { 0, 0,}; /* lower bounds */
  nlopt_opt opt;
  opt = nlopt_create(NLOPT_LN_NELDERMEAD, 2); /* algorithm and dimensionality */
  nlopt_set_lower_bounds(opt, lb);

  nlopt_set_min_objective(opt, myfunc, &data_in );

  nlopt_set_xtol_rel(opt, 1e-4);
  double minf; /* the minimum objective value, upon return */
  double x[2] = {0.5, 0.5};  /* some initial guess */
  nlopt_result result = nlopt_optimize(opt, x, &minf);
  Rcpp::Rcout << "result:" << result;
    return;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51240355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档