+@cindex @code{tensor} (class)
+@subsection Predefined tensors
+
+Some frequently used special tensors such as the delta, epsilon and metric
+tensors are predefined in GiNaC. They have special properties when
+contracted with other tensor expressions and some of them have constant
+matrix representations (they will evaluate to a number when numeric
+indices are specified).
+
+@cindex @code{delta_tensor()}
+@subsubsection Delta tensor
+
+The delta tensor takes two indices, is symmetric and has the matrix
+representation @code{diag(1,1,1,...)}. It is constructed by the function
+@code{delta_tensor()}:
+
+@example
+@{
+ symbol A("A"), B("B");
+
+ idx i(symbol("i"), 3), j(symbol("j"), 3),
+ k(symbol("k"), 3), l(symbol("l"), 3);
+
+ ex e = indexed(A, i, j) * indexed(B, k, l)
+ * delta_tensor(i, k) * delta_tensor(j, l) << endl;
+ cout << e.simplify_indexed() << endl;
+ // -> B.i.j*A.i.j
+
+ cout << delta_tensor(i, i) << endl;
+ // -> 3
+@}
+@end example
+
+@cindex @code{metric_tensor()}
+@subsubsection General metric tensor
+
+The function @code{metric_tensor()} creates a general symmetric metric
+tensor with two indices that can be used to raise/lower tensor indices. The
+metric tensor is denoted as @samp{g} in the output and if its indices are of
+mixed variance it is automatically replaced by a delta tensor:
+
+@example
+@{
+ symbol A("A");
+
+ varidx mu(symbol("mu"), 4), nu(symbol("nu"), 4), rho(symbol("rho"), 4);
+
+ ex e = metric_tensor(mu, nu) * indexed(A, nu.toggle_variance(), rho);
+ cout << e.simplify_indexed() << endl;
+ // -> A~mu~rho
+
+ e = delta_tensor(mu, nu.toggle_variance()) * metric_tensor(nu, rho);
+ cout << e.simplify_indexed() << endl;
+ // -> g~mu~rho
+
+ e = metric_tensor(mu.toggle_variance(), nu.toggle_variance())
+ * metric_tensor(nu, rho);
+ cout << e.simplify_indexed() << endl;
+ // -> delta.mu~rho
+
+ e = metric_tensor(nu.toggle_variance(), rho.toggle_variance())
+ * metric_tensor(mu, nu) * (delta_tensor(mu.toggle_variance(), rho)
+ + indexed(A, mu.toggle_variance(), rho));
+ cout << e.simplify_indexed() << endl;
+ // -> 4+A.rho~rho
+@}
+@end example
+
+@cindex @code{lorentz_g()}
+@subsubsection Minkowski metric tensor
+
+The Minkowski metric tensor is a special metric tensor with a constant
+matrix representation which is either @code{diag(1, -1, -1, ...)} (negative
+signature, the default) or @code{diag(-1, 1, 1, ...)} (positive signature).
+It is created with the function @code{lorentz_g()} (although it is output as
+@samp{eta}):
+
+@example
+@{
+ varidx mu(symbol("mu"), 4);
+
+ e = delta_tensor(varidx(0, 4), mu.toggle_variance())
+ * lorentz_g(mu, varidx(0, 4)); // negative signature
+ cout << e.simplify_indexed() << endl;
+ // -> 1
+
+ e = delta_tensor(varidx(0, 4), mu.toggle_variance())
+ * lorentz_g(mu, varidx(0, 4), true); // positive signature
+ cout << e.simplify_indexed() << endl;
+ // -> -1
+@}
+@end example
+
+@subsubsection Epsilon tensor
+
+The epsilon tensor is totally antisymmetric, its number of indices is equal
+to the dimension of the index space (the indices must all be of the same
+numeric dimension), and @samp{eps.1.2.3...} (resp. @samp{eps~0~1~2...}) is
+defined to be 1. Its behaviour with indices that have a variance also
+depends on the signature of the metric. Epsilon tensors are output as
+@samp{eps}.
+
+There are three functions defined to create epsilon tensors in 2, 3 and 4
+dimensions:
+
+@example
+ex epsilon_tensor(const ex & i1, const ex & i2);
+ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3);
+ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig = false);
+@end example
+
+The first two functions create an epsilon tensor in 2 or 3 Euclidean
+dimensions, the last function creates an epsilon tensor in a 4-dimensional
+Minkowski space (the last @code{bool} argument specifies whether the metric
+has negative or positive signature, as in the case of the Minkowski metric
+tensor).
+
+@subsection Linear algebra
+
+The @code{matrix} class can be used with indices to do some simple linear
+algebra (linear combinations and products of vectors and matrices, traces
+and scalar products):
+
+@example
+@{
+ idx i(symbol("i"), 2), j(symbol("j"), 2);
+ symbol x("x"), y("y");
+
+ matrix A(2, 2, lst(1, 2, 3, 4)), X(2, 1, lst(x, y));
+
+ cout << indexed(A, i, i) << endl;
+ // -> 5
+
+ ex e = indexed(A, i, j) * indexed(X, j);
+ cout << e.simplify_indexed() << endl;
+ // -> [[ [[2*y+x]], [[4*y+3*x]] ]].i
+
+ e = indexed(A, i, j) * indexed(X, i) + indexed(X, j) * 2;
+ cout << e.simplify_indexed() << endl;
+ // -> [[ [[3*y+3*x,6*y+2*x]] ]].j
+@}
+@end example
+
+You can of course obtain the same results with the @code{matrix::add()},
+@code{matrix::mul()} and @code{matrix::trace()} methods but with indices you
+don't have to worry about transposing matrices.
+
+Matrix indices always start at 0 and their dimension must match the number
+of rows/columns of the matrix. Matrices with one row or one column are
+vectors and can have one or two indices (it doesn't matter whether it's a
+row or a column vector). Other matrices must have two indices.
+
+You should be careful when using indices with variance on matrices. GiNaC
+doesn't look at the variance and doesn't know that @samp{F~mu~nu} and
+@samp{F.mu.nu} are different matrices. In this case you should use only
+one form for @samp{F} and explicitly multiply it with a matrix representation
+of the metric tensor.
+
+
+@node Methods and Functions, Information About Expressions, Indexed objects, Top
+@c node-name, next, previous, up
+@chapter Methods and Functions
+@cindex polynomial
+
+In this chapter the most important algorithms provided by GiNaC will be
+described. Some of them are implemented as functions on expressions,
+others are implemented as methods provided by expression objects. If
+they are methods, there exists a wrapper function around it, so you can
+alternatively call it in a functional way as shown in the simple
+example:
+
+@example
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+int main()
+@{
+ ex x = numeric(1.0);
+
+ cout << "As method: " << sin(x).evalf() << endl;
+ cout << "As function: " << evalf(sin(x)) << endl;
+@}
+@end example
+
+@cindex @code{subs()}
+The general rule is that wherever methods accept one or more parameters
+(@var{arg1}, @var{arg2}, @dots{}) the order of arguments the function
+wrapper accepts is the same but preceded by the object to act on
+(@var{object}, @var{arg1}, @var{arg2}, @dots{}). This approach is the
+most natural one in an OO model but it may lead to confusion for MapleV
+users because where they would type @code{A:=x+1; subs(x=2,A);} GiNaC
+would require @code{A=x+1; subs(A,x==2);} (after proper declaration of
+@code{A} and @code{x}). On the other hand, since MapleV returns 3 on
+@code{A:=x^2+3; coeff(A,x,0);} (GiNaC: @code{A=pow(x,2)+3;
+coeff(A,x,0);}) it is clear that MapleV is not trying to be consistent
+here. Also, users of MuPAD will in most cases feel more comfortable
+with GiNaC's convention. All function wrappers are implemented
+as simple inline functions which just call the corresponding method and
+are only provided for users uncomfortable with OO who are dead set to
+avoid method invocations. Generally, nested function wrappers are much
+harder to read than a sequence of methods and should therefore be
+avoided if possible. On the other hand, not everything in GiNaC is a
+method on class @code{ex} and sometimes calling a function cannot be
+avoided.
+
+@menu
+* Information About Expressions::
+* Substituting Symbols::
+* Polynomial Arithmetic:: Working with polynomials.
+* Rational Expressions:: Working with rational functions.
+* Symbolic Differentiation::
+* Series Expansion:: Taylor and Laurent expansion.
+* Built-in Functions:: List of predefined mathematical functions.
+* Input/Output:: Input and output of expressions.
+@end menu
+
+
+@node Information About Expressions, Substituting Symbols, Methods and Functions, Methods and Functions
+@c node-name, next, previous, up
+@section Getting information about expressions
+
+@subsection Checking expression types
+@cindex @code{is_ex_of_type()}
+@cindex @code{ex_to_numeric()}
+@cindex @code{ex_to_@dots{}}
+@cindex @code{Converting ex to other classes}
+@cindex @code{info()}
+
+Sometimes it's useful to check whether a given expression is a plain number,
+a sum, a polynomial with integer coefficients, or of some other specific type.
+GiNaC provides two functions for this (the first one is actually a macro):
+
+@example
+bool is_ex_of_type(const ex & e, TYPENAME t);
+bool ex::info(unsigned flag);
+@end example
+
+When the test made by @code{is_ex_of_type()} returns true, it is safe to
+call one of the functions @code{ex_to_@dots{}}, where @code{@dots{}} is
+one of the class names (@xref{The Class Hierarchy}, for a list of all
+classes). For example, assuming @code{e} is an @code{ex}:
+
+@example
+@{
+ @dots{}
+ if (is_ex_of_type(e, numeric))
+ numeric n = ex_to_numeric(e);
+ @dots{}
+@}
+@end example
+
+@code{is_ex_of_type()} allows you to check whether the top-level object of
+an expression @samp{e} is an instance of the GiNaC class @samp{t}
+(@xref{The Class Hierarchy}, for a list of all classes). This is most useful,
+e.g., for checking whether an expression is a number, a sum, or a product:
+
+@example
+@{
+ symbol x("x");
+ ex e1 = 42;
+ ex e2 = 4*x - 3;
+ is_ex_of_type(e1, numeric); // true
+ is_ex_of_type(e2, numeric); // false
+ is_ex_of_type(e1, add); // false
+ is_ex_of_type(e2, add); // true
+ is_ex_of_type(e1, mul); // false
+ is_ex_of_type(e2, mul); // false
+@}
+@end example
+
+The @code{info()} method is used for checking certain attributes of
+expressions. The possible values for the @code{flag} argument are defined
+in @file{ginac/flags.h}, the most important being explained in the following
+table:
+
+@cartouche
+@multitable @columnfractions .30 .70
+@item @strong{Flag} @tab @strong{Returns true if the object is@dots{}}
+@item @code{numeric}
+@tab @dots{}a number (same as @code{is_ex_of_type(..., numeric)})
+@item @code{real}
+@tab @dots{}a real integer, rational or float (i.e. is not complex)
+@item @code{rational}
+@tab @dots{}an exact rational number (integers are rational, too)
+@item @code{integer}
+@tab @dots{}a (non-complex) integer
+@item @code{crational}
+@tab @dots{}an exact (complex) rational number (such as @math{2/3+7/2*I})
+@item @code{cinteger}
+@tab @dots{}a (complex) integer (such as @math{2-3*I})
+@item @code{positive}
+@tab @dots{}not complex and greater than 0
+@item @code{negative}
+@tab @dots{}not complex and less than 0
+@item @code{nonnegative}
+@tab @dots{}not complex and greater than or equal to 0
+@item @code{posint}
+@tab @dots{}an integer greater than 0
+@item @code{negint}
+@tab @dots{}an integer less than 0
+@item @code{nonnegint}
+@tab @dots{}an integer greater than or equal to 0
+@item @code{even}
+@tab @dots{}an even integer
+@item @code{odd}
+@tab @dots{}an odd integer
+@item @code{prime}
+@tab @dots{}a prime integer (probabilistic primality test)
+@item @code{relation}
+@tab @dots{}a relation (same as @code{is_ex_of_type(..., relational)})
+@item @code{relation_equal}
+@tab @dots{}a @code{==} relation
+@item @code{relation_not_equal}
+@tab @dots{}a @code{!=} relation
+@item @code{relation_less}
+@tab @dots{}a @code{<} relation
+@item @code{relation_less_or_equal}
+@tab @dots{}a @code{<=} relation
+@item @code{relation_greater}
+@tab @dots{}a @code{>} relation
+@item @code{relation_greater_or_equal}
+@tab @dots{}a @code{>=} relation
+@item @code{symbol}
+@tab @dots{}a symbol (same as @code{is_ex_of_type(..., symbol)})
+@item @code{list}
+@tab @dots{}a list (same as @code{is_ex_of_type(..., lst)})
+@item @code{polynomial}
+@tab @dots{}a polynomial (i.e. only consists of sums and products of numbers and symbols with positive integer powers)
+@item @code{integer_polynomial}
+@tab @dots{}a polynomial with (non-complex) integer coefficients
+@item @code{cinteger_polynomial}
+@tab @dots{}a polynomial with (possibly complex) integer coefficients (such as @math{2-3*I})
+@item @code{rational_polynomial}
+@tab @dots{}a polynomial with (non-complex) rational coefficients
+@item @code{crational_polynomial}
+@tab @dots{}a polynomial with (possibly complex) rational coefficients (such as @math{2/3+7/2*I})
+@item @code{rational_function}
+@tab @dots{}a rational function (@math{x+y}, @math{z/(x+y)})
+@item @code{algebraic}
+@tab @dots{}an algebraic object (@math{sqrt(2)}, @math{sqrt(x)-1})
+@end multitable
+@end cartouche
+
+
+@subsection Accessing subexpressions
+@cindex @code{nops()}
+@cindex @code{op()}
+@cindex @code{has()}
+@cindex container
+@cindex @code{relational} (class)
+
+GiNaC provides the two methods
+
+@example
+unsigned ex::nops();
+ex ex::op(unsigned i);
+@end example
+
+for accessing the subexpressions in the container-like GiNaC classes like
+@code{add}, @code{mul}, @code{lst}, and @code{function}. @code{nops()}
+determines the number of subexpressions (@samp{operands}) contained, while
+@code{op()} returns the @code{i}-th (0..@code{nops()-1}) subexpression.
+In the case of a @code{power} object, @code{op(0)} will return the basis
+and @code{op(1)} the exponent. For @code{indexed} objects, @code{op(0)}
+is the base expression and @code{op(i)}, @math{i>0} are the indices.
+
+The left-hand and right-hand side expressions of objects of class
+@code{relational} (and only of these) can also be accessed with the methods
+
+@example
+ex ex::lhs();
+ex ex::rhs();
+@end example
+
+Finally, the method
+
+@example
+bool ex::has(const ex & other);
+@end example
+
+checks whether an expression contains the given subexpression @code{other}.
+This only works reliably if @code{other} is of an atomic class such as a
+@code{numeric} or a @code{symbol}. It is, e.g., not possible to verify that
+@code{a+b+c} contains @code{a+c} (or @code{a+b}) as a subexpression.
+
+
+@subsection Comparing expressions
+@cindex @code{is_equal()}
+@cindex @code{is_zero()}
+
+Expressions can be compared with the usual C++ relational operators like
+@code{==}, @code{>}, and @code{<} but if the expressions contain symbols,
+the result is usually not determinable and the result will be @code{false},
+except in the case of the @code{!=} operator. You should also be aware that
+GiNaC will only do the most trivial test for equality (subtracting both
+expressions), so something like @code{(pow(x,2)+x)/x==x+1} will return
+@code{false}.
+
+Actually, if you construct an expression like @code{a == b}, this will be
+represented by an object of the @code{relational} class (@xref{Relations}.)
+which is not evaluated until (explicitly or implicitely) cast to a @code{bool}.
+
+There are also two methods
+
+@example
+bool ex::is_equal(const ex & other);
+bool ex::is_zero();
+@end example
+
+for checking whether one expression is equal to another, or equal to zero,
+respectively.
+
+@strong{Warning:} You will also find an @code{ex::compare()} method in the
+GiNaC header files. This method is however only to be used internally by
+GiNaC to establish a canonical sort order for terms, and using it to compare
+expressions will give very surprising results.
+
+
+@node Substituting Symbols, Polynomial Arithmetic, Information About Expressions, Methods and Functions
+@c node-name, next, previous, up
+@section Substituting symbols
+@cindex @code{subs()}
+
+Symbols can be replaced with expressions via the @code{.subs()} method:
+
+@example
+ex ex::subs(const ex & e);
+ex ex::subs(const lst & syms, const lst & repls);
+@end example
+
+In the first form, @code{subs()} accepts a relational of the form
+@samp{symbol == expression} or a @code{lst} of such relationals. E.g.
+
+@example
+@{
+ symbol x("x"), y("y");
+ ex e1 = 2*x^2-4*x+3;
+ cout << "e1(7) = " << e1.subs(x == 7) << endl;
+ ex e2 = x*y + x;
+ cout << "e2(-2, 4) = " << e2.subs(lst(x == -2, y == 4)) << endl;
+@}
+@end example
+
+will print @samp{73} and @samp{-10}, respectively.
+
+If you specify multiple substitutions, they are performed in parallel, so e.g.
+@code{subs(lst(x == y, y == x))} exchanges @samp{x} and @samp{y}.
+
+The second form of @code{subs()} takes two lists, one for the symbols and
+one for the expressions to be substituted (both lists must contain the same
+number of elements). Using this form, you would write @code{subs(lst(x, y), lst(y, x))}
+to exchange @samp{x} and @samp{y}.
+
+
+@node Polynomial Arithmetic, Rational Expressions, Substituting Symbols, Methods and Functions
+@c node-name, next, previous, up
+@section Polynomial arithmetic
+
+@subsection Expanding and collecting
+@cindex @code{expand()}
+@cindex @code{collect()}
+
+A polynomial in one or more variables has many equivalent
+representations. Some useful ones serve a specific purpose. Consider
+for example the trivariate polynomial @math{4*x*y + x*z + 20*y^2 +
+21*y*z + 4*z^2} (written down here in output-style). It is equivalent
+to the factorized polynomial @math{(x + 5*y + 4*z)*(4*y + z)}. Other
+representations are the recursive ones where one collects for exponents
+in one of the three variable. Since the factors are themselves
+polynomials in the remaining two variables the procedure can be
+repeated. In our expample, two possibilities would be @math{(4*y + z)*x
++ 20*y^2 + 21*y*z + 4*z^2} and @math{20*y^2 + (21*z + 4*x)*y + 4*z^2 +
+x*z}.
+
+To bring an expression into expanded form, its method
+
+@example
+ex ex::expand();
+@end example
+
+may be called. In our example above, this corresponds to @math{4*x*y +
+x*z + 20*y^2 + 21*y*z + 4*z^2}. Again, since the canonical form in
+GiNaC is not easily guessable you should be prepared to see different
+orderings of terms in such sums!
+
+Another useful representation of multivariate polynomials is as a
+univariate polynomial in one of the variables with the coefficients
+being polynomials in the remaining variables. The method
+@code{collect()} accomplishes this task:
+
+@example
+ex ex::collect(const symbol & s);
+@end example
+
+Note that the original polynomial needs to be in expanded form in order
+to be able to find the coefficients properly.
+
+@subsection Degree and coefficients
+@cindex @code{degree()}
+@cindex @code{ldegree()}
+@cindex @code{coeff()}
+
+The degree and low degree of a polynomial can be obtained using the two
+methods
+
+@example
+int ex::degree(const symbol & s);
+int ex::ldegree(const symbol & s);
+@end example
+
+which also work reliably on non-expanded input polynomials (they even work
+on rational functions, returning the asymptotic degree). To extract
+a coefficient with a certain power from an expanded polynomial you use
+
+@example
+ex ex::coeff(const symbol & s, int n);
+@end example
+
+You can also obtain the leading and trailing coefficients with the methods
+
+@example
+ex ex::lcoeff(const symbol & s);
+ex ex::tcoeff(const symbol & s);
+@end example
+
+which are equivalent to @code{coeff(s, degree(s))} and @code{coeff(s, ldegree(s))},
+respectively.
+
+An application is illustrated in the next example, where a multivariate
+polynomial is analyzed:
+
+@example
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+int main()
+@{
+ symbol x("x"), y("y");
+ ex PolyInp = 4*pow(x,3)*y + 5*x*pow(y,2) + 3*y
+ - pow(x+y,2) + 2*pow(y+2,2) - 8;
+ ex Poly = PolyInp.expand();
+
+ for (int i=Poly.ldegree(x); i<=Poly.degree(x); ++i) @{
+ cout << "The x^" << i << "-coefficient is "
+ << Poly.coeff(x,i) << endl;
+ @}
+ cout << "As polynomial in y: "
+ << Poly.collect(y) << endl;
+@}
+@end example
+
+When run, it returns an output in the following fashion:
+
+@example
+The x^0-coefficient is y^2+11*y
+The x^1-coefficient is 5*y^2-2*y
+The x^2-coefficient is -1
+The x^3-coefficient is 4*y
+As polynomial in y: -x^2+(5*x+1)*y^2+(-2*x+4*x^3+11)*y
+@end example
+
+As always, the exact output may vary between different versions of GiNaC
+or even from run to run since the internal canonical ordering is not
+within the user's sphere of influence.
+
+
+@subsection Polynomial division
+@cindex polynomial division
+@cindex quotient
+@cindex remainder
+@cindex pseudo-remainder
+@cindex @code{quo()}
+@cindex @code{rem()}
+@cindex @code{prem()}
+@cindex @code{divide()}
+
+The two functions
+
+@example
+ex quo(const ex & a, const ex & b, const symbol & x);
+ex rem(const ex & a, const ex & b, const symbol & x);
+@end example
+
+compute the quotient and remainder of univariate polynomials in the variable
+@samp{x}. The results satisfy @math{a = b*quo(a, b, x) + rem(a, b, x)}.
+
+The additional function
+
+@example
+ex prem(const ex & a, const ex & b, const symbol & x);
+@end example
+
+computes the pseudo-remainder of @samp{a} and @samp{b} which satisfies
+@math{c*a = b*q + prem(a, b, x)}, where @math{c = b.lcoeff(x) ^ (a.degree(x) - b.degree(x) + 1)}.
+
+Exact division of multivariate polynomials is performed by the function
+
+@example
+bool divide(const ex & a, const ex & b, ex & q);
+@end example
+
+If @samp{b} divides @samp{a} over the rationals, this function returns @code{true}
+and returns the quotient in the variable @code{q}. Otherwise it returns @code{false}
+in which case the value of @code{q} is undefined.
+
+
+@subsection Unit, content and primitive part
+@cindex @code{unit()}
+@cindex @code{content()}
+@cindex @code{primpart()}
+
+The methods
+
+@example
+ex ex::unit(const symbol & x);
+ex ex::content(const symbol & x);
+ex ex::primpart(const symbol & x);
+@end example
+
+return the unit part, content part, and primitive polynomial of a multivariate
+polynomial with respect to the variable @samp{x} (the unit part being the sign
+of the leading coefficient, the content part being the GCD of the coefficients,
+and the primitive polynomial being the input polynomial divided by the unit and
+content parts). The product of unit, content, and primitive part is the
+original polynomial.
+
+
+@subsection GCD and LCM
+@cindex GCD
+@cindex LCM
+@cindex @code{gcd()}
+@cindex @code{lcm()}
+
+The functions for polynomial greatest common divisor and least common
+multiple have the synopsis
+
+@example
+ex gcd(const ex & a, const ex & b);
+ex lcm(const ex & a, const ex & b);
+@end example
+
+The functions @code{gcd()} and @code{lcm()} accept two expressions
+@code{a} and @code{b} as arguments and return a new expression, their
+greatest common divisor or least common multiple, respectively. If the
+polynomials @code{a} and @code{b} are coprime @code{gcd(a,b)} returns 1
+and @code{lcm(a,b)} returns the product of @code{a} and @code{b}.
+
+@example
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+int main()
+@{
+ symbol x("x"), y("y"), z("z");
+ ex P_a = 4*x*y + x*z + 20*pow(y, 2) + 21*y*z + 4*pow(z, 2);
+ ex P_b = x*y + 3*x*z + 5*pow(y, 2) + 19*y*z + 12*pow(z, 2);
+
+ ex P_gcd = gcd(P_a, P_b);
+ // x + 5*y + 4*z
+ ex P_lcm = lcm(P_a, P_b);
+ // 4*x*y^2 + 13*y*x*z + 20*y^3 + 81*y^2*z + 67*y*z^2 + 3*x*z^2 + 12*z^3
+@}
+@end example
+
+
+@node Rational Expressions, Symbolic Differentiation, Polynomial Arithmetic, Methods and Functions
+@c node-name, next, previous, up
+@section Rational expressions
+
+@subsection The @code{normal} method
+@cindex @code{normal()}
+@cindex simplification
+@cindex temporary replacement
+
+Some basic form of simplification of expressions is called for frequently.
+GiNaC provides the method @code{.normal()}, which converts a rational function
+into an equivalent rational function of the form @samp{numerator/denominator}
+where numerator and denominator are coprime. If the input expression is already
+a fraction, it just finds the GCD of numerator and denominator and cancels it,
+otherwise it performs fraction addition and multiplication.
+
+@code{.normal()} can also be used on expressions which are not rational functions
+as it will replace all non-rational objects (like functions or non-integer
+powers) by temporary symbols to bring the expression to the domain of rational
+functions before performing the normalization, and re-substituting these
+symbols afterwards. This algorithm is also available as a separate method
+@code{.to_rational()}, described below.
+
+This means that both expressions @code{t1} and @code{t2} are indeed
+simplified in this little program:
+
+@example
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+int main()
+@{
+ symbol x("x");
+ ex t1 = (pow(x,2) + 2*x + 1)/(x + 1);
+ ex t2 = (pow(sin(x),2) + 2*sin(x) + 1)/(sin(x) + 1);
+ cout << "t1 is " << t1.normal() << endl;
+ cout << "t2 is " << t2.normal() << endl;
+@}
+@end example
+
+Of course this works for multivariate polynomials too, so the ratio of
+the sample-polynomials from the section about GCD and LCM above would be
+normalized to @code{P_a/P_b} = @code{(4*y+z)/(y+3*z)}.
+
+
+@subsection Numerator and denominator
+@cindex numerator
+@cindex denominator
+@cindex @code{numer()}
+@cindex @code{denom()}
+
+The numerator and denominator of an expression can be obtained with
+
+@example
+ex ex::numer();
+ex ex::denom();
+@end example
+
+These functions will first normalize the expression as described above and
+then return the numerator or denominator, respectively.
+
+
+@subsection Converting to a rational expression
+@cindex @code{to_rational()}
+
+Some of the methods described so far only work on polynomials or rational
+functions. GiNaC provides a way to extend the domain of these functions to
+general expressions by using the temporary replacement algorithm described
+above. You do this by calling
+
+@example
+ex ex::to_rational(lst &l);
+@end example
+
+on the expression to be converted. The supplied @code{lst} will be filled
+with the generated temporary symbols and their replacement expressions in
+a format that can be used directly for the @code{subs()} method. It can also
+already contain a list of replacements from an earlier application of
+@code{.to_rational()}, so it's possible to use it on multiple expressions
+and get consistent results.
+
+For example,
+
+@example
+@{
+ symbol x("x");
+ ex a = pow(sin(x), 2) - pow(cos(x), 2);
+ ex b = sin(x) + cos(x);
+ ex q;
+ lst l;
+ divide(a.to_rational(l), b.to_rational(l), q);
+ cout << q.subs(l) << endl;
+@}
+@end example
+
+will print @samp{sin(x)-cos(x)}.
+
+
+@node Symbolic Differentiation, Series Expansion, Rational Expressions, Methods and Functions
+@c node-name, next, previous, up
+@section Symbolic differentiation
+@cindex differentiation
+@cindex @code{diff()}
+@cindex chain rule
+@cindex product rule
+
+GiNaC's objects know how to differentiate themselves. Thus, a
+polynomial (class @code{add}) knows that its derivative is the sum of
+the derivatives of all the monomials:
+
+@example
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+int main()
+@{
+ 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
+ cout << P.diff(z) << endl; // 0
+@}
+@end example
+
+If a second integer parameter @var{n} is given, the @code{diff} method
+returns the @var{n}th derivative.
+
+If @emph{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
+@code{1/cosh(x)}. Since the derivative of @code{cosh(x)} is
+@code{sinh(x)} and the derivative of @code{pow(x,-1)} is
+@code{-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 @var{n}th Euler number is the coefficient of
+@code{x^n/n!} in the expansion of @code{1/cosh(x)}. We may use this
+identity to code a function that generates Euler numbers in just three
+lines:
+
+@cindex Euler numbers
+@example
+#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)
+ cout << EulerNumber(i) << endl;
+ return 0;
+@}
+@end example
+
+When you run it, it produces the sequence @code{1}, @code{-1}, @code{5},
+@code{-61}, @code{1385}, @code{-50521}. We increment the loop variable
+@code{i} by two since all odd Euler numbers vanish anyways.
+
+
+@node Series Expansion, Built-in Functions, Symbolic Differentiation, Methods and Functions
+@c node-name, next, previous, up
+@section Series expansion
+@cindex @code{series()}