此函数计算X
处的函数Foo的推导值double Deriv( double(* Foo)(double x), double X )
{
const double mtDx = 1.0e-6;
double x1 = Foo(X+mtDx);
double x0 = Foo(X);
return ( x1 - x0 ) / mtDx;
}
我想写一个Funktion,它不返回X的派生值,而是一个新函数,它是函数Foo的推导。
xxxx Deriv( double(* Foo)(double x) )
{
return Derivation of Foo;
}
然后就可以写了 SecondDeriv = Deriv(Deriv(Foo))
根据新标准在C ++中是否可以编写这样的函数? 我认为用旧标准来说这是不可能的。
答案 0 :(得分:1)
这是一种方法。
#include <iostream>
#include <functional>
std::function<double(double)> Deriv( double(*Foo)(double x) )
{
auto f = [Foo](double x) -> double
{
const double mtDx = 1.0e-6;
double x1 = Foo(x+mtDx);
double x0 = Foo(x);
return ( x1 - x0 ) / mtDx;
};
return f;
}
double Foo(double x)
{
return x*x;
}
double Bar(double x)
{
return x*x*x;
}
int main()
{
std::cout << Deriv(Foo)(10) << std::endl;
std::cout << Deriv(Bar)(10) << std::endl;
}
输出:
20
300
答案 1 :(得分:1)
一旦你可以在一个点计算一个函数的值,你就可以用它来实现你的一般函数。 Lambda表达式允许您轻松生成这些派生函数:
auto MakeDerivative(double (&f)(double)) {
return [=](double x) { return Deriv(f, x); };
}
如果您希望能够使用有状态函数,则可能需要将Deriv
更新为函数模板,其第一个参数类型是模板参数。如果您想重复应用MakeDerivative
(因为它的返回类型是有状态闭包),这是正确的:
template <typename F>
double Deriv(F f, double x) {
// your code here
}
template <typename F>
auto MakeDerivative(F f) {
return [=](double x) { return Deriv(f, x); };
}
但是,您可能会对&#34;自动差异化等技术感兴趣。它允许你直接用原始函数的定义来表达导数,代价是在一个扩大的域(一个无穷小的邻域,基本上)上工作。
答案 2 :(得分:1)
使用通用lambda,实现玩具derivative
很简单。在下面的代码中,derivative
是数学意义上的导数运算符。它接受函数double -> double
,生成其衍生double -> double
。
#include <iostream>
double delta = 0.001;
auto derivative = [] ( auto foo ) {
return [foo] (double x) {
// the simplest formula for numeric derivative
return (foo(x + delta) - foo(x)) / delta;
};
};
// test
int main() {
auto quar = [] ( double x ) { return x * x; };
auto dev_quar = derivative(quar);
auto dev_dev_quar = derivative(dev_quar);
for ( double s = 0.0; s < 10.0; ++s ) {
std::cout << "(" << quar(s) << "," << dev_quar(s) << "," << dev_dev_quar(s) << ")\n";
}
}