]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
fixed typo
[ginac.git] / doc / tutorial / ginac.texi
index 992a3ec26b5910441e85294f93e2d0799f5fbbf2..f9bd79131451dde72a9477afdce0f0f00613f321 100644 (file)
@@ -721,6 +721,25 @@ The next sections will outline the general picture of GiNaC's class
 hierarchy and describe the classes of objects that are handled by
 @code{ex}.
 
+@subsection Note: Expressions and STL containers
+
+GiNaC expressions (@code{ex} objects) have value semantics (they can be
+assigned, reassigned and copied like integral types) but the operator
+@code{<} doesn't provide a well-defined ordering on them. In STL-speak,
+expressions are @samp{Assignable} but not @samp{LessThanComparable}.
+
+This implies that in order to use expressions in sorted containers such as
+@code{std::map<>} and @code{std::set<>} you have to supply a suitable
+comparison predicate. GiNaC provides such a predicate, called
+@code{ex_is_less}. For example, a set of expressions should be defined
+as @code{std::set<ex, ex_is_less>}.
+
+Unsorted containers such as @code{std::vector<>} and @code{std::list<>}
+don't pose a problem. A @code{std::vector<ex>} works as expected.
+
+@xref{Information About Expressions}, for more about comparing and ordering
+expressions.
+
 
 @node Automatic evaluation, Error handling, Expressions, Basic Concepts
 @c    node-name, next, previous, up
@@ -742,7 +761,13 @@ evaluation}. GiNaC only performs transformations that are
 
 @itemize @bullet
 @item
-at most of complexity @math{O(n log n)}
+at most of complexity
+@tex
+$O(n\log n)$
+@end tex
+@ifnottex
+@math{O(n log n)}
+@end ifnottex
 @item
 algebraically correct, possibly except for a set of measure zero (e.g.
 @math{x/x} is transformed to @math{1} although this is incorrect for @math{x=0})
@@ -773,7 +798,7 @@ ex MyEx6 = z*(x + y);   // z*(x+y)
 The general rule is that when you construct expressions, GiNaC automatically
 creates them in canonical form, which might differ from the form you typed in
 your program. This may create some awkward looking output (@samp{-y+x} instead
-of @samp{y-x}) but allows for more efficient operation and usually yields
+of @samp{x-y}) but allows for more efficient operation and usually yields
 some immediate simplifications.
 
 @cindex @code{eval()}
@@ -899,7 +924,13 @@ $\sqrt{2}$
 @end ifnottex
 @dots{}
 @item @code{pseries} @tab Power Series, e.g. @math{x-1/6*x^3+1/120*x^5+O(x^7)}
-@item @code{function} @tab A symbolic function like @math{sin(2*x)}
+@item @code{function} @tab A symbolic function like
+@tex
+$\sin 2x$
+@end tex
+@ifnottex
+@math{sin(2*x)}
+@end ifnottex
 @item @code{lst} @tab Lists of expressions @{@math{x}, @math{2*y}, @math{3+z}@}
 @item @code{matrix} @tab @math{m}x@math{n} matrices of expressions
 @item @code{relational} @tab A relation like the identity @math{x}@code{==}@math{y}
@@ -1162,6 +1193,30 @@ can be applied is listed in the following table.
 @end multitable
 @end cartouche
 
+@subsection Converting numbers
+
+Sometimes it is desirable to convert a @code{numeric} object back to a
+built-in arithmetic type (@code{int}, @code{double}, etc.). The @code{numeric}
+class provides a couple of methods for this purpose:
+
+@cindex @code{to_int()}
+@cindex @code{to_long()}
+@cindex @code{to_double()}
+@cindex @code{to_cl_N()}
+@example
+int numeric::to_int() const;
+long numeric::to_long() const;
+double numeric::to_double() const;
+cln::cl_N numeric::to_cl_N() const;
+@end example
+
+@code{to_int()} and @code{to_long()} only work when the number they are
+applied on is an exact integer. Otherwise the program will halt with a
+message like @samp{Not a 32-bit integer}. @code{to_double()} applied on a
+rational number will return a floating-point approximation. Both
+@code{to_int()/to_long()} and @code{to_double()} discard the imaginary
+part of complex numbers.
+
 
 @node Constants, Fundamental containers, Numbers, Basic Concepts
 @c    node-name, next, previous, up
@@ -1280,17 +1335,30 @@ and safe simplifications are carried out like transforming
 The GiNaC class @code{lst} serves for holding a @dfn{list} of arbitrary
 expressions. They are not as ubiquitous as in many other computer algebra
 packages, but are sometimes used to supply a variable number of arguments of
-the same type to GiNaC methods such as @code{subs()} and @code{to_rational()},
-so you should have a basic understanding of them.
+the same type to GiNaC methods such as @code{subs()} and some @code{matrix}
+constructors, so you should have a basic understanding of them.
 
-Lists of up to 16 expressions can be directly constructed from single
+Lists can be constructed by assigning a comma-separated sequence of
 expressions:
 
 @example
 @{
     symbol x("x"), y("y");
-    lst l(x, 2, y, x+y);
-    // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y'
+    lst l;
+    l = x, 2, y, x+y;
+    // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y',
+    // in that order
+    ...
+@end example
+
+There are also constructors that allow direct creation of lists of up to
+16 expressions, which is often more convenient but slightly less efficient:
+
+@example
+    ...
+    // This produces the same list 'l' as above:
+    // lst l(x, 2, y, x+y);
+    // lst l = lst(x, 2, y, x+y);
     ...
 @end example
 
@@ -1345,10 +1413,10 @@ the C++ standard library:
 @example
     ...
     // print the elements of the list (requires #include <iterator>)
-    copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));
+    std::copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));
 
     // sum up the elements of the list (requires #include <numeric>)
-    ex sum = accumulate(l.begin(), l.end(), ex(0));
+    ex sum = std::accumulate(l.begin(), l.end(), ex(0));
     cout << sum << endl;  // prints '2+2*x+2*y'
     ...
 @end example
@@ -1395,8 +1463,9 @@ You can bring the elements of a list into a canonical order with @code{sort()}:
 
 @example
     ...
-    lst l1(x, 2, y, x+y);
-    lst l2(2, x+y, x, y);
+    lst l1, l2;
+    l1 = x, 2, y, x+y;
+    l2 = 2, x+y, x, y;
     l1.sort();
     l2.sort();
     // l1 and l2 are now equal
@@ -1408,7 +1477,8 @@ elements with @code{unique()}:
 
 @example
     ...
-    lst l3(x, 2, 2, 2, y, x+y, y+x);
+    lst l3;
+    l3 = x, 2, 2, 2, y, x+y, y+x;
     l3.unique();        // l3 is now @{x, 2, y, x+y@}
 @}
 @end example
