C - 如何编写一个函数,返回真实有价值函数的导数,而不是导数的值

C++ -- How write a function, that return the derivative of a real valued function, not the value of the derivative

本文关键字:函数 何编写 有价值 真实 一个 返回      更新时间:2023-10-16

此函数计算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 中可以编写这样的功能吗?我认为,使用旧标准是不可能的。

一旦您可以在某个点计算函数的值,就可以使用它来实现一般函数。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); };
}

但是,您可能对"自动分化"之类的技术感兴趣,这些技术使您可以直接根据原始功能的定义来表达衍生物,这是以在扩大域(本质上是无限的邻里(工作为代价的。。

这是一种方法。

#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

使用通用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";
    }
}