Reputation: 315
This function calculates the value of the Derivation of the Function Foo at X
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;
}
I would like to write a Funktion, which returned not the value of the derivation at X, but a new function which IS the derivation of the function Foo.
xxxx Deriv( double(* Foo)(double x) )
{
return Derivation of Foo;
}
Then it would be possible to write SecondDeriv = Deriv( Deriv( Foo ))
Is it possible in C++ according to new standard to write such a function ? I think with old standard it was impossible.
Upvotes: 4
Views: 3847
Reputation: 476950
Once you can compute the value of a function at one point, you can use that to implement your general function. Lambda expressions allow you to generate those derived functions easily:
auto MakeDerivative(double (&f)(double)) {
return [=](double x) { return Deriv(f, x); };
}
If you want to be able to use stateful functions, you may need to update your Deriv
to be a function template whose first parameter type is a template parameter. This is true in particular if you want to apply MakeDerivative
repeatedly (since its return types are stateful closures):
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); };
}
However, you may be interested in techniques like "automatic differentiation" which allow you to express the derivative directly in terms of the definition of the original function, at the cost of working on an enlarged domain (an infinitesimal neighbourhood, essentially).
Upvotes: 1
Reputation: 16404
Using generic lambda, implementing a toy derivative
is simple. In the following code, derivative
is a derivative operator in the math sense. It accepts a function double -> double
, produces its derivative 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";
}
}
Upvotes: 1
Reputation: 206567
Here's one way to do it.
#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;
}
Output:
20
300
Upvotes: 1