[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.9 Symbolic differentiation
GiNaC's objects know how to differentiate themselves. Thus, a
polynomial (class add
) knows that its derivative is the sum of
the derivatives of all the monomials:
{ symbol x("x"), y("y"), z("z"); ex P = pow(x, 5) + pow(x, 2) + y; cout << P.diff(x,2) << endl; // -> 20*x^3 + 2 cout << P.diff(y) << endl; // 1 // -> 1 cout << P.diff(z) << endl; // 0 // -> 0 } |
If a second integer parameter n is given, the diff
method
returns the nth derivative.
If every object and every function is told what its derivative
is, all derivatives of composed objects can be calculated using the
chain rule and the product rule. Consider, for instance the expression
1/cosh(x)
. Since the derivative of cosh(x)
is
sinh(x)
and the derivative of pow(x,-1)
is
-pow(x,-2)
, GiNaC can readily compute the composition. It turns
out that the composition is the generating function for Euler Numbers,
i.e. the so called nth Euler number is the coefficient of
x^n/n!
in the expansion of 1/cosh(x)
. We may use this
identity to code a function that generates Euler numbers in just three
lines:
#include <ginac/ginac.h> using namespace GiNaC; ex EulerNumber(unsigned n) { symbol x; const ex generator = pow(cosh(x),-1); return generator.diff(x,n).subs(x==0); } int main() { for (unsigned i=0; i<11; i+=2) std::cout << EulerNumber(i) << std::endl; return 0; } |
When you run it, it produces the sequence 1
, -1
, 5
,
-61
, 1385
, -50521
. We increment the loop variable
i
by two since all odd Euler numbers vanish anyways.