@@ -1504,16 +1574,39 @@ matrix with @math{m} rows and @math{n} columns are accessed with two
 second one in the range 0@dots{}@math{n-1}.
 
 There are a couple of ways to construct matrices, with or without preset
-elements:
+elements. The constructor
+
+@example
+matrix::matrix(unsigned r, unsigned c);
+@end example
+
+creates a matrix with @samp{r} rows and @samp{c} columns with all elements
+set to zero.
+
+The fastest way to create a matrix with preinitialized elements is to assign
+a list of comma-separated expressions to an empty matrix (see below for an
+example). But you can also specify the elements as a (flat) list with
+
+@example
+matrix::matrix(unsigned r, unsigned c, const lst & l);
+@end example
+
+The function
 
 @cindex @code{lst_to_matrix()}
+@example
+ex lst_to_matrix(const lst & l);
+@end example
+
+constructs a matrix from a list of lists, each list representing a matrix row.
+
+There is also a set of functions for creating some special types of
+matrices:
+
 @cindex @code{diag_matrix()}
 @cindex @code{unit_matrix()}
 @cindex @code{symbolic_matrix()}
 @example
-matrix::matrix(unsigned r, unsigned c);
-matrix::matrix(unsigned r, unsigned c, const lst & l);
-ex lst_to_matrix(const lst & l);
 ex diag_matrix(const lst & l);
 ex unit_matrix(unsigned x);
 ex unit_matrix(unsigned r, unsigned c);
@@ -1521,16 +1614,11 @@ 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);
 @end example
 
-The first two functions are @code{matrix} constructors which create a matrix
-with @samp{r} rows and @samp{c} columns. The matrix elements can be
-initialized from a (flat) list of expressions @samp{l}. Otherwise they are
-all set to zero. The @code{lst_to_matrix()} function constructs a matrix
-from a list of lists, each list representing a matrix row. @code{diag_matrix()}
-constructs a diagonal matrix given the list of diagonal elements.
-@code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r} by @samp{c})
-unit matrix. And finally, @code{symbolic_matrix} constructs a matrix filled
-with newly generated symbols made of the specified base name and the
-position of each element in the matrix.
+@code{diag_matrix()} constructs a diagonal matrix given the list of diagonal
+elements. @code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r}
+by @samp{c}) unit matrix. And finally, @code{symbolic_matrix} constructs a
+matrix filled with newly generated symbols made of the specified base name
+and the position of each element in the matrix.
 
 Matrix elements can be accessed and set using the parenthesis (function call)
 operator:
@@ -1544,18 +1632,24 @@ It is also possible to access the matrix elements in a linear fashion with
 the @code{op()} method. But C++-style subscripting with square brackets
 @samp{[]} is not available.
 
-Here are a couple of examples of constructing matrices:
+Here are a couple of examples for constructing matrices:
 
 @example
 @{
     symbol a("a"), b("b");
 
     matrix M(2, 2);
-    M(0, 0) = a;
-    M(1, 1) = b;
+    M = a, 0,
+        0, b;
     cout << M << endl;
      // -> [[a,0],[0,b]]
 
+    matrix M2(2, 2);
+    M2(0, 0) = a;
+    M2(1, 1) = b;
+    cout << M2 << endl;
+     // -> [[a,0],[0,b]]
+
     cout << matrix(2, 2, lst(a, 0, 0, b)) << endl;
      // -> [[a,0],[0,b]]
 
@@ -1592,9 +1686,13 @@ and @math{C}:
 
 @example
 @{
-    matrix A(2, 2, lst(1, 2, 3, 4));
-    matrix B(2, 2, lst(-1, 0, 2, 1));
-    matrix C(2, 2, lst(8, 4, 2, 1));
+    matrix A(2, 2), B(2, 2), C(2, 2);
+    A =  1, 2,
+         3, 4;
+    B = -1, 0,
+         2, 1;
+    C =  8, 4,
+         2, 1;
 
     matrix result = A.mul(B).sub(C.mul_scalar(2));
     cout << result << endl;
@@ -1663,7 +1761,7 @@ computing determinants, traces, and characteristic polynomials:
 @example
 ex matrix::determinant(unsigned algo=determinant_algo::automatic) const;
 ex matrix::trace() const;
-ex matrix::charpoly(const symbol & lambda) const;
+ex matrix::charpoly(const ex & lambda) const;
 @end example
 
 The @samp{algo} argument of @code{determinant()} allows to select
@@ -2393,7 +2491,10 @@ and scalar products):
     symbol x("x"), y("y");
 
     // A is a 2x2 matrix, X is a 2x1 vector
-    matrix A(2, 2, lst(1, 2, 3, 4)), X(2, 1, lst(x, y));
+    matrix A(2, 2), X(2, 1);
+    A = 1, 2,
+        3, 4;
+    X = x, y;
 
     cout << indexed(A, i, i) << endl;
      // -> 5
@@ -2876,6 +2977,7 @@ avoided.
 
 @menu
 * Information About Expressions::
+* Numerical Evaluation::
 * Substituting Expressions::
 * Pattern Matching and Advanced Substitutions::
 * Applying a Function on Subexpressions::
@@ -2891,7 +2993,7 @@ avoided.
 @end menu
 
 
-@node Information About Expressions, Substituting Expressions, Methods and Functions, Methods and Functions
+@node Information About Expressions, Numerical Evaluation, Methods and Functions, Methods and Functions
 @c    node-name, next, previous, up
 @section Getting information about expressions
 
@@ -3088,13 +3190,118 @@ bool ex::is_zero();
 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.
 
+@subsection Ordering expressions
+@cindex @code{ex_is_less} (class)
+@cindex @code{ex_is_equal} (class)
+@cindex @code{compare()}
+
+Sometimes it is necessary to establish a mathematically well-defined ordering
+on a set of arbitrary expressions, for example to use expressions as keys
+in a @code{std::map<>} container, or to bring a vector of expressions into
+a canonical order (which is done internally by GiNaC for sums and products).
+
+The operators @code{<}, @code{>} etc. described in the last section cannot
+be used for this, as they don't implement an ordering relation in the
+mathematical sense. In particular, they are not guaranteed to be
+antisymmetric: if @samp{a} and @samp{b} are different expressions, and
+@code{a < b} yields @code{false}, then @code{b < a} doesn't necessarily
+yield @code{true}.
+
+By default, STL classes and algorithms use the @code{<} and @code{==}
+operators to compare objects, which are unsuitable for expressions, but GiNaC
+provides two functors that can be supplied as proper binary comparison
+predicates to the STL:
+
+@example
+class ex_is_less : public std::binary_function<ex, ex, bool> @{
+public:
+    bool operator()(const ex &lh, const ex &rh) const;
+@};
+
+class ex_is_equal : public std::binary_function<ex, ex, bool> @{
+public:
+    bool operator()(const ex &lh, const ex &rh) const;
+@};
+@end example
+
+For example, to define a @code{map} that maps expressions to strings you
+have to use
+
+@example
+std::map<ex, std::string, ex_is_less> myMap;
+@end example
+
+Omitting the @code{ex_is_less} template parameter will introduce spurious
+bugs because the map operates improperly.
+
+Other examples for the use of the functors:
+
+@example
+std::vector<ex> v;
+// fill vector
+...
+
+// sort vector
+std::sort(v.begin(), v.end(), ex_is_less());
+
+// count the number of expressions equal to '1'
+unsigned num_ones = std::count_if(v.begin(), v.end(),
+                                  std::bind2nd(ex_is_equal(), 1));
+@end example
 
-@node Substituting Expressions, Pattern Matching and Advanced Substitutions, Information About Expressions, Methods and Functions
+The implementation of @code{ex_is_less} uses the member function
+
+@example
+int ex::compare(const ex & other) const;
+@end example
+
+which returns @math{0} if @code{*this} and @code{other} are equal, @math{-1}
+if @code{*this} sorts before @code{other}, and @math{1} if @code{*this} sorts
+after @code{other}.
+
+
+@node Numerical Evaluation, Substituting Expressions, Information About Expressions, Methods and Functions
+@c    node-name, next, previous, up
+@section Numercial Evaluation
+@cindex @code{evalf()}
+
+GiNaC keeps algebraic expressions, numbers and constants in their exact form.
+To evaluate them using floating-point arithmetic you need to call
+
+@example
+ex ex::evalf(int level = 0) const;
+@end example
+
+@cindex @code{Digits}
+The accuracy of the evaluation is controlled by the global object @code{Digits}
+which can be assigned an integer value. The default value of @code{Digits}
+is 17. @xref{Numbers}, for more information and examples.
+
+To evaluate an expression to a @code{double} floating-point number you can
+call @code{evalf()} followed by @code{numeric::to_double()}, like this:
+
+@example
+@{
+    // Approximate sin(x/Pi)
+    symbol x("x");
+    ex e = series(sin(x/Pi), x == 0, 6);
+
+    // Evaluate numerically at x=0.1
+    ex f = evalf(e.subs(x == 0.1));
+
+    // ex_to<numeric> is an unsafe cast, so check the type first
+    if (is_a<numeric>(f)) @{
+        double d = ex_to<numeric>(f).to_double();
+        cout << d << endl;
+         // -> 0.0318256
+    @} else
+        // error
+@}
+@end example
+
+
+@node Substituting Expressions, Pattern Matching and Advanced Substitutions, Numerical Evaluation, Methods and Functions
 @c    node-name, next, previous, up
 @section Substituting expressions
 @cindex @code{subs()}
@@ -3104,6 +3311,7 @@ expressions via the @code{.subs()} method:
 
 @example
 ex ex::subs(const ex & e, unsigned options = 0);
+ex ex::subs(const exmap & m, unsigned options = 0);
 ex ex::subs(const lst & syms, const lst & repls, unsigned options = 0);
 @end example
 
@@ -3127,16 +3335,44 @@ In the first form, @code{subs()} accepts a relational of the form
 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 objects to be
+The second form of @code{subs()} takes an @code{exmap} object which is a
+pair associative container that maps expressions to expressions (currently
+implemented as a @code{std::map}). This is the most efficient one of the
+three @code{subs()} forms and should be used when the number of objects to
+be substituted is large or unknown.
+
+Using this form, the second example from above would look like this:
+
+@example
+@{
+    symbol x("x"), y("y");
+    ex e2 = x*y + x;
+
+    exmap m;
+    m[x] = -2;
+    m[y] = 4;
+    cout << "e2(-2, 4) = " << e2.subs(m) << endl;
+@}
+@end example
+
+The third form of @code{subs()} takes two lists, one for the objects to be
 replaced 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}.
+
+@example
+@{
+    symbol x("x"), y("y");
+    ex e2 = x*y + x;
+
+    cout << "e2(-2, 4) = " << e2.subs(lst(x, y), lst(-2, 4)) << endl;
+@}
+@end example
 
 The optional last argument to @code{subs()} is a combination of
 @code{subs_options} flags. There are two options available:
-@code{subs_options::subs_no_pattern} disables pattern matching, which makes
+@code{subs_options::no_pattern} disables pattern matching, which makes
 large @code{subs()} operations significantly faster if you are not using
-patterns. The second option, @code{subs_options::subs_algebraic} enables
+patterns. The second option, @code{subs_options::algebraic} enables
 algebraic substitutions in products and powers.
 @ref{Pattern Matching and Advanced Substitutions}, for more information
 about patterns and algebraic substitutions.
@@ -3444,7 +3680,7 @@ The last example would be written in C++ in this way:
 @end example
 
 @subsection Algebraic substitutions
-Supplying the @code{subs_options::subs_algebraic} option to @code{subs()}
+Supplying the @code{subs_options::algebraic} option to @code{subs()}
 enables smarter, algebraic substitutions in products and powers. If you want
 to substitute some factors of a product, you only need to list these factors
 in your pattern. Furthermore, if an (integer) power of some expression occurs
@@ -3456,41 +3692,41 @@ An example clarifies it all (hopefully):
 
 @example
 cout << (a*a*a*a+b*b*b*b+pow(x+y,4)).subs(wild()*wild()==pow(wild(),3),
-                                        subs_options::subs_algebraic) << endl;
+                                        subs_options::algebraic) << endl;
 // --> (y+x)^6+b^6+a^6
 
-cout << ((a+b+c)*(a+b+c)).subs(a+b==x,subs_options::subs_algebraic) << endl;
+cout << ((a+b+c)*(a+b+c)).subs(a+b==x,subs_options::algebraic) << endl;
 // --> (c+b+a)^2
 // Powers and products are smart, but addition is just the same.
 
-cout << ((a+b+c)*(a+b+c)).subs(a+b+wild()==x+wild(), subs_options::subs_algebraic)
+cout << ((a+b+c)*(a+b+c)).subs(a+b+wild()==x+wild(), subs_options::algebraic)
                                                                       << endl;
 // --> (x+c)^2
 // As I said: addition is just the same.
 
-cout << (pow(a,5)*pow(b,7)+2*b).subs(b*b*a==x,subs_options::subs_algebraic) << endl;
+cout << (pow(a,5)*pow(b,7)+2*b).subs(b*b*a==x,subs_options::algebraic) << endl;
 // --> x^3*b*a^2+2*b
 
-cout << (pow(a,-5)*pow(b,-7)+2*b).subs(1/(b*b*a)==x,subs_options::subs_algebraic)
+cout << (pow(a,-5)*pow(b,-7)+2*b).subs(1/(b*b*a)==x,subs_options::algebraic)
                                                                        << endl;
 // --> 2*b+x^3*b^(-1)*a^(-2)
 
-cout << (4*x*x*x-2*x*x+5*x-1).subs(x==a,subs_options::subs_algebraic) << endl;
+cout << (4*x*x*x-2*x*x+5*x-1).subs(x==a,subs_options::algebraic) << endl;
 // --> -1-2*a^2+4*a^3+5*a
 
 cout << (4*x*x*x-2*x*x+5*x-1).subs(pow(x,wild())==pow(a,wild()),
-                                subs_options::subs_algebraic) << endl;
+                                subs_options::algebraic) << endl;
 // --> -1+5*x+4*x^3-2*x^2
 // You should not really need this kind of patterns very often now.
 // But perhaps this it's-not-a-bug-it's-a-feature (c/sh)ould still change.
 
 cout << ex(sin(1+sin(x))).subs(sin(wild())==cos(wild()),
-                                subs_options::subs_algebraic) << endl;
+                                subs_options::algebraic) << endl;
 // --> cos(1+cos(x))
 
 cout << expand((a*sin(x+y)*sin(x+y)+a*cos(x+y)*cos(x+y)+b)
         .subs((pow(cos(wild()),2)==1-pow(sin(wild()),2)),
-                                subs_options::subs_algebraic)) << endl;
+                                subs_options::algebraic)) << endl;
 // --> b+a
 @end example
 
@@ -4033,8 +4269,8 @@ constants, functions and indexed objects as well:
 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);
+ex quo(const ex & a, const ex & b, const ex & x);
+ex rem(const ex & a, const ex & b, const ex & x);
 @end example
 
 compute the quotient and remainder of univariate polynomials in the variable
@@ -4043,7 +4279,7 @@ compute the quotient and remainder of univariate polynomials in the variable
 The additional function
 
 @example
-ex prem(const ex & a, const ex & b, const symbol & x);
+ex prem(const ex & a, const ex & b, const ex & x);
 @end example
 
 computes the pseudo-remainder of @samp{a} and @samp{b} which satisfies
@@ -4068,9 +4304,9 @@ in which case the value of @code{q} is undefined.
 The methods
 
 @example
-ex ex::unit(const symbol & x);
-ex ex::content(const symbol & x);
-ex ex::primpart(const symbol & x);
+ex ex::unit(const ex & x);
+ex ex::content(const ex & x);
+ex ex::primpart(const ex & x);
 @end example
 
 return the unit part, content part, and primitive polynomial of a multivariate
@@ -4228,19 +4464,21 @@ general expressions by using the temporary replacement algorithm described
 above. You do this by calling
 
 @example
-ex ex::to_polynomial(lst &l);
+ex ex::to_polynomial(exmap & m);
+ex ex::to_polynomial(lst & l);
 @end example
 or
 @example
-ex ex::to_rational(lst &l);
+ex ex::to_rational(exmap & m);
+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_polynomial()} or @code{.to_rational()}, so it's possible to use
-it on multiple expressions and get consistent results.
+on the expression to be converted. The supplied @code{exmap} or @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_polynomial()} or @code{.to_rational()}, so it's
+possible to use it on multiple expressions and get consistent results.
 
 The difference betwerrn @code{.to_polynomial()} and @code{.to_rational()}
 is probably best illustrated with an example:
@@ -4273,9 +4511,9 @@ The following more useful example will print @samp{sin(x)-cos(x)}:
     ex a = pow(sin(x), 2) - pow(cos(x), 2);
     ex b = sin(x) + cos(x);
     ex q;
-    lst l;
-    divide(a.to_polynomial(l), b.to_polynomial(l), q);
-    cout << q.subs(l) << endl;
+    exmap m;
+    divide(a.to_polynomial(m), b.to_polynomial(m), q);
+    cout << q.subs(m) << endl;
 @}
 @end example
 
@@ -4571,8 +4809,17 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Li2(x)}
 @tab Dilogarithm
 @cindex @code{Li2()}
+@item @code{Li(n, x)}
+@tab classical polylogarithm as well as multiple polylogarithm
+@cindex @code{Li()}
+@item @code{S(n, p, x)}
+@tab Nielsen's generalized polylogarithm
+@cindex @code{S()}
+@item @code{H(n, x)}
+@tab harmonic polylogarithm
+@cindex @code{H()}
 @item @code{zeta(x)}
-@tab Riemann's zeta function
+@tab Riemann's zeta function as well as multiple zeta value
 @cindex @code{zeta()}
 @item @code{zeta(n, x)}
 @tab derivatives of Riemann's zeta function
@@ -4619,6 +4866,25 @@ serious CAS.  It is to be expected that future revisions of the C++
 standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
+@cindex nested sums
+The functions @code{Li}, @code{S}, @code{H} and @code{zeta} share certain
+properties and are refered to as nested sums functions, because they all
+have a uniform representation as nested sums (for mathematical details and
+conventions see @emph{S.Moch, P.Uwer, S.Weinzierl hep-ph/0110083}).
+@code{Li} and @code{zeta} can take @code{lst}s as arguments, in which case
+they represent not classical polylogarithms or simple zeta functions but
+multiple polylogarithms or multiple zeta values respectively (note that the two
+@code{lst}s for @code{Li} must have the same length). The first parameter
+of the harmonic polylogarithm can also be a @code{lst}.
+For all these functions the arguments in the @code{lst}s are expected to be
+in the same order as they appear in the nested sums representation
+(note that this convention differs from the one in the aforementioned paper 
+in the cases of @code{Li} and @code{zeta}).
+If you want to numerically evaluate the functions, the parameters @code{n}
+and @code{p} as well as @code{x} in the case of @code{zeta} must all be
+positive integers (or @code{lst}s containing them). The multiple polylogarithm
+has the additional restriction that the second parameter must only
+contain arguments with an absolute value smaller than one.
 
 @node Solving Linear Systems of Equations, Input/Output, Built-in Functions, Methods and Functions
 @c    node-name, next, previous, up
