在C ++中的另一个函数中定义一个函数

问题描述 投票:0回答:1

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

// [[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个回答
0
投票

为了达到你想要的效果,我将使用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 ++编译器,该编译器可以编译c ++ 11代码并编辑R项目中的Makevars文件,并在顶部添加以下内容:

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

例如,关于这个here的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.