]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
Fixed misprint in the delta tensor example.
[ginac.git] / doc / tutorial / ginac.texi
index 9c4d15ee358bc63991650f005654ed9c9d3722d8..b65e71e16f50767eb19e2c9db211beb46d60527e 100644 (file)
@@ -23,7 +23,7 @@
 This is a tutorial that documents GiNaC @value{VERSION}, an open
 framework for symbolic computation within the C++ programming language.
 
-Copyright (C) 1999-2004 Johannes Gutenberg University Mainz, Germany
+Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany
 
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -52,7 +52,7 @@ notice identical to this one.
 
 @page
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1999-2004 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2005 Johannes Gutenberg University Mainz, Germany
 @sp 2
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -135,7 +135,7 @@ the near future.
 
 @section License
 The GiNaC framework for symbolic computation within the C++ programming
-language is Copyright @copyright{} 1999-2004 Johannes Gutenberg
+language is Copyright @copyright{} 1999-2005 Johannes Gutenberg
 University Mainz, Germany.
 
 This program is free software; you can redistribute it and/or
@@ -602,6 +602,17 @@ insane amounts of memory and CPU time.  Feel free to kill them if your
 machine catches fire.  Another quite important intent is to allow people
 to fiddle around with optimization.
 
+By default, the only documentation that will be built is this tutorial
+in @file{.info} format. To build the GiNaC tutorial and reference manual
+in HTML, DVI, PostScript, or PDF formats, use one of
+
+@example
+$ make html
+$ make dvi
+$ make ps
+$ make pdf
+@end example
+
 Generally, the top-level Makefile runs recursively to the
 subdirectories.  It is therefore safe to go into any subdirectory
 (@code{doc/}, @code{ginsh/}, @dots{}) and simply type @code{make}
@@ -637,7 +648,7 @@ All the header files will be installed into @file{@var{PREFIX}/include/ginac/}
 (or @file{@var{INCLUDEDIR}/ginac/}, if specified).
 
 @item
-All documentation (HTML and Postscript) will be stuffed into
+All documentation (info) will be stuffed into
 @file{@var{PREFIX}/share/doc/GiNaC/} (or
 @file{@var{DATADIR}/doc/GiNaC/}, if @var{DATADIR} was specified).
 
@@ -682,6 +693,7 @@ meta-class for storing all mathematical objects.
 * Lists::                        Lists of expressions.
 * Mathematical functions::       Mathematical functions.
 * Relations::                    Equality, Inequality and all that.
+* Integrals::                    Symbolic integrals.
 * Matrices::                     Matrices.
 * Indexed objects::              Handling indexed quantities.
 * Non-commutative objects::      Algebras with non-commutative products.
@@ -1796,7 +1808,7 @@ point number of class @code{numeric} you should call
 wrapped inside an @code{ex}.
 
 
-@node Relations, Matrices, Mathematical functions, Basic Concepts
+@node Relations, Integrals, Mathematical functions, Basic Concepts
 @c    node-name, next, previous, up
 @section Relations
 @cindex @code{relational} (class)