@@ -4644,12 +4910,11 @@ let us solve the two equations @code{a*x+b*y==3} and @code{x-y==b}:
 @example
 @{
     symbol a("a"), b("b"), x("x"), y("y");
-    lst eqns;
-    eqns.append(a*x+b*y==3).append(x-y==b);
-    lst vars;
-    vars.append(x).append(y);
+    lst eqns, vars;
+    eqns = a*x+b*y==3, x-y==b;
+    vars = x, y;
     cout << lsolve(eqns, vars) << endl;
-    // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
+     // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
 @end example
 
 When the linear equations @code{eqns} are underdetermined, the solution
@@ -4992,7 +5257,8 @@ And the stored expressions can be retrieved by their name:
 
 @example
     // ...
-    lst syms(x, y);
+    lst syms;
+    syms = x, y;
 
     ex ex1 = a2.unarchive_ex(syms, "foo");
     ex ex2 = a2.unarchive_ex(syms, "the second one");
@@ -5105,7 +5371,7 @@ class may change between GiNaC versions.
 @chapter Extending GiNaC
 
 By reading so far you should have gotten a fairly good understanding of
-GiNaC's design-patterns.  From here on you should start reading the
+GiNaC's design patterns.  From here on you should start reading the
 sources.  All we can do now is issue some recommendations how to tackle
 GiNaC's many loose ends in order to fulfill everybody's dreams.  If you
 develop some useful extension please don't hesitate to contact the GiNaC
@@ -5114,6 +5380,7 @@ authors---they will happily incorporate them into future versions.
 @menu
 * What does not belong into GiNaC::  What to avoid.
 * Symbolic functions::               Implementing symbolic functions.
+* Printing::                         Adding new output formats.
 * Structures::                       Defining new algebraic classes (the easy way).
 * Adding classes::                   Defining new algebraic classes (the hard way).
 @end menu
@@ -5143,7 +5410,7 @@ inefficient.  For this purpose, the underlying foundation classes
 provided by CLN are much better suited.
 
 
-@node Symbolic functions, Structures, What does not belong into GiNaC, Extending GiNaC
+@node Symbolic functions, Printing, What does not belong into GiNaC, Extending GiNaC
 @c    node-name, next, previous, up
 @section Symbolic functions
 
@@ -5184,12 +5451,7 @@ that is not further evaluated:
 @example
 DECLARE_FUNCTION_2P(myfcn)
 
-static ex myfcn_eval(const ex & x, const ex & y)
-@{
-    return myfcn(x, y).hold();
-@}
-
-REGISTER_FUNCTION(myfcn, eval_func(myfcn_eval))
+REGISTER_FUNCTION(myfcn, dummy())
 @end example
 
 Any code that has seen the @code{DECLARE_FUNCTION} line can use @code{myfcn()}
@@ -5199,33 +5461,20 @@ in algebraic expressions:
 @{
     ...
     symbol x("x");
-    ex e = 2*myfcn(42, 3*x+1) - x;
-     // this calls myfcn_eval(42, 3*x+1), and inserts its return value into
-     // the actual expression
+    ex e = 2*myfcn(42, 1+3*x) - x;
     cout << e << endl;
      // prints '2*myfcn(42,1+3*x)-x'
     ...
 @}
 @end example
 
-@cindex @code{hold()}
-@cindex evaluation
-The @code{eval_func()} option specifies the C++ function that implements
-the @code{eval()} method, GiNaC's anonymous evaluator. This function takes
-the same number of arguments as the associated symbolic function (two in this
-case) and returns the (possibly transformed or in some way simplified)
-symbolically evaluated function (@xref{Automatic evaluation}, for a description
-of the automatic evaluation process). If no (further) evaluation is to take
-place, the @code{eval_func()} function must return the original function
-with @code{.hold()}, to avoid a potential infinite recursion. If your
-symbolic functions produce a segmentation fault or stack overflow when
-using them in expressions, you are probably missing a @code{.hold()}
-somewhere.
+The @code{dummy()} option in the @code{REGISTER_FUNCTION} line signifies
+"no options". A function with no options specified merely acts as a kind of
+container for its arguments. It is a pure "dummy" function with no associated
+logic (which is, however, sometimes perfectly sufficient).
 
-There is not much you can do with the @code{myfcn} function. It merely acts
-as a kind of container for its arguments (which is, however, sometimes
-perfectly sufficient). Let's have a look at the implementation of GiNaC's
-cosine function.
+Let's now have a look at the implementation of GiNaC's cosine function for an
+example of how to make an "intelligent" function.
 
 @subsection The cosine function
 
@@ -5239,24 +5488,53 @@ which declares to all programs using GiNaC that there is a function @samp{cos}
 that takes one @code{ex} as an argument. This is all they need to know to use
 this function in expressions.
 
-The implementation of the cosine function is in @file{inifcns_trans.cpp}. The
-@code{eval_func()} function looks something like this (actually, it doesn't
-look like this at all, but it should give you an idea what is going on):
+The implementation of the cosine function is in @file{inifcns_trans.cpp}. Here
+is its @code{REGISTER_FUNCTION} line:
+
+@example
+REGISTER_FUNCTION(cos, eval_func(cos_eval).
+                       evalf_func(cos_evalf).
+                       derivative_func(cos_deriv).
+                       latex_name("\\cos"));
+@end example
+
+There are four options defined for the cosine function. One of them
+(@code{latex_name}) gives the function a proper name for LaTeX output; the
+other three indicate the C++ functions in which the "brains" of the cosine
+function are defined.
+
+@cindex @code{hold()}
+@cindex evaluation
+The @code{eval_func()} option specifies the C++ function that implements
+the @code{eval()} method, GiNaC's anonymous evaluator. This function takes
+the same number of arguments as the associated symbolic function (one in this
+case) and returns the (possibly transformed or in some way simplified)
+symbolically evaluated function (@xref{Automatic evaluation}, for a description
+of the automatic evaluation process). If no (further) evaluation is to take
+place, the @code{eval_func()} function must return the original function
+with @code{.hold()}, to avoid a potential infinite recursion. If your
+symbolic functions produce a segmentation fault or stack overflow when
+using them in expressions, you are probably missing a @code{.hold()}
+somewhere.
+
+The @code{eval_func()} function for the cosine looks something like this
+(actually, it doesn't look like this at all, but it should give you an idea
+what is going on):
 
 @example
 static ex cos_eval(const ex & x)
 @{
-    if (<x is a multiple of 2*Pi>)
+    if ("x is a multiple of 2*Pi")
         return 1;
-    else if (<x is a multiple of Pi>)
+    else if ("x is a multiple of Pi")
         return -1;
-    else if (<x is a multiple of Pi/2>)
+    else if ("x is a multiple of Pi/2")
         return 0;
     // more rules...
 
-    else if (<x has the form 'acos(y)'>)
+    else if ("x has the form 'acos(y)'")
         return y;
-    else if (<x has the form 'asin(y)'>)
+    else if ("x has the form 'asin(y)'")
         return sqrt(1-y^2);
     // more rules...
 
@@ -5265,6 +5543,20 @@ static ex cos_eval(const ex & x)
 @}
 @end example
 
+This function is called every time the cosine is used in a symbolic expression:
+
+@example
+@{
+    ...
+    e = cos(Pi);
+     // this calls cos_eval(Pi), and inserts its return value into
+     // the actual expression
+    cout << e << endl;
+     // prints '-1'
+    ...
+@}
+@end example
+
 In this way, @code{cos(4*Pi)} automatically becomes @math{1},
 @code{cos(asin(a+b))} becomes @code{sqrt(1-(a+b)^2)}, etc. If no reasonable
 symbolic transformation can be done, the unmodified function is returned
@@ -5320,7 +5612,7 @@ static ex tan_series(const ex & x, const relational & rel,
     // Find the actual expansion point
     const ex x_pt = x.subs(rel);
 
-    if (<x_pt is not an odd multiple of Pi/2>)
+    if ("x_pt is not an odd multiple of Pi/2")
         throw do_taylor();  // tell function::series() to do Taylor expansion
 
     // On a pole, expand sin()/cos()
@@ -5331,26 +5623,13 @@ static ex tan_series(const ex & x, const relational & rel,
 The @code{series()} implementation of a function @emph{must} return a
 @code{pseries} object, otherwise your code will crash.
 
-Now that all the ingredients have been set up, the @code{REGISTER_FUNCTION}
-macro is used to tell the system how the @code{cos()} function behaves:
-
-@example
-REGISTER_FUNCTION(cos, eval_func(cos_eval).
-                       evalf_func(cos_evalf).
-                       derivative_func(cos_deriv).
-                       latex_name("\\cos"));
-@end example
-
-This registers the @code{cos_eval()}, @code{cos_evalf()} and
-@code{cos_deriv()} C++ functions with the @code{cos()} function, and also
-gives it a proper LaTeX name.
-
 @subsection Function options
 
 GiNaC functions understand several more options which are always
 specified as @code{.option(params)}. None of them are required, but you
-need to specify at least one option to @code{REGISTER_FUNCTION()} (usually
-the @code{eval()} method).
+need to specify at least one option to @code{REGISTER_FUNCTION()}. There
+is a do-nothing option called @code{dummy()} which you can use to define
+functions without any special options.
 
 @example
 eval_func(<C++ function>)
@@ -5408,8 +5687,350 @@ arguments. @xref{Indexed objects}, for an explanation of symmetry
 specifications. GiNaC will automatically rearrange the arguments of
 symmetric functions into a canonical order.
 
+Sometimes you may want to have finer control over how functions are
+displayed in the output. For example, the @code{abs()} function prints
+itself as @samp{abs(x)} in the default output format, but as @samp{|x|}
+in LaTeX mode, and @code{fabs(x)} in C source output. This is achieved
+with the
+
+@example
+print_func<C>(<C++ function>)
+@end example
+
+option which is explained in the next section.
+
+
+@node Printing, Structures, Symbolic functions, Extending GiNaC
+@c    node-name, next, previous, up
+@section GiNaC's expression output system
+
+GiNaC allows the output of expressions in a variety of different formats
+(@pxref{Input/Output}). This section will explain how expression output
+is implemented internally, and how to define your own output formats or
+change the output format of built-in algebraic objects. You will also want
+to read this section if you plan to write your own algebraic classes or
+functions.
+
+@cindex @code{print_context} (class)
+@cindex @code{print_dflt} (class)
+@cindex @code{print_latex} (class)
+@cindex @code{print_tree} (class)
+@cindex @code{print_csrc} (class)
+All the different output formats are represented by a hierarchy of classes
+rooted in the @code{print_context} class, defined in the @file{print.h}
+header file:
+
+@table @code
+@item print_dflt
+the default output format
+@item print_latex
+output in LaTeX mathematical mode
+@item print_tree
+a dump of the internal expression structure (for debugging)
+@item print_csrc
+the base class for C source output
+@item print_csrc_float
+C source output using the @code{float} type
+@item print_csrc_double
+C source output using the @code{double} type
+@item print_csrc_cl_N
+C source output using CLN types
+@end table
+
+The @code{print_context} base class provides two public data members:
+
+@example
+class print_context
+@{
+    ...
+public:
+    std::ostream & s;
+    unsigned options;
+@};
+@end example
+
+@code{s} is a reference to the stream to output to, while @code{options}
+holds flags and modifiers. Currently, there is only one flag defined:
+@code{print_options::print_index_dimensions} instructs the @code{idx} class
+to print the index dimension which is normally hidden.
+
+When you write something like @code{std::cout << e}, where @code{e} is
+an object of class @code{ex}, GiNaC will construct an appropriate
+@code{print_context} object (of a class depending on the selected output
+format), fill in the @code{s} and @code{options} members, and call
+
+@cindex @code{print()}
+@example
+void ex::print(const print_context & c, unsigned level = 0) const;
+@end example
+
+which in turn forwards the call to the @code{print()} method of the
+top-level algebraic object contained in the expression.
+
+Unlike other methods, GiNaC classes don't usually override their
+@code{print()} method to implement expression output. Instead, the default
+implementation @code{basic::print(c, level)} performs a run-time double
+dispatch to a function selected by the dynamic type of the object and the
+passed @code{print_context}. To this end, GiNaC maintains a separate method
+table for each class, similar to the virtual function table used for ordinary
+(single) virtual function dispatch.
+
+The method table contains one slot for each possible @code{print_context}
+type, indexed by the (internally assigned) serial number of the type. Slots
+may be empty, in which case GiNaC will retry the method lookup with the
+@code{print_context} object's parent class, possibly repeating the process
+until it reaches the @code{print_context} base class. If there's still no
+method defined, the method table of the algebraic object's parent class
+is consulted, and so on, until a matching method is found (eventually it
+will reach the combination @code{basic/print_context}, which prints the
+object's class name enclosed in square brackets).
+
+You can think of the print methods of all the different classes and output
+formats as being arranged in a two-dimensional matrix with one axis listing
+the algebraic classes and the other axis listing the @code{print_context}
+classes.
+
+Subclasses of @code{basic} can, of course, also overload @code{basic::print()}
+to implement printing, but then they won't get any of the benefits of the
+double dispatch mechanism (such as the ability for derived classes to
+inherit only certain print methods from its parent, or the replacement of
+methods at run-time).
+
+@subsection Print methods for classes
+
+The method table for a class is set up either in the definition of the class,
+by passing the appropriate @code{print_func<C>()} option to
+@code{GINAC_IMPLEMENT_REGISTERED_CLASS_OPT()} (@xref{Adding classes}, for
+an example), or at run-time using @code{set_print_func<T, C>()}. The latter
+can also be used to override existing methods dynamically.
+
+The argument to @code{print_func<C>()} and @code{set_print_func<T, C>()} can
+be a member function of the class (or one of its parent classes), a static
+member function, or an ordinary (global) C++ function. The @code{C} template
+parameter specifies the appropriate @code{print_context} type for which the
+method should be invoked, while, in the case of @code{set_print_func<>()}, the
+@code{T} parameter specifies the algebraic class (for @code{print_func<>()},
+the class is the one being implemented by
+@code{GINAC_IMPLEMENT_REGISTERED_CLASS_OPT}).
+
+For print methods that are member functions, their first argument must be of
+a type convertible to a @code{const C &}, and the second argument must be an
+@code{unsigned}.
+
+For static members and global functions, the first argument must be of a type
+convertible to a @code{const T &}, the second argument must be of a type
+convertible to a @code{const C &}, and the third argument must be an
+@code{unsigned}. A global function will, of course, not have access to
+private and protected members of @code{T}.
+
+The @code{unsigned} argument of the print methods (and of @code{ex::print()}
+and @code{basic::print()}) is used for proper parenthesizing of the output
+(and by @code{print_tree} for proper indentation). It can be used for similar
+purposes if you write your own output formats.
+
+The explanations given above may seem complicated, but in practice it's
+really simple, as shown in the following example. Suppose that we want to
+display exponents in LaTeX output not as superscripts but with little
+upwards-pointing arrows. This can be achieved in the following way:
+
+@example
+void my_print_power_as_latex(const power & p,
+                             const print_latex & c,
+                             unsigned level)
+@{
+    // get the precedence of the 'power' class
+    unsigned power_prec = p.precedence();
+
+    // if the parent operator has the same or a higher precedence
+    // we need parentheses around the power
+    if (level >= power_prec)
+        c.s << '(';
+
+    // print the basis and exponent, each enclosed in braces, and
+    // separated by an uparrow
+    c.s << '@{';
+    p.op(0).print(c, power_prec);
+    c.s << "@}\\uparrow@{";
+    p.op(1).print(c, power_prec);
+    c.s << '@}';
+
+    // don't forget the closing parenthesis
+    if (level >= power_prec)
+        c.s << ')';
+@}
+                                                                                
+int main()
+@{
+    // a sample expression
+    symbol x("x"), y("y");
+    ex e = -3*pow(x, 3)*pow(y, -2) + pow(x+y, 2) - 1;
+
+    // switch to LaTeX mode
+    cout << latex;
+
+    // this prints "-1+@{(y+x)@}^@{2@}-3 \frac@{x^@{3@}@}@{y^@{2@}@}"
+    cout << e << endl;
+
+    // now we replace the method for the LaTeX output of powers with
+    // 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@}@}"
+    cout << e << endl;
+@}
+@end example
+
+Some notes:
+
+@itemize
+
+@item
+The first argument of @code{my_print_power_as_latex} could also have been
+a @code{const basic &}, the second one a @code{const print_context &}.
+
+@item
+The above code depends on @code{mul} objects converting their operands to
+@code{power} objects for the purpose of printing.
+
+@item
+The output of products including negative powers as fractions is also
+controlled by the @code{mul} class.
+
+@item
+The @code{power/print_latex} method provided by GiNaC prints square roots
+using @code{\sqrt}, but the above code doesn't.
+
+@end itemize
+
+It's not possible to restore a method table entry to its previous or default
+value. Once you have called @code{set_print_func()}, you can only override
+it with another call to @code{set_print_func()}, but you can't easily go back
+to the default behavior again (you can, of course, dig around in the GiNaC
+sources, find the method that is installed at startup
+(@code{power::do_print_latex} in this case), and @code{set_print_func} that
+one; that is, after you circumvent the C++ member access control@dots{}).
+
+@subsection Print methods for functions
+
+Symbolic functions employ a print method dispatch mechanism similar to the
+one used for classes. The methods are specified with @code{print_func<C>()}
+function options. If you don't specify any special print methods, the function
+will be printed with its name (or LaTeX name, if supplied), followed by a
+comma-separated list of arguments enclosed in parentheses.
+
+For example, this is what GiNaC's @samp{abs()} function is defined like:
+
+@example
+static ex abs_eval(const ex & arg) @{ ... @}
+static ex abs_evalf(const ex & arg) @{ ... @}
+                                                                                
+static void abs_print_latex(const ex & arg, const print_context & c)
+@{
+    c.s << "@{|"; arg.print(c); c.s << "|@}";
+@}
+                                                                                
+static void abs_print_csrc_float(const ex & arg, const print_context & c)
+@{
+    c.s << "fabs("; arg.print(c); c.s << ")";
+@}
+                                                                                
+REGISTER_FUNCTION(abs, eval_func(abs_eval).
+                       evalf_func(abs_evalf).
+                       print_func<print_latex>(abs_print_latex).
+                       print_func<print_csrc_float>(abs_print_csrc_float).
+                       print_func<print_csrc_double>(abs_print_csrc_float));
+@end example
+
+This will display @samp{abs(x)} as @samp{|x|} in LaTeX mode and @code{fabs(x)}
+in non-CLN C source output, but as @code{abs(x)} in all other formats.
+
+There is currently no equivalent of @code{set_print_func()} for functions.
+
+@subsection Adding new output formats
+
+Creating a new output format involves subclassing @code{print_context},
+which is somewhat similar to adding a new algebraic class
+(@pxref{Adding classes}). There is a macro @code{GINAC_DECLARE_PRINT_CONTEXT}
+that needs to go into the class definition, and a corresponding macro
+@code{GINAC_IMPLEMENT_PRINT_CONTEXT} that has to appear at global scope.
+Every @code{print_context} class needs to provide a default constructor
+and a constructor from an @code{std::ostream} and an @code{unsigned}
+options value.
+
+Here is an example for a user-defined @code{print_context} class:
+
+@example
+class print_myformat : public print_dflt
+@{
+    GINAC_DECLARE_PRINT_CONTEXT(print_myformat, print_dflt)
+public:
+    print_myformat(std::ostream & os, unsigned opt = 0)
+     : print_dflt(os, opt) @{@}
+@};
+
+print_myformat::print_myformat() : print_dflt(std::cout) @{@}
+
+GINAC_IMPLEMENT_PRINT_CONTEXT(print_myformat, print_dflt)
+@end example
+
+That's all there is to it. None of the actual expression output logic is
+implemented in this class. It merely serves as a selector for choosing
+a particular format. The algorithms for printing expressions in the new
+format are implemented as print methods, as described above.
+
+@code{print_myformat} is a subclass of @code{print_dflt}, so it behaves
+exactly like GiNaC's default output format:
+
+@example
+@{
+    symbol x("x");
+    ex e = pow(x, 2) + 1;
 
-@node Structures, Adding classes, Symbolic functions, Extending GiNaC
+    // this prints "1+x^2"
+    cout << e << endl;
+    
+    // this also prints "1+x^2"
+    e.print(print_myformat()); cout << endl;
+
+    ...
+@}
+@end example
+
+To fill @code{print_myformat} with life, we need to supply appropriate
+print methods with @code{set_print_func()}, like this:
+
+@example
+// This prints powers with '**' instead of '^'. See the LaTeX output
+// example above for explanations.
+void print_power_as_myformat(const power & p,
+                             const print_myformat & c,
+                             unsigned level)
+@{
+    unsigned power_prec = p.precedence();
+    if (level >= power_prec)
+        c.s << '(';
+    p.op(0).print(c, power_prec);
+    c.s << "**";
+    p.op(1).print(c, power_prec);
+    if (level >= power_prec)
+        c.s << ')';
+@}
+
+@{
+    ...
+    // install a new print method for power objects
+    set_print_func<power, print_myformat>(print_power_as_myformat);
+
+    // now this prints "1+x**2"
+    e.print(print_myformat()); cout << endl;
+
+    // but the default format is still "1+x^2"
+    cout << e << endl;
+@}
+@end example
+
+
+@node Structures, Adding classes, Printing, Extending GiNaC
 @c    node-name, next, previous, up
 @section Structures
 
@@ -5535,10 +6156,15 @@ desired, most notably proper output:
 @end example
 
 By default, any structure types you define will be printed as
-@samp{[structure object]}. To override this, you can specialize the
-template's @code{print()} member function. The member functions of
-GiNaC classes are described in more detail in the next section, but
-it shouldn't be hard to figure out what's going on here:
+@samp{[structure object]}. To override this you can either specialize the
+template's @code{print()} member function, or specify print methods with
+@code{set_print_func<>()}, as described in @ref{Printing}. Unfortunately,
+it's not possible to supply class options like @code{print_func<>()} to
+structures, so for a self-contained structure type you need to resort to
+overriding the @code{print()} function, which is also what we will do here.
+
+The member functions of GiNaC classes are described in more detail in the
+next section, but it shouldn't be hard to figure out what's going on here:
 
 @example
 void sprod::print(const print_context & c, unsigned level) const
@@ -5816,7 +6442,7 @@ to the unarchiving functions. This class registry is defined in the
 
 The disadvantage of this proprietary RTTI implementation is that there's
 a little more to do when implementing new classes (C++'s RTTI works more
-or less automatic) but don't worry, most of the work is simplified by
+or less automatically) but don't worry, most of the work is simplified by
 macros.
 
 @subsection A minimalistic example
@@ -5872,7 +6498,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(mystring, basic)
 @end example
 
 The @code{GINAC_DECLARE_REGISTERED_CLASS} and @code{GINAC_IMPLEMENT_REGISTERED_CLASS}
-macros are defined in @file{registrar.h}.  They take the name of the class
+macros are defined in @file{registrar.h}. They take the name of the class
 and its direct superclass as arguments and insert all required declarations
 for the RTTI system. The @code{GINAC_DECLARE_REGISTERED_CLASS} should be
 the first line after the opening brace of the class definition. The
@@ -5881,10 +6507,12 @@ source (at global scope, of course, not inside a function).
 
 @code{GINAC_DECLARE_REGISTERED_CLASS} contains, among other things the
 declarations of the default constructor and a couple of other functions that
-are required.  It also defines a type @code{inherited} which refers to the
+are required. It also defines a type @code{inherited} which refers to the
 superclass so you don't have to modify your code every time you shuffle around
-the class hierarchy.  @code{GINAC_IMPLEMENT_REGISTERED_CLASS} registers the
-class with the GiNaC RTTI.
+the class hierarchy. @code{GINAC_IMPLEMENT_REGISTERED_CLASS} registers the
+class with the GiNaC RTTI (there is also a
+@code{GINAC_IMPLEMENT_REGISTERED_CLASS_OPT} which allows specifying additional
+options for the class, and which we will be using instead in a few minutes).
 
 Now there are seven member functions we have to implement to get a working
 class:
@@ -6053,20 +6681,21 @@ cout << e << endl;
 @end example
 
 Hm, not exactly what we expect, but of course the @code{mystring} class
-doesn't yet know how to print itself. This is done in the @code{print()}
-member function. Let's say that we wanted to print the string surrounded
-by double quotes:
+doesn't yet know how to print itself. This can be done either by implementing
+the @code{print()} member function, or, preferably, by specifying a
+@code{print_func<>()} class option. Let's say that we want to print the string
+surrounded by double quotes:
 
 @example
 class mystring : public basic
 @{
     ...
-public:
-    void print(const print_context &c, unsigned level = 0) const;
+protected:
+    void do_print(const print_context &c, unsigned level = 0) const;
     ...
 @};
 
-void mystring::print(const print_context &c, unsigned level) const
+void mystring::do_print(const print_context &c, unsigned level) const
 @{
     // print_context::s is a reference to an ostream
     c.s << '\"' << str << '\"';
@@ -6074,14 +6703,39 @@ void mystring::print(const print_context &c, unsigned level) const
 @end example
 
 The @code{level} argument is only required for container classes to
-correctly parenthesize the output. Let's try again to print the expression:
+correctly parenthesize the output.
+
+Now we need to tell GiNaC that @code{mystring} objects should use the
+@code{do_print()} member function for printing themselves. For this, we
+replace the line
+
+@example
+GINAC_IMPLEMENT_REGISTERED_CLASS(mystring, basic)
+@end example
+
+with
+
+@example
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mystring, basic,
+  print_func<print_context>(&mystring::do_print))
+@end example
+
+Let's try again to print the expression:
 
 @example
 cout << e << endl;
  // -> "Hello, world!"
 @end example
 
-Much better. The @code{mystring} class can be used in arbitrary expressions:
+Much better. If we wanted to have @code{mystring} objects displayed in a
+different way depending on the output format (default, LaTeX, etc.), we
+would have supplied multiple @code{print_func<>()} options with different
+template parameters (@code{print_dflt}, @code{print_latex}, etc.),
+separated by dots. This is similar to the way options are specified for
+symbolic functions. @xref{Printing}, for a more in-depth description of the
+way expression output is implemented in GiNaC.
+
+The @code{mystring} class can be used in arbitrary expressions:
 
 @example
 e += mystring("GiNaC rulez"); 
@@ -6480,7 +7134,7 @@ inserted.  But it may be useful to remember that this is not what
 happens.  Knowing this will enable you to write much more efficient
 code.  If you still have an uncertain feeling with copy-on-write
 semantics, we recommend you have a look at the
-@uref{http://www.cerfnet.com/~mpcline/c++-faq-lite/, C++-FAQ lite} by
+@uref{http://www.parashift.com/c++-faq-lite/, C++-FAQ lite} by
 Marshall Cline.  Chapter 16 covers this issue and presents an
 implementation which is pretty close to the one in GiNaC.
 
@@ -6740,6 +7394,7 @@ The following shows how to build a simple package using automake
 and the @samp{AM_PATH_GINAC} macro. The program used here is @file{simple.cpp}:
 
 @example
+#include <iostream>
 #include <ginac/ginac.h>
 
 int main()