【问题标题】:Define a function within another function in C++在 C++ 中的另一个函数中定义一个函数
【发布时间】:2018-05-19 20:50:59
【问题描述】:

为了求解微分方程,我使用 R 中的 Rcpp 包和 C++ 中的 boost 包。我在 C++ 中创建了 eq 函数,它将 R 函数 mod_cpp 转换为“C++ 函数”(见下文)。接下来将 eq 函数作为参数放入Integrate_const 函数中。最后,我可以用 Rcpp 在 R 中编译它,我得到一个名为 my_fun 的 R 函数,它只依赖于向量 vs. 一切正常。

// [[Rcpp::export]]
void my_fun22(Rcpp::NumericVector &x, const double t){
  Function f("mod_cpp");
  x=f(_["t"]=t,_["x"]=x);
}     

Rcpp::NumericVector nvec(130);
void eq(const state_type &x, state_type &dxdt, const double t){
  boost_array_to_nvec2(x, nvec);
  my_fun22(nvec,t);
  nvec_to_boost_array2(nvec, dxdt);
}

Rcpp::NumericMatrix my_fun(const Rcpp::NumericVector vs) {
  state_type x = nvec_to_boost_array(vs); // initial conditions
  integrate_const(make_dense_output( 1E-4 , 1E-4 , stepper_type () ) ,
                eq , x , 0.0 , 120.0 , 1.0 , write_cout);
  return data;
}

问题是mod_cpp函数中包含的我模型的所有参数都是固定的。我现在要做的是创建另一个与 my_fun 完成相同工作但取决于模型的某些参数的函数。更准确地说,创建一个名为 my_fun2(vs, theta) 的函数,它依赖于 vs AND theta。我已经尝试过这样做,但正在努力重新定义 my_fun 函数中的 eq 函数,因为它不允许在 R 中的另一个函数中定义函数。我错过了什么吗?

【问题讨论】:

标签: c++ r rcpp


【解决方案1】:

为了实现您想要的,我将使用 c++ 11 lambda 函数,而不是将 eq 创建为函数,我将其定义为二阶函数:返回不同函数的函数,其参数可以是 theta你提到的。例如:

...
Rcpp::NumericMatrix my_fun(const Rcpp::NumericVector vs, const float theta) {
  state_type x = nvec_to_boost_array(vs); // initial conditions
  integrate_const(make_dense_output( 1E-4 , 1E-4 , stepper_type () ) ,
            eq(theta) , x , 0.0 , 120.0 , 1.0 , write_cout);
...
}

然后修改后的eq 将类似于:

std::function<void(const state_type, state_type, const double)> eq(const float theta) {
   return [&theta](const state_type &x, state_type &dxdt, const double t) {
     // do something with theta here
     // for instance, modify nvec
     ...
     // then your old function body
     boost_array_to_nvec2(x, nvec);
     my_fun22(nvec,t);
     nvec_to_boost_array2(nvec, dxdt);
   }
}

这样你可以在执行时传递参数。我还没有测试过,但我猜这个想法应该没问题。

要使用 c++ 11 功能,您需要确保在系统路径中安装了可以编译 c++ 11 代码的 c++ 编译器,并在 R 项目中编辑 Makevars 文件并在顶部添加以下内容:

PKG_CXXFLAGS = -g -O3 -std=c++11

例如,有关此here 的更多信息。

【讨论】:

  • 出现以下错误:error: reference to 'function' is ambiguous
  • 这是因为没有找到function,您需要使用std 命名空间或将function 替换为std::function。检查更新的答案。
  • Makevars 位于何处?在 Rcpp 包中,我没有任何 Makevars 文件。
  • 通常我在使用链接的 c++ 代码创建 R 包时所做的只是在选择 Rcpp 模板的新文件夹中创建一个 R studio 项目。在我的情况下,Makevars 位于 src 文件夹中。也许this example 可以给你一个提示(免责声明:我做到了)。甚至还有一个二阶函数的示例here,如果您需要进一步的帮助,请告诉我。
  • 嗯,是的,我想你是对的,可能你不需要,但将所有代码放入一个包中可能也是一个好主意(这只是我个人的选择,是否最好的方法与否可能取决于您的具体问题)。另外,由于您已经在使用Rcpp,最好直接在您的代码中使用Eigenarmadillo 的c++ 代码,而 使用R 包装器,它们大多被设计为直接从 R 中使用,而不是从 c++ 代码中使用。同样,这取决于您要达到的目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
  • 2012-01-15
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多