. Let us at some point
know its meaning
and know the value of its derivative
and
, we don’t need to know anything more - no expression for
nor even meanings
. Consider the function
and ask ourselves: what is its value and the value of its derivative at the point
? Obviously:
and
. Please note that on the right side there are only those numbers that we know.
, and ask about it the same question. It is easy to see that in this case we easily find
and
. Similarly, for
we have
and
. And so on: for any elementary function applied to
, we can calculate the value and the derivative using only two numbers:
and
.
, and we also know only two numbers about it:
and
. Then for the function
we can just as easily calculate both the value and the derivative at the same point; and similarly for any binary operation. For example, for multiplication we have: if
then
and
.class Derivable { double val, deriv; public: Derivable(double _val, double _deriv) : val(_val), deriv(_deriv) {} double getValue() {return val;} double getDerivative() {return deriv;} Derivable operator+(Derivable f) { return Derivable(val + f.val, deriv + f.deriv); } Derivable operator-(Derivable f) { return Derivable(val - f.val, deriv - f.deriv); } Derivable operator*(Derivable f) { return Derivable(val * f.val, deriv * f.val + val * f.deriv); } Derivable operator/(Derivable f) { return Derivable(val / f.val, (deriv * f.val - val * f.deriv) / f.val / f.val); } friend Derivable cos(Derivable f); }; Derivable cos(Derivable f) { return Derivable(cos(f.val), -sin(f.val)*f.deriv); } double everywhere with Derivable - and we get a code that calculates the same function along with its derivative. True, of course, the question arises: where to start? We still know how to get new Derivable , but where do we get the very first Derivable ? In fact, everything is clear. The expressions for our function include, first, various constants, independent of
and, secondly, actually itself
. Any constant
independent of
, it is necessary, of course, to replace Derivable(c, 0) ; and the occurrences of the variable itself
- on Derivable(x0, 1) . (Here, for clarity, x0 means that
for which we calculate the function. In a real program, most likely, the corresponding variable will also be called x ).
together with its derivative: Derivable f(double x, double a) { Derivable xd(x, 1); Derivable ad(a, 0); Derivable two(2, 0); return ad*xd*xd*xd - cos(xd/two); } Naturally, in order not to fence such code, it is easier to add an implicit type conversion to our class: Derivable(double c): val(c), deriv(0) {} and a named constructor for an independent variable: static Derivable IndependendVariable(double x) { return Derivable(x,1); } after which the function code f becomes even simpler: Derivable f(double x, double a) { Derivable xd = Derivable::IndependendVariable(x); return xd*xd*xd*a - cos(xd/2); }
Newton's method (here I, of course, made the operators global, so that a*xd worked; above, they are class members only in order not to clutter the code). If you want to change the equation to be solved, you need to change the function code f and that's it; the derivative will be automatically calculated correctly. (Of course, in this example, it might be easier to calculate the derivative by hand, because the function is simple, but as soon as the equations become more complicated, the possibility of not thinking about the code for calculating the derivative is very convenient.)Derivable , the rest of the code will not even need to be changed!f by the Monte Carlo method? - but still the scope of automatic differentiation is quite wide. (And then, if you really calculate your function by the Monte-Carlo method, how do you even imagine its derivative?)Derivable class a template that accepts the number of independent variables as a template parameter.Derivable class a template that accepts the data type for the function and derivative values as a template parameter (i.e. Derivable ..; Derivable
). Derivable<Derivable >, ? . , : , , , , , . , Derivable<Derivable >, , .
, ; «forward» «reverse» ( . ). , -, , , — .
http://habrahabr.ru/post/63055/
http://en.wikipedia.org/wiki/Automatic_differentiation,
http://www.coin-or.org/CppAD/Doc/mul_level.htm ( Derivable<Derivable >)Derivable ..; Derivable
). Derivable<Derivable >, ? . , : , , , , , . , Derivable<Derivable >, , .
, ; «forward» «reverse» ( . ). , -, , , — .
http://habrahabr.ru/post/63055/
http://en.wikipedia.org/wiki/Automatic_differentiation,
http://www.coin-or.org/CppAD/Doc/mul_level.htm ( Derivable<Derivable >)Derivable ..; Derivable
). Derivable<Derivable >, ? . , : , , , , , . , Derivable<Derivable >, , .
, ; «forward» «reverse» ( . ). , -, , , — .
http://habrahabr.ru/post/63055/
http://en.wikipedia.org/wiki/Automatic_differentiation,
http://www.coin-or.org/CppAD/Doc/mul_level.htm ( Derivable<Derivable >)Derivable ..; Derivable
). Derivable<Derivable >, ? . , : , , , , , . , Derivable<Derivable >, , .
, ; «forward» «reverse» ( . ). , -, , , — .
http://habrahabr.ru/post/63055/
http://en.wikipedia.org/wiki/Automatic_differentiation,
http://www.coin-or.org/CppAD/Doc/mul_level.htm ( Derivable<Derivable >)Derivable ..; Derivable
). Derivable<Derivable >, ? . , : , , , , , . , Derivable<Derivable >, , .
, ; «forward» «reverse» ( . ). , -, , , — .
http://habrahabr.ru/post/63055/
http://en.wikipedia.org/wiki/Automatic_differentiation,
http://www.coin-or.org/CppAD/Doc/mul_level.htm ( Derivable<Derivable >)Source: https://habr.com/ru/post/170729/
All Articles