我正在尝试构建一些嵌套函数,如下所示(简化示例):
// the actual functions come from particle physics and are extremely ugly
double f(double x){
return 2*x+1;
}
//in reality a numerical derivative term
double F(const std::function<double(double)>& f, double x){
return f(x) - f(x+1);
}
// in reality another higher order numerical derivative
double G(const std::function<double(double)>& f, double x){
return f(x) + f(x+1);
}
// in reality a function where the index is supposed to control the degree of derivatives of the function
double H(const std::function<double(double)>& f, double x, int switch){
if(0 == switch){
return G(f(x));
} else {
return F(f(x));
}
}
这是目标(2d用于演示):
double sum=0;
for(int i=0; i<1;++i){
for(int j=0; j<1;++j){
sum += H(H(f,i),j);
}
}
所以有两件事:
H
在F
和G
之间切换(我的实际问题有3个案例)。H(H(...)...)
问题是函数f
的类型,它是H
的第一个参数,当我通过它时第二次类型不再是double(double)
而是double(std::function<double(double)>,double(double),double)
左右...... 或其他方面: https://i.stack.imgur.com/XkbmJ.gif(无法发布图片,代表不够)
答案 0 :(得分:2)
首先,不要明确使用std::function
,而是让你的函数参数模板化,比如
template <typename Arg>
double F(Arg const & f, double x){
return f(x) - f(x+1);
}
这为优化和通用性提供了更多空间。
其次,将所有函数转换为返回lambda:
template <typename Arg>
auto F(Arg const & f){
return [f](double x){ return f(x) - f(x+1); };
}
template <typename Arg>
auto G(Arg const & f){
return [f](double x){ return f(x) + f(x+1); };
}
template <typename Arg>
std::function<double(double)> H(Arg const & f, int which){
if(0 == which){
return F(f);
} else {
return G(f);
}
}
注意auto
返回类型:返回lambda需要这个。
现在你不打电话给F(f,x)
,而是F
将f
转换为它的衍生物(或其他东西),现在可以将其应用于x
。这些现在可以像
F(f)(0.1); // apply F(f) to x=0.1
F(F(G(f)))(0.5); // apply F(F(G(f))) to x=0.5
H(H(f,0),1)(4.2); // apply H(H(f,0),1) to x=4.2
答案 1 :(得分:1)
如果您有内部f
和switch
的值(NB更改该名称,switch
是流量控制构造),那么您可以部分应用H
然后将其传递给H
std::function<double(double)> partial_H(std::function<double(double)> f, int choice)
{
return [f, choice](double x) { return H(f, x, choice); };
}