@@ -1822,8 +1834,68 @@ conversion from @code{relational} to @code{bool} takes place.  Note,
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
+@node Integrals, Matrices, Relations, Basic Concepts
+@c    node-name, next, previous, up
+@section Integrals
+@cindex @code{integral} (class)
+
+An object of class @dfn{integral} can be used to hold a symbolic integral.
+If you want to symbolically represent the integral of @code{x*x} from 0 to
+1, you would write this as
+@example
+integral(x, 0, 1, x*x)
+@end example
+The first argument is the integration variable. It should be noted that
+GiNaC is not very good (yet?) at symbolically evaluating integrals. In
+fact, it can only integrate polynomials. An expression containing integrals
+can be evaluated symbolically by calling the
+@example
+.eval_integ()
+@end example
+method on it. Numerical evaluation is available by calling the
+@example
+.evalf()
+@end example
+method on an expression containing the integral. This will only evaluate
+integrals into a number if @code{subs}ing the integration variable by a
+number in the fourth argument of an integral and then @code{evalf}ing the
+result always results in a number. Of course, also the boundaries of the
+integration domain must @code{evalf} into numbers. It should be noted that
+trying to @code{evalf} a function with discontinuities in the integration
+domain is not recommended. The accuracy of the numeric evaluation of
+integrals is determined by the static member variable
+@example
+ex integral::relative_integration_error
+@end example
+of the class @code{integral}. The default value of this is 10^-8.
+The integration works by halving the interval of integration, until numeric
+stability of the answer indicates that the requested accuracy has been
+reached. The maximum depth of the halving can be set via the static member
+variable
+@example
+int integral::max_integration_level
+@end example
+The default value is 15. If this depth is exceeded, @code{evalf} will simply
+return the integral unevaluated. The function that performs the numerical
+evaluation, is also available as
+@example
+ex adaptivesimpson(const ex & x, const ex & a, const ex & b, const ex & f,
+const ex & error)
+@end example
+This function will throw an exception if the maximum depth is exceeded. The
+last parameter of the function is optional and defaults to the
+@code{relative_integration_error}. To make sure that we do not do too
+much work if an expression contains the same integral multiple times,
+a lookup table is used.
+
+If you know that an expression holds an integral, you can get the
+integration variable, the left boundary, right boundary and integrant by
+respectively calling @code{.op(0)}, @code{.op(1)}, @code{.op(2)}, and
+@code{.op(3)}. Differentiating integrals with respect to variables works
+as expected. Note that it makes no sense to differentiate an integral
+with respect to the integration variable.
 
-@node Matrices, Indexed objects, Relations, Basic Concepts
+@node Matrices, Indexed objects, Integrals, Basic Concepts
 @c    node-name, next, previous, up
 @section Matrices
 @cindex @code{matrix} (class)
@@ -1871,7 +1943,8 @@ ex diag_matrix(const lst & l);
 ex unit_matrix(unsigned x);
 ex unit_matrix(unsigned r, unsigned c);
 ex symbolic_matrix(unsigned r, unsigned c, const string & base_name);
-ex symbolic_matrix(unsigned r, unsigned c, const string & base_name, const string & tex_base_name);
+ex symbolic_matrix(unsigned r, unsigned c, const string & base_name,
+                   const string & tex_base_name);
 @end example
 
 @code{diag_matrix()} constructs a diagonal matrix given the list of diagonal
@@ -2041,7 +2114,8 @@ Matrices may also be inverted using the @code{ex matrix::inverse()}
 method and linear systems may be solved with:
 
 @example
-matrix matrix::solve(const matrix & vars, const matrix & rhs, unsigned algo=solve_algo::automatic) const;
+matrix matrix::solve(const matrix & vars, const matrix & rhs,
+                     unsigned algo=solve_algo::automatic) const;
 @end example
 
 Assuming the matrix object this method is applied on is an @code{m}
@@ -2092,7 +2166,7 @@ one or more indices.
 
 @end itemize
 
-@strong{Note:} when printing expressions, covariant indices and indices
+@strong{Please notice:} when printing expressions, covariant indices and indices
 without variance are denoted @samp{.i} while contravariant indices are
 denoted @samp{~i}. Dotted indices have a @samp{*} in front of the index
 value. In the following, we are going to use that notation in the text so
@@ -2584,7 +2658,7 @@ representation @code{diag(1, 1, 1, ...)}. It is constructed by the function
         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;
+         * delta_tensor(i, k) * delta_tensor(j, l);
     cout << e.simplify_indexed() << endl;
      // -> B.i.j*A.i.j
 
@@ -2712,7 +2786,8 @@ 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);
+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
@@ -2911,11 +2986,18 @@ non-commutative expressions).
 @cindex @code{clifford} (class)
 @subsection Clifford algebra
 
+
+Clifford algebras are supported in two flavours: Dirac gamma
+matrices (more physical) and generic Clifford algebras (more
+mathematical). 
+
 @cindex @code{dirac_gamma()}
-Clifford algebra elements (also called Dirac gamma matrices, although GiNaC
-doesn't treat them as matrices) are designated as @samp{gamma~mu} and satisfy
-@samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where @samp{eta~mu~nu}
-is the Minkowski metric tensor. Dirac gammas are constructed by the function
+@subsubsection Dirac gamma matrices
+Dirac gamma matrices (note that GiNaC doesn't treat them
+as matrices) are designated as @samp{gamma~mu} and satisfy
+@samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where
+@samp{eta~mu~nu} is the Minkowski metric tensor. Dirac gammas are
+constructed by the function
 
 @example
 ex dirac_gamma(const ex & mu, unsigned char rl = 0);
@@ -2935,7 +3017,7 @@ The unity element of a Clifford algebra is constructed by
 ex dirac_ONE(unsigned char rl = 0);
 @end example
 
-@strong{Note:} You must always use @code{dirac_ONE()} when referring to
+@strong{Please notice:} You must always use @code{dirac_ONE()} when referring to
 multiples of the unity element, even though it's customary to omit it.
 E.g. instead of @code{dirac_gamma(mu)*(dirac_slash(q,4)+m)} you have to
 write @code{dirac_gamma(mu)*(dirac_slash(q,4)+m*dirac_ONE())}. Otherwise,
@@ -3002,24 +3084,35 @@ for example
 
 @cindex @code{dirac_trace()}
 To calculate the trace of an expression containing strings of Dirac gammas
-you use the function
+you use one of the functions
 
 @example
+ex dirac_trace(const ex & e, const std::set<unsigned char> & rls,
+               const ex & trONE = 4);
+ex dirac_trace(const ex & e, const lst & rll, const ex & trONE = 4);
 ex dirac_trace(const ex & e, unsigned char rl = 0, const ex & trONE = 4);
 @end example
 
-This function takes the trace of all gammas with the specified representation
-label; gammas with other labels are left standing. The last argument to
+These functions take the trace over all gammas in the specified set @code{rls}
+or list @code{rll} of representation labels, or the single label @code{rl};
+gammas with other labels are left standing. The last argument to
 @code{dirac_trace()} is the value to be returned for the trace of the unity
-element, which defaults to 4. The @code{dirac_trace()} function is a linear
-functional that is equal to the usual trace only in @math{D = 4} dimensions.
-In particular, the functional is not cyclic in @math{D != 4} dimensions when
-acting on expressions containing @samp{gamma5}, so it's not a proper trace.
-This @samp{gamma5} scheme is described in greater detail in
+element, which defaults to 4.
+
+The @code{dirac_trace()} function is a linear functional that is equal to the
+ordinary matrix trace only in @math{D = 4} dimensions. In particular, the
+functional is not cyclic in
+@tex $D \ne 4$
+@end tex
+dimensions when acting on
+expressions containing @samp{gamma5}, so it's not a proper trace. This
+@samp{gamma5} scheme is described in greater detail in
 @cite{The Role of gamma5 in Dimensional Regularization}.
 
 The value of the trace itself is also usually different in 4 and in
-@math{D != 4} dimensions:
+@tex $D \ne 4$
+@end tex
+dimensions:
 
 @example
 @{
@@ -3083,6 +3176,292 @@ You can use this to compare two expressions or for further simplifications:
 @}
 @end example
 
+@cindex @code{clifford_unit()}
+@subsubsection A generic Clifford algebra
+
+A generic Clifford algebra, i.e. a
+@tex
+$2^n$
+@end tex
+dimensional algebra with
+generators 
+@tex $e_k$
+@end tex 
+satisfying the identities 
+@tex
+$e_i e_j + e_j e_i = M(i, j) $
+@end tex
+@ifnottex
+e~i e~j + e~j e~i = M(i, j)
+@end ifnottex
+for some matrix (@code{metric})
+@math{M(i, j)}, which may be non-symmetric and containing symbolic
+entries. Such generators are created by the function
+
+@example
+    ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
+@end example
+
+where @code{mu} should be a @code{varidx} class object indexing the
+generators, @code{metr} defines the metric @math{M(i, j)} and can be
+represented by a square @code{matrix}, @code{tensormetric} or @code{indexed} class
+object, optional parameter @code{rl} allows to distinguish different
+Clifford algebras (which will commute with each other). Note that the call
+@code{clifford_unit(mu, minkmetric())} creates something very close to
+@code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns a
+metric defining this Clifford number.
+
+If the matrix @math{M(i, j)} is in fact symmetric you may prefer to create
+the Clifford algebra units with a call like that
+
+@example
+    ex e = clifford_unit(mu, indexed(M, sy_symm(), i, j));
+@end example
+
+since this may yield some further automatic simplifications.
+
+Individual generators of a Clifford algebra can be accessed in several
+ways. For example 
+
+@example
+@{
+    ... 
+    varidx nu(symbol("nu"), 4);
+    realsymbol s("s");
+    ex M = diag_matrix(lst(1, -1, 0, s));
+    ex e = clifford_unit(nu, M);
+    ex e0 = e.subs(nu == 0);
+    ex e1 = e.subs(nu == 1);
+    ex e2 = e.subs(nu == 2);
+    ex e3 = e.subs(nu == 3);
+    ...
+@}
+@end example
+
+will produce four anti-commuting generators of a Clifford algebra with properties
+@tex
+$e_0^2=1 $, $e_1^2=-1$,  $e_2^2=0$ and $e_3^2=s$.
+@end tex
+@ifnottex
+@code{pow(e0, 2) = 1},  @code{pow(e1, 2) = -1},   @code{pow(e2, 2) = 0} and   @code{pow(e3, 2) = s}. 
+@end ifnottex
+
+@cindex @code{lst_to_clifford()}
+A similar effect can be achieved from the function
+
+@example
+    ex lst_to_clifford(const ex & v, const ex & mu,  const ex & metr,
+                       unsigned char rl = 0);
+    ex lst_to_clifford(const ex & v, const ex & e);
+@end example
+
+which converts a list or vector 
+@tex
+$v = (v^0, v^1, ..., v^n)$
+@end tex
+@ifnottex
+@samp{v = (v~0, v~1, ..., v~n)} 
+@end ifnottex
+into the
+Clifford number 
+@tex
+$v^0 e_0 + v^1 e_1 + ... + v^n e_n$
+@end tex
+@ifnottex
+@samp{v~0 e.0 + v~1 e.1 + ... + v~n e.n}
+@end ifnottex
+with @samp{e.k}
+directly supplied in the second form of the procedure. In the first form
+the Clifford unit @samp{e.k} is generated by the call of
+@code{clifford_unit(mu, metr, rl)}. The previous code may be rewritten
+with the help of @code{lst_to_clifford()} as follows
+
+@example
+@{
+    ...
+    varidx nu(symbol("nu"), 4);
+    realsymbol s("s");
+    ex M = diag_matrix(lst(1, -1, 0, s));
+    ex e0 = lst_to_clifford(lst(1, 0, 0, 0), nu, M);
+    ex e1 = lst_to_clifford(lst(0, 1, 0, 0), nu, M);
+    ex e2 = lst_to_clifford(lst(0, 0, 1, 0), nu, M);
+    ex e3 = lst_to_clifford(lst(0, 0, 0, 1), nu, M);
+  ...
+@}
+@end example
+
+@cindex @code{clifford_to_lst()}
+There is the inverse function 
+
+@example
+    lst clifford_to_lst(const ex & e, const ex & c, bool algebraic = true);
+@end example
+
+which takes an expression @code{e} and tries to find a list
+@tex
+$v = (v^0, v^1, ..., v^n)$
+@end tex
+@ifnottex
+@samp{v = (v~0, v~1, ..., v~n)} 
+@end ifnottex
+such that 
+@tex
+$e = v^0 c_0 + v^1 c_1 + ... + v^n c_n$
+@end tex
+@ifnottex
+@samp{e = v~0 c.0 + v~1 c.1 + ... + v~n c.n}
+@end ifnottex
+with respect to the given Clifford units @code{c} and with none of the
+@samp{v~k} containing Clifford units @code{c} (of course, this
+may be impossible). This function can use an @code{algebraic} method
+(default) or a symbolic one. With the @code{algebraic} method the @samp{v~k} are calculated as
+@tex
+$(e c_k + c_k e)/c_k^2$. If $c_k^2$
+@end tex
+@ifnottex
+@samp{(e c.k + c.k e)/pow(c.k, 2)}.   If @samp{pow(c.k, 2)} 
+@end ifnottex
+is zero or is not a @code{numeric} for some @samp{k}
+then the method will be automatically changed to symbolic. The same effect
+is obtained by the assignment (@code{algebraic = false}) in the procedure call.
+
+@cindex @code{clifford_prime()}
+@cindex @code{clifford_star()}
+@cindex @code{clifford_bar()}
+There are several functions for (anti-)automorphisms of Clifford algebras:
+
+@example
+    ex clifford_prime(const ex & e)
+    inline ex clifford_star(const ex & e) @{ return e.conjugate(); @}
+    inline ex clifford_bar(const ex & e) @{ return clifford_prime(e.conjugate()); @}
+@end example
+
+The automorphism of a Clifford algebra @code{clifford_prime()} simply
+changes signs of all Clifford units in the expression. The reversion
+of a Clifford algebra @code{clifford_star()} coincides with the
+@code{conjugate()} method and effectively reverses the order of Clifford
+units in any product. Finally the main anti-automorphism
+of a Clifford algebra @code{clifford_bar()} is the composition of the
+previous two, i.e. it makes the reversion and changes signs of all Clifford units
+in a product. These functions correspond to the notations
+@math{e'},
+@tex
+$e^*$
+@end tex
+@ifnottex
+e*
+@end ifnottex
+and
+@tex
+$\overline{e}$
+@end tex
+@ifnottex
+@code{\bar@{e@}}
+@end ifnottex
+used in Clifford algebra textbooks.
+
+@cindex @code{clifford_norm()}
+The function
+
+@example
+    ex clifford_norm(const ex & e);
+@end example
+
+@cindex @code{clifford_inverse()}
+calculates the norm of a Clifford number from the expression
+@tex
+$||e||^2 = e\overline{e}$.
+@end tex
+@ifnottex
+@code{||e||^2 = e \bar@{e@}}
+@end ifnottex
+ The inverse of a Clifford expression is returned by the function
+
+@example
+    ex clifford_inverse(const ex & e);
+@end example
+
+which calculates it as 
+@tex
+$e^{-1} = \overline{e}/||e||^2$.
+@end tex
+@ifnottex
+@math{e^@{-1@} = \bar@{e@}/||e||^2}
+@end ifnottex
+ If
+@tex
+$||e|| = 0$
+@end tex
+@ifnottex
+@math{||e||=0}
+@end ifnottex
+then an exception is raised.
+
+@cindex @code{remove_dirac_ONE()}
+If a Clifford number happens to be a factor of
+@code{dirac_ONE()} then we can convert it to a ``real'' (non-Clifford)
+expression by the function
+
+@example
+    ex remove_dirac_ONE(const ex & e);
+@end example
+
+@cindex @code{canonicalize_clifford()}
+The function @code{canonicalize_clifford()} works for a
+generic Clifford algebra in a similar way as for Dirac gammas.
+
+The last provided function is
+
+@cindex @code{clifford_moebius_map()}
+@example
+    ex clifford_moebius_map(const ex & a, const ex & b, const ex & c,
+                            const ex & d, const ex & v, const ex & G,
+                            unsigned char rl = 0);
+    ex clifford_moebius_map(const ex & M, const ex & v, const ex & G,
+                            unsigned char rl = 0);
+@end example 
+
+It takes a list or vector @code{v} and makes the Moebius (conformal or
+linear-fractional) transformation @samp{v -> (av+b)/(cv+d)} defined by
+the matrix @samp{M = [[a, b], [c, d]]}. The parameter @code{G} defines
+the metric of the surrounding (pseudo-)Euclidean space. This can be a
+matrix or a Clifford unit, in the later case the parameter @code{rl} is
+ignored even if supplied.  The returned value of this function is a list
+of components of the resulting vector.
+
+LaTeX output for Clifford units looks like @code{\clifford[1]@{e@}^@{@{\nu@}@}},
+where @code{1} is the @code{representation_label} and @code{\nu} is the
+index of the corresponding unit. This provides a flexible typesetting
+with a suitable defintion of the @code{\clifford} command. For example, the
+definition 
+@example
+    \newcommand@{\clifford@}[1][]@{@}
+@end example
+typesets all Clifford units identically, while the alternative definition
+@example
+    \newcommand@{\clifford@}[2][]@{\ifcase #1 #2\or \tilde@{#2@} \or \breve@{#2@} \fi@}
+@end example
+prints units with @code{representation_label=0} as 
+@tex
+$e$,
+@end tex
+@ifnottex
+@code{e},
+@end ifnottex
+with @code{representation_label=1} as 
+@tex
+$\tilde{e}$
+@end tex
+@ifnottex
+@code{\tilde@{e@}}
+@end ifnottex
+ and with @code{representation_label=2} as 
+@tex
+$\breve{e}$.
+@end tex
+@ifnottex
+@code{\breve@{e@}}.
+@end ifnottex
 
 @cindex @code{color} (class)
 @subsection Color algebra
@@ -3109,7 +3488,7 @@ The unity element of a color algebra is constructed by
 ex color_ONE(unsigned char rl = 0);
 @end example
 
-@strong{Note:} You must always use @code{color_ONE()} when referring to
+@strong{Please notice:} You must always use @code{color_ONE()} when referring to
 multiples of the unity element, even though it's customary to omit it.
 E.g. instead of @code{color_T(a)*(color_T(b)*indexed(X,b)+1)} you have to
 write @code{color_T(a)*(color_T(b)*indexed(X,b)+color_ONE())}. Otherwise,
@@ -3177,16 +3556,19 @@ expressions containing color objects:
 @end example
 
 @cindex @code{color_trace()}
-To calculate the trace of an expression containing color objects you use the
-function
+To calculate the trace of an expression containing color objects you use one
+of the functions
 
 @example
+ex color_trace(const ex & e, const std::set<unsigned char> & rls);
+ex color_trace(const ex & e, const lst & rll);
 ex color_trace(const ex & e, unsigned char rl = 0);
 @end example
 
-This function takes the trace of all color @samp{T} objects with the
-specified representation label; @samp{T}s with other labels are left
-standing. For example:
+These functions take the trace over all color @samp{T} objects in the
+specified set @code{rls} or list @code{rll} of representation labels, or the
+single label @code{rl}; @samp{T}s with other labels are left standing. For
+example:
 
 @example
     ...
@@ -4543,9 +4925,11 @@ together with @code{find()}:
 
 @example
 > a=expand((sin(x)+sin(y))*(1+p+q)*(1+d));
-d*p*sin(x)+p*sin(x)+q*d*sin(x)+q*sin(y)+d*sin(x)+q*d*sin(y)+sin(y)+d*sin(y)+q*sin(x)+d*sin(y)*p+sin(x)+sin(y)*p
+d*p*sin(x)+p*sin(x)+q*d*sin(x)+q*sin(y)+d*sin(x)+q*d*sin(y)+sin(y)+d*sin(y)
++q*sin(x)+d*sin(y)*p+sin(x)+sin(y)*p
 > collect(a,@{p,q@});
-d*sin(x)+(d*sin(x)+sin(y)+d*sin(y)+sin(x))*p+(d*sin(x)+sin(y)+d*sin(y)+sin(x))*q+sin(y)+d*sin(y)+sin(x)
+d*sin(x)+(d*sin(x)+sin(y)+d*sin(y)+sin(x))*p
++(d*sin(x)+sin(y)+d*sin(y)+sin(x))*q+sin(y)+d*sin(y)+sin(x)
 > collect(a,find(a,sin($1)));
 (1+q+d+q*d+d*p+p)*sin(y)+(1+q+d+q*d+d*p+p)*sin(x)
 > collect(a,@{find(a,sin($1)),p,q@});
@@ -4706,6 +5090,7 @@ in which case the value of @code{q} is undefined.
 @cindex @code{unit()}
 @cindex @code{content()}
 @cindex @code{primpart()}
+@cindex @code{unitcontprim()}
 
 The methods
 
@@ -4713,14 +5098,26 @@ The methods
 ex ex::unit(const ex & x);
 ex ex::content(const ex & x);
 ex ex::primpart(const ex & x);
+ex ex::primpart(const ex & x, const ex & c);
 @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.
+content parts). The second variant of @code{primpart()} expects the previously
+calculated content part of the polynomial in @code{c}, which enables it to
+work faster in the case where the content part has already been computed. The
+product of unit, content, and primitive part is the original polynomial.
+
+Additionally, the method
+
+@example
+void ex::unitcontprim(const ex & x, ex & u, ex & c, ex & p);
+@end example
+
+computes the unit, content, and primitive parts in one go, returning them
+in @code{u}, @code{c}, and @code{p}, respectively.
 
 
 @subsection GCD, LCM and resultant
@@ -5254,6 +5651,12 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Li(m, x)}
 @tab classical polylogarithm as well as multiple polylogarithm
 @cindex @code{Li()}
+@item @code{G(a, y)}
+@tab multiple polylogarithm
+@cindex @code{G()}
+@item @code{G(a, s, y)}
+@tab multiple polylogarithm with explicit signs for the imaginary parts
+@cindex @code{G()}
 @item @code{S(n, p, x)}
 @tab Nielsen's generalized polylogarithm
 @cindex @code{S()}
@@ -5327,15 +5730,22 @@ to which others like the harmonic polylogarithm, Nielsen's generalized
 polylogarithm and the multiple zeta value belong.
 Everyone of these functions can also be written as a multiple polylogarithm with specific
 parameters. This whole family of functions is therefore often referred to simply as
-multiple polylogarithms, containing @code{Li}, @code{H}, @code{S} and @code{zeta}.
+multiple polylogarithms, containing @code{Li}, @code{G}, @code{H}, @code{S} and @code{zeta}.
+The multiple polylogarithm itself comes in two variants: @code{Li} and @code{G}. While
+@code{Li} and @code{G} in principle represent the same function, the different
+notations are more natural to the series representation or the integral
+representation, respectively.
 
 To facilitate the discussion of these functions we distinguish between indices and
 arguments as parameters. In the table above indices are printed as @code{m}, @code{s},
-@code{n} or @code{p}, whereas arguments are printed as @code{x}.
+@code{n} or @code{p}, whereas arguments are printed as @code{x}, @code{a} and @code{y}.
 
 To define a @code{Li}, @code{H} or @code{zeta} with a depth greater than one, you have to
 pass a GiNaC @code{lst} for the indices @code{m} and @code{s}, and in the case of @code{Li}
-for the argument @code{x} as well.
+for the argument @code{x} as well. The parameter @code{a} of @code{G} must always be a @code{lst} containing
+the arguments in expanded form. If @code{G} is used with a third parameter @code{s}, @code{s} must
+have the same length as @code{a}. It contains then the signs of the imaginary parts of the arguments. If
+@code{s} is not given, the signs default to +1.
 Note that @code{Li} and @code{zeta} are polymorphic in this respect. They can stand in for
 the classical polylogarithm and Riemann's zeta function (if depth is one), as well as for
 the multiple polylogarithm and the multiple zeta value, respectively. Note also, that
@@ -5383,11 +5793,18 @@ So in comparison to the referenced publications the order of indices and argumen
 is reversed.
 
 The functions only evaluate if the indices are integers greater than zero, except for the indices
-@code{s} in @code{zeta} and @code{m} in @code{H}. Since @code{s} will be interpreted as the sequence
-of signs for the corresponding indices @code{m}, it must contain 1 or -1, e.g.
+@code{s} in @code{zeta} and @code{G} as well as @code{m} in @code{H}. Since @code{s}
+will be interpreted as the sequence of signs for the corresponding indices
+@code{m} or the sign of the imaginary part for the
+corresponding arguments @code{a}, it must contain 1 or -1, e.g.
 @code{zeta(lst(3,4), lst(-1,1))} means
 @tex
-$\zeta(\overline{3},4)$.
+$\zeta(\overline{3},4)$
+@end tex
+and
+@code{G(lst(a,b), lst(-1,1), c)} means
+@tex
+$G(a-0\epsilon,b+0\epsilon;c)$.
 @end tex
 The definition of @code{H} allows indices to be 0, 1 or -1 (in expanded notation) or equally to
 be any integer (in compact notation). With GiNaC expanded and compact notation can be mixed,
@@ -5420,14 +5837,9 @@ Li(@{3,1,3@},@{-x,1,-1@})
 -Li(@{2,1@},@{x,-1@})*log(x)+2*Li(@{3,1@},@{x,-1@})+Li(@{2,2@},@{x,-1@})
 @end example
 
-Every function apart from the multiple polylogarithm @code{Li} can be numerically evaluated for
-arbitrary real or complex arguments. @code{Li} only evaluates if for all arguments
-@tex
-$x_i$ the condition
-@end tex
-@tex
-$x_1x_2\cdots x_i < 1$ holds.
-@end tex
+Every function can be numerically evaluated for
+arbitrary real or complex arguments. The precision is arbitrary and can be set through the
+global variable @code{Digits}:
 
 @example
 > Digits=100;
@@ -5459,6 +5871,9 @@ E.Remiddi, J.A.M.Vermaseren, Int.J.Mod.Phys. A15 (2000), pp. 725-754
 @cite{Special Values of Multiple Polylogarithms}, 
 J.Borwein, D.Bradley, D.Broadhurst, P.Lisonek, Trans.Amer.Math.Soc. 353/3 (2001), pp. 907-941
 
+@cite{Numerical Evaluation of Multiple Polylogarithms}, 
+J.Vollinga, S.Weinzierl, hep-ph/0410259
+
 @node Complex Conjugation, Solving Linear Systems of Equations, Multiple polylogarithms, Methods and Functions
 @c    node-name, next, previous, up
 @section Complex Conjugation
@@ -5503,7 +5918,8 @@ matrix operations that comes in handy when a system of linear equations
 needs to be solved:
 
 @example
-ex lsolve(const ex &eqns, const ex &symbols, unsigned options=solve_algo::automatic);
+ex lsolve(const ex & eqns, const ex & symbols,
+          unsigned options = solve_algo::automatic);
 @end example
 
 Here, @code{eqns} is a @code{lst} of equalities (i.e. class
@@ -5582,7 +5998,8 @@ format to the default, use the @code{dflt} manipulator:
 
 @example
     // ...
-    cout << latex;            // all output to cout will be in LaTeX format from now on
+    cout << latex;            // all output to cout will be in LaTeX format from
+                              // now on
     cout << e << endl;        // prints '4.5 i+\frac@{3@}@{2@} x^@{2@}'
     cout << sin(x/2) << endl; // prints '\sin(\frac@{1@}@{2@} x)'
     cout << dflt;             // revert to default output format
@@ -5673,7 +6090,8 @@ For example, the code snippet
 will print
 
 @example
-    @{(-\ln(\circ))@}+@{(-\gamma_E)@} \circ+@{(\frac@{1@}@{12@} \pi^@{2@})@} \circ^@{2@}+\mathcal@{O@}(\circ^@{3@})
+    @{(-\ln(\circ))@}+@{(-\gamma_E)@} \circ+@{(\frac@{1@}@{12@} \pi^@{2@})@} \circ^@{2@}
+    +\mathcal@{O@}(\circ^@{3@})
 @end example
 
 @cindex @code{index_dimensions}
@@ -6501,7 +6919,8 @@ int main()
     // our own one
     set_print_func<power, print_latex>(my_print_power_as_latex);
 
-    // this prints "-1+@{@{(y+x)@}@}\uparrow@{2@}-3 \frac@{@{x@}\uparrow@{3@}@}@{@{y@}\uparrow@{2@}@}"
+    // this prints "-1+@{@{(y+x)@}@}\uparrow@{2@}-3 \frac@{@{x@}\uparrow@{3@}@}@{@{y@}
+    //              \uparrow@{2@}@}"
     cout << e << endl;
 @}
 @end example
@@ -6845,7 +7264,8 @@ inline bool operator==(const sprod_s & lhs, const sprod_s & rhs)
 
 inline bool operator<(const sprod_s & lhs, const sprod_s & rhs)
 @{
-    return lhs.left.compare(rhs.left) < 0 ? true : lhs.right.compare(rhs.right) < 0;
+    return lhs.left.compare(rhs.left) < 0
+           ? true : lhs.right.compare(rhs.right) < 0;
 @}
 @end example
 
@@ -7169,7 +7589,7 @@ constructor.
 by GiNaC to establish a canonical sort order for terms. It returns 0, +1 or
 -1, depending on the relative order of this object and the @code{other}
 object. If it returns 0, the objects are considered equal.
-@strong{Note:} This has nothing to do with the (numeric) ordering
+@strong{Please notice:} This has nothing to do with the (numeric) ordering
 relationship expressed by @code{<}, @code{>=} etc (which cannot be defined
 for non-numeric classes). For example, @code{numeric(1).compare_same_type(numeric(2))}
 may return +1 even though 1 is clearly smaller than 2. Every GiNaC class
@@ -7903,7 +8323,8 @@ For packages configured using GNU automake, GiNaC also provides
 a macro to automate the process of checking for GiNaC.
 
 @example
-AM_PATH_GINAC([@var{MINIMUM-VERSION}, [@var{ACTION-IF-FOUND} [, @var{ACTION-IF-NOT-FOUND}]]])
+AM_PATH_GINAC([@var{MINIMUM-VERSION}, [@var{ACTION-IF-FOUND}
+              [, @var{ACTION-IF-NOT-FOUND}]]])
 @end example
 
 This macro: