]> www.ginac.de Git - ginac.git/commitdiff
location of C++ FAQ Lite has changed ginac_1-0
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 30 Oct 2003 22:18:16 +0000 (22:18 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 30 Oct 2003 22:18:16 +0000 (22:18 +0000)
doc/tutorial/ginac.texi

index 602e2fc542521b18090f9d80501e3a60b7af6bbe..1fbea8ca36f15cf6eea634b5850ff579d366935b 100644 (file)
@@ -773,7 +773,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
 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{x-y}) but allows for more efficient operation and usually yields
+of @samp{y-x}) but allows for more efficient operation and usually yields
 some immediate simplifications.
 
 @cindex @code{eval()}
 some immediate simplifications.
 
 @cindex @code{eval()}
@@ -808,7 +808,7 @@ at a singularity.
 The @code{pole_error} class has a member function
 
 @example
 The @code{pole_error} class has a member function
 
 @example
-int pole_error::degree() const;
+int pole_error::degree(void) const;
 @end example
 
 that returns the order of the singularity (or 0 when the pole is
 @end example
 
 that returns the order of the singularity (or 0 when the pole is
@@ -831,7 +831,7 @@ exceptions generated by GiNaC:
 using namespace std;
 using namespace GiNaC;
 
 using namespace std;
 using namespace GiNaC;
 
-int main()
+int main(void)
 @{
     try @{
         ...
 @{
     try @{
         ...
@@ -909,7 +909,6 @@ $\sqrt{2}$
 @item @code{varidx} @tab Index with variance
 @item @code{spinidx} @tab Index with variance and dot (used in Weyl-van-der-Waerden spinor formalism)
 @item @code{wildcard} @tab Wildcard for pattern matching
 @item @code{varidx} @tab Index with variance
 @item @code{spinidx} @tab Index with variance and dot (used in Weyl-van-der-Waerden spinor formalism)
 @item @code{wildcard} @tab Wildcard for pattern matching
-@item @code{structure} @tab Template for user-defined classes
 @end multitable
 @end cartouche
 
 @end multitable
 @end cartouche
 
@@ -1275,7 +1274,6 @@ and safe simplifications are carried out like transforming
 @cindex @code{prepend()}
 @cindex @code{remove_first()}
 @cindex @code{remove_last()}
 @cindex @code{prepend()}
 @cindex @code{remove_first()}
 @cindex @code{remove_last()}
-@cindex @code{remove_all()}
 
 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
 
 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
@@ -1305,60 +1303,11 @@ individual elements:
     ...
 @end example
 
     ...
 @end example
 
-As with the standard @code{list<T>} container, accessing random elements of a
-@code{lst} is generally an operation of order @math{O(N)}. Faster read-only
-sequential access to the elements of a list is possible with the
-iterator types provided by the @code{lst} class:
-
-@example
-typedef ... lst::const_iterator;
-typedef ... lst::const_reverse_iterator;
-lst::const_iterator lst::begin() const;
-lst::const_iterator lst::end() const;
-lst::const_reverse_iterator lst::rbegin() const;
-lst::const_reverse_iterator lst::rend() const;
-@end example
-
-For example, to print the elements of a list individually you can use:
-
-@example
-    ...
-    // O(N)
-    for (lst::const_iterator i = l.begin(); i != l.end(); ++i)
-        cout << *i << endl;
-    ...
-@end example
-
-which is one order faster than
-
-@example
-    ...
-    // O(N^2)
-    for (size_t i = 0; i < l.nops(); ++i)
-        cout << l.op(i) << endl;
-    ...
-@end example
-
-These iterators also allow you to use some of the algorithms provided by
-the C++ standard library:
-
-@example
-    ...
-    // print the elements of the list (requires #include <iterator>)
-    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));
-    cout << sum << endl;  // prints '2+2*x+2*y'
-    ...
-@end example
-
 @code{lst} is one of the few GiNaC classes that allow in-place modifications
 (the only other one is @code{matrix}). You can modify single elements:
 
 @example
     ...
 @code{lst} is one of the few GiNaC classes that allow in-place modifications
 (the only other one is @code{matrix}). You can modify single elements:
 
 @example
     ...
-    l[1] = 42;       // l is now @{x, 42, y, x+y@}
     l.let_op(1) = 7; // l is now @{x, 7, y, x+y@}
     ...
 @end example
     l.let_op(1) = 7; // l is now @{x, 7, y, x+y@}
     ...
 @end example
@@ -1383,14 +1332,6 @@ and @code{remove_last()}:
     ...
 @end example
 
     ...
 @end example
 
-You can remove all the elements of a list with @code{remove_all()}:
-
-@example
-    ...
-    l.remove_all();     // l is now empty
-    ...
-@end example
-
 You can bring the elements of a list into a canonical order with @code{sort()}:
 
 @example
 You can bring the elements of a list into a canonical order with @code{sort()}:
 
 @example
@@ -1574,8 +1515,9 @@ Here are a couple of examples of constructing matrices:
 @end example
 
 @cindex @code{transpose()}
 @end example
 
 @cindex @code{transpose()}
+@cindex @code{inverse()}
 There are three ways to do arithmetic with matrices. The first (and most
 There are three ways to do arithmetic with matrices. The first (and most
-direct one) is to use the methods provided by the @code{matrix} class:
+efficient one) is to use the methods provided by the @code{matrix} class:
 
 @example
 matrix matrix::add(const matrix & other) const;
 
 @example
 matrix matrix::add(const matrix & other) const;
@@ -1583,7 +1525,8 @@ matrix matrix::sub(const matrix & other) const;
 matrix matrix::mul(const matrix & other) const;
 matrix matrix::mul_scalar(const ex & other) const;
 matrix matrix::pow(const ex & expn) const;
 matrix matrix::mul(const matrix & other) const;
 matrix matrix::mul_scalar(const ex & other) const;
 matrix matrix::pow(const ex & expn) const;
-matrix matrix::transpose() const;
+matrix matrix::transpose(void) const;
+matrix matrix::inverse(void) const;
 @end example
 
 All of these methods return the result as a new matrix object. Here is an
 @end example
 
 All of these methods return the result as a new matrix object. Here is an
@@ -1661,36 +1604,16 @@ computing determinants, traces, and characteristic polynomials:
 @cindex @code{trace()}
 @cindex @code{charpoly()}
 @example
 @cindex @code{trace()}
 @cindex @code{charpoly()}
 @example
-ex matrix::determinant(unsigned algo=determinant_algo::automatic) const;
-ex matrix::trace() const;
+ex matrix::determinant(unsigned algo = determinant_algo::automatic) const;
+ex matrix::trace(void) const;
 ex matrix::charpoly(const symbol & lambda) const;
 @end example
 
 ex matrix::charpoly(const symbol & lambda) const;
 @end example
 
-The @samp{algo} argument of @code{determinant()} allows to select
-between different algorithms for calculating the determinant.  The
-asymptotic speed (as parametrized by the matrix size) can greatly differ
-between those algorithms, depending on the nature of the matrix'
-entries.  The possible values are defined in the @file{flags.h} header
-file.  By default, GiNaC uses a heuristic to automatically select an
-algorithm that is likely (but not guaranteed) to give the result most
-quickly.
-
-@cindex @code{inverse()}
-@cindex @code{solve()}
-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;
-@end example
-
-Assuming the matrix object this method is applied on is an @code{m}
-times @code{n} matrix, then @code{vars} must be a @code{n} times
-@code{p} matrix of symbolic indeterminates and @code{rhs} a @code{m}
-times @code{p} matrix.  The returned matrix then has dimension @code{n}
-times @code{p} and in the case of an underdetermined system will still
-contain some of the indeterminates from @code{vars}.  If the system is
-overdetermined, an exception is thrown.
+The @samp{algo} argument of @code{determinant()} allows to select between
+different algorithms for calculating the determinant. The possible values
+are defined in the @file{flags.h} header file. By default, GiNaC uses a
+heuristic to automatically select an algorithm that is likely to give the
+result most quickly.
 
 
 @node Indexed objects, Non-commutative objects, Matrices, Basic Concepts
 
 
 @node Indexed objects, Non-commutative objects, Matrices, Basic Concepts
@@ -1755,9 +1678,6 @@ int main()
     symbol A("A");
     cout << indexed(A, i, j) << endl;
      // -> A.i.j
     symbol A("A");
     cout << indexed(A, i, j) << endl;
      // -> A.i.j
-    cout << index_dimensions << indexed(A, i, j) << endl;
-     // -> A.i[3].j[3]
-    cout << dflt; // reset cout to default output format (dimensions hidden)
     ...
 @end example
 
     ...
 @end example
 
@@ -1770,10 +1690,6 @@ construct an expression containing one indexed object, @samp{A.i.j}. It has
 the symbol @code{A} as its base expression and the two indices @code{i} and
 @code{j}.
 
 the symbol @code{A} as its base expression and the two indices @code{i} and
 @code{j}.
 
-The dimensions of indices are normally not visible in the output, but one
-can request them to be printed with the @code{index_dimensions} manipulator,
-as shown above.
-
 Note the difference between the indices @code{i} and @code{j} which are of
 class @code{idx}, and the index values which are the symbols @code{i_sym}
 and @code{j_sym}. The indices of indexed objects cannot directly be symbols
 Note the difference between the indices @code{i} and @code{j} which are of
 class @code{idx}, and the index values which are the symbols @code{i_sym}
 and @code{j_sym}. The indices of indexed objects cannot directly be symbols
@@ -1822,8 +1738,8 @@ anything useful with it.
 The methods
 
 @example
 The methods
 
 @example
-ex idx::get_value();
-ex idx::get_dimension();
+ex idx::get_value(void);
+ex idx::get_dimension(void);
 @end example
 
 return the value and dimension of an @code{idx} object. If you have an index
 @end example
 
 return the value and dimension of an @code{idx} object. If you have an index
@@ -1834,10 +1750,10 @@ object, you can get a reference to the @code{idx} object with the function
 There are also the methods
 
 @example
 There are also the methods
 
 @example
-bool idx::is_numeric();
-bool idx::is_symbolic();
-bool idx::is_dim_numeric();
-bool idx::is_dim_symbolic();
+bool idx::is_numeric(void);
+bool idx::is_symbolic(void);
+bool idx::is_dim_numeric(void);
+bool idx::is_dim_symbolic(void);
 @end example
 
 for checking whether the value and dimension are numeric or symbolic
 @end example
 
 for checking whether the value and dimension are numeric or symbolic
@@ -1868,8 +1784,8 @@ this can be overridden by supplying a third argument to the @code{varidx}
 constructor. The two methods
 
 @example
 constructor. The two methods
 
 @example
-bool varidx::is_covariant();
-bool varidx::is_contravariant();
+bool varidx::is_covariant(void);
+bool varidx::is_contravariant(void);
 @end example
 
 allow you to check the variance of a @code{varidx} object (use @code{ex_to<varidx>()}
 @end example
 
 allow you to check the variance of a @code{varidx} object (use @code{ex_to<varidx>()}
@@ -1877,7 +1793,7 @@ to get the object reference from an expression). There's also the very useful
 method
 
 @example
 method
 
 @example
-ex varidx::toggle_variance();
+ex varidx::toggle_variance(void);
 @end example
 
 which makes a new index with the same value and dimension but the opposite
 @end example
 
 which makes a new index with the same value and dimension but the opposite
@@ -1911,8 +1827,8 @@ supplying a fourth argument to the @code{spinidx} constructor. The two
 methods
 
 @example
 methods
 
 @example
-bool spinidx::is_dotted();
-bool spinidx::is_undotted();
+bool spinidx::is_dotted(void);
+bool spinidx::is_undotted(void);
 @end example
 
 allow you to check whether or not a @code{spinidx} object is dotted (use
 @end example
 
 allow you to check whether or not a @code{spinidx} object is dotted (use
@@ -1920,8 +1836,8 @@ allow you to check whether or not a @code{spinidx} object is dotted (use
 Finally, the two methods
 
 @example
 Finally, the two methods
 
 @example
-ex spinidx::toggle_dot();
-ex spinidx::toggle_variance_dot();
+ex spinidx::toggle_dot(void);
+ex spinidx::toggle_variance_dot(void);
 @end example
 
 create a new index with the same value and dimension but opposite dottedness
 @end example
 
 create a new index with the same value and dimension but opposite dottedness
@@ -2081,7 +1997,7 @@ indices into a canonical order which allows for some immediate simplifications:
 @end example
 
 @cindex @code{get_free_indices()}
 @end example
 
 @cindex @code{get_free_indices()}
-@cindex dummy index
+@cindex Dummy index
 @subsection Dummy indices
 
 GiNaC treats certain symbolic index pairs as @dfn{dummy indices} meaning
 @subsection Dummy indices
 
 GiNaC treats certain symbolic index pairs as @dfn{dummy indices} meaning
@@ -2142,7 +2058,7 @@ and calculating traces and convolutions of matrices and predefined tensors)
 there is the method
 
 @example
 there is the method
 
 @example
-ex ex::simplify_indexed();
+ex ex::simplify_indexed(void);
 ex ex::simplify_indexed(const scalar_products & sp);
 @end example
 
 ex ex::simplify_indexed(const scalar_products & sp);
 @end example
 
@@ -2492,8 +2408,8 @@ Information about the commutativity of an object or expression can be
 obtained with the two member functions
 
 @example
 obtained with the two member functions
 
 @example
-unsigned ex::return_type() const;
-unsigned ex::return_type_tinfo() const;
+unsigned ex::return_type(void) const;
+unsigned ex::return_type_tinfo(void) const;
 @end example
 
 The @code{return_type()} function returns one of three values (defined in
 @end example
 
 The @code{return_type()} function returns one of three values (defined in
@@ -2879,14 +2795,12 @@ avoided.
 * Substituting Expressions::
 * Pattern Matching and Advanced Substitutions::
 * Applying a Function on Subexpressions::
 * Substituting Expressions::
 * Pattern Matching and Advanced Substitutions::
 * Applying a Function on Subexpressions::
-* Visitors and Tree Traversal::
 * Polynomial Arithmetic::           Working with polynomials.
 * Rational Expressions::            Working with rational functions.
 * Symbolic Differentiation::
 * Series Expansion::                Taylor and Laurent expansion.
 * Symmetrization::
 * Built-in Functions::              List of predefined mathematical functions.
 * Polynomial Arithmetic::           Working with polynomials.
 * Rational Expressions::            Working with rational functions.
 * Symbolic Differentiation::
 * Series Expansion::                Taylor and Laurent expansion.
 * Symmetrization::
 * Built-in Functions::              List of predefined mathematical functions.
-* Solving Linear Systems of Equations::
 * Input/Output::                    Input and output of expressions.
 @end menu
 
 * Input/Output::                    Input and output of expressions.
 @end menu
 
@@ -2912,8 +2826,8 @@ GiNaC provides a couple of functions for this:
 bool is_a<T>(const ex & e);
 bool is_exactly_a<T>(const ex & e);
 bool ex::info(unsigned flag);
 bool is_a<T>(const ex & e);
 bool is_exactly_a<T>(const ex & e);
 bool ex::info(unsigned flag);
-unsigned ex::return_type() const;
-unsigned ex::return_type_tinfo() const;
+unsigned ex::return_type(void) const;
+unsigned ex::return_type_tinfo(void) const;
 @end example
 
 When the test made by @code{is_a<T>()} returns true, it is safe to call
 @end example
 
 When the test made by @code{is_a<T>()} returns true, it is safe to call
@@ -3041,8 +2955,8 @@ for an explanation of these.
 GiNaC provides the two methods
 
 @example
 GiNaC provides the two methods
 
 @example
-size_t ex::nops();
-ex ex::op(size_t i);
+unsigned ex::nops();
+ex ex::op(unsigned i);
 @end example
 
 for accessing the subexpressions in the container-like GiNaC classes like
 @end example
 
 for accessing the subexpressions in the container-like GiNaC classes like
@@ -3088,75 +3002,10 @@ bool ex::is_zero();
 for checking whether one expression is equal to another, or equal to zero,
 respectively.
 
 for checking whether one expression is equal to another, or equal to zero,
 respectively.
 
-
-@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
-
-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}.
+@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 Expressions, Pattern Matching and Advanced Substitutions, Information About Expressions, Methods and Functions
 
 
 @node Substituting Expressions, Pattern Matching and Advanced Substitutions, Information About Expressions, Methods and Functions
@@ -3168,8 +3017,8 @@ Algebraic objects inside expressions can be replaced with arbitrary
 expressions via the @code{.subs()} method:
 
 @example
 expressions via the @code{.subs()} method:
 
 @example
-ex ex::subs(const ex & e, unsigned options = 0);
-ex ex::subs(const lst & syms, const lst & repls, unsigned options = 0);
+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
 @end example
 
 In the first form, @code{subs()} accepts a relational of the form
@@ -3197,15 +3046,6 @@ 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}.
 
 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}.
 
-The optional last argument to @code{subs()} is a combination of
-@code{subs_options} flags. There are two options available:
-@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::algebraic} enables
-algebraic substitutions in products and powers.
-@ref{Pattern Matching and Advanced Substitutions}, for more information
-about patterns and algebraic substitutions.
-
 @code{subs()} performs syntactic substitution of any complete algebraic
 object; it does not try to match sub-expressions as is demonstrated by the
 following example:
 @code{subs()} performs syntactic substitution of any complete algebraic
 object; it does not try to match sub-expressions as is demonstrated by the
 following example:
@@ -3446,9 +3286,9 @@ bool ex::find(const ex & pattern, lst & found);
 @end example
 
 works a bit like @code{has()} but it doesn't stop upon finding the first
 @end example
 
 works a bit like @code{has()} but it doesn't stop upon finding the first
-match. Instead, it appends all found matches to the specified list. If there
-are multiple occurrences of the same expression, it is entered only once to
-the list. @code{find()} returns false if no matches were found (in
+match. Instead, it inserts all found matches into the specified list. If
+there are multiple occurrences of the same expression, it is entered only
+once to the list. @code{find()} returns false if no matches were found (in
 @command{ginsh}, it returns an empty list):
 
 @example
 @command{ginsh}, it returns an empty list):
 
 @example
@@ -3508,62 +3348,11 @@ The last example would be written in C++ in this way:
 @}
 @end example
 
 @}
 @end example
 
-@subsection Algebraic substitutions
-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
-in your pattern and in the expression that you want the substitution to occur
-in, it can be substituted as many times as possible, without getting negative
-powers.
-
-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::algebraic) << endl;
-// --> (y+x)^6+b^6+a^6
-
-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::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::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::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::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::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::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::algebraic)) << endl;
-// --> b+a
-@end example
 
 
-
-@node Applying a Function on Subexpressions, Visitors and Tree Traversal, Pattern Matching and Advanced Substitutions, Methods and Functions
+@node Applying a Function on Subexpressions, Polynomial Arithmetic, Pattern Matching and Advanced Substitutions, Methods and Functions
 @c    node-name, next, previous, up
 @section Applying a Function on Subexpressions
 @c    node-name, next, previous, up
 @section Applying a Function on Subexpressions
-@cindex tree traversal
+@cindex Tree traversal
 @cindex @code{map()}
 
 Sometimes you may want to perform an operation on specific parts of an
 @cindex @code{map()}
 
 Sometimes you may want to perform an operation on specific parts of an
@@ -3580,7 +3369,7 @@ ex calc_trace(ex e)
         return ex_to<matrix>(e).trace();
     else if (is_a<add>(e)) @{
         ex sum = 0;
         return ex_to<matrix>(e).trace();
     else if (is_a<add>(e)) @{
         ex sum = 0;
-        for (size_t i=0; i<e.nops(); i++)
+        for (unsigned i=0; i<e.nops(); i++)
             sum += calc_trace(e.op(i));
         return sum;
     @} else if (is_a<mul>)(e)) @{
             sum += calc_trace(e.op(i));
         return sum;
     @} else if (is_a<mul>)(e)) @{
@@ -3705,214 +3494,7 @@ argument. You can not use functions like @samp{diff()}, @samp{op()},
 @end example
 
 
 @end example
 
 
-@node Visitors and Tree Traversal, Polynomial Arithmetic, Applying a Function on Subexpressions, Methods and Functions
-@c    node-name, next, previous, up
-@section Visitors and Tree Traversal
-@cindex tree traversal
-@cindex @code{visitor} (class)
-@cindex @code{accept()}
-@cindex @code{visit()}
-@cindex @code{traverse()}
-@cindex @code{traverse_preorder()}
-@cindex @code{traverse_postorder()}
-
-Suppose that you need a function that returns a list of all indices appearing
-in an arbitrary expression. The indices can have any dimension, and for
-indices with variance you always want the covariant version returned.
-
-You can't use @code{get_free_indices()} because you also want to include
-dummy indices in the list, and you can't use @code{find()} as it needs
-specific index dimensions (and it would require two passes: one for indices
-with variance, one for plain ones).
-
-The obvious solution to this problem is a tree traversal with a type switch,
-such as the following:
-
-@example
-void gather_indices_helper(const ex & e, lst & l)
-@{
-    if (is_a<varidx>(e)) @{
-        const varidx & vi = ex_to<varidx>(e);
-        l.append(vi.is_covariant() ? vi : vi.toggle_variance());
-    @} else if (is_a<idx>(e)) @{
-        l.append(e);
-    @} else @{
-        size_t n = e.nops();
-        for (size_t i = 0; i < n; ++i)
-            gather_indices_helper(e.op(i), l);
-    @}
-@}
-
-lst gather_indices(const ex & e)
-@{
-    lst l;
-    gather_indices_helper(e, l);
-    l.sort();
-    l.unique();
-    return l;
-@}
-@end example
-
-This works fine but fans of object-oriented programming will feel
-uncomfortable with the type switch. One reason is that there is a possibility
-for subtle bugs regarding derived classes. If we had, for example, written
-
-@example
-    if (is_a<idx>(e)) @{
-      ...
-    @} else if (is_a<varidx>(e)) @{
-      ...
-@end example
-
-in @code{gather_indices_helper}, the code wouldn't have worked because the
-first line "absorbs" all classes derived from @code{idx}, including
-@code{varidx}, so the special case for @code{varidx} would never have been
-executed.
-
-Also, for a large number of classes, a type switch like the above can get
-unwieldy and inefficient (it's a linear search, after all).
-@code{gather_indices_helper} only checks for two classes, but if you had to
-write a function that required a different implementation for nearly
-every GiNaC class, the result would be very hard to maintain and extend.
-
-The cleanest approach to the problem would be to add a new virtual function
-to GiNaC's class hierarchy. In our example, there would be specializations
-for @code{idx} and @code{varidx} while the default implementation in
-@code{basic} performed the tree traversal. Unfortunately, in C++ it's
-impossible to add virtual member functions to existing classes without
-changing their source and recompiling everything. GiNaC comes with source,
-so you could actually do this, but for a small algorithm like the one
-presented this would be impractical.
-
-One solution to this dilemma is the @dfn{Visitor} design pattern,
-which is implemented in GiNaC (actually, Robert Martin's Acyclic Visitor
-variation, described in detail in
-@uref{http://objectmentor.com/publications/acv.pdf}). Instead of adding
-virtual functions to the class hierarchy to implement operations, GiNaC
-provides a single "bouncing" method @code{accept()} that takes an instance
-of a special @code{visitor} class and redirects execution to the one
-@code{visit()} virtual function of the visitor that matches the type of
-object that @code{accept()} was being invoked on.
-
-Visitors in GiNaC must derive from the global @code{visitor} class as well
-as from the class @code{T::visitor} of each class @code{T} they want to
-visit, and implement the member functions @code{void visit(const T &)} for
-each class.
-
-A call of
-
-@example
-void ex::accept(visitor & v) const;
-@end example
-
-will then dispatch to the correct @code{visit()} member function of the
-specified visitor @code{v} for the type of GiNaC object at the root of the
-expression tree (e.g. a @code{symbol}, an @code{idx} or a @code{mul}).
-
-Here is an example of a visitor:
-
-@example
-class my_visitor
- : public visitor,          // this is required
-   public add::visitor,     // visit add objects
-   public numeric::visitor, // visit numeric objects
-   public basic::visitor    // visit basic objects
-@{
-    void visit(const add & x)
-    @{ cout << "called with an add object" << endl; @}
-
-    void visit(const numeric & x)
-    @{ cout << "called with a numeric object" << endl; @}
-
-    void visit(const basic & x)
-    @{ cout << "called with a basic object" << endl; @}
-@};
-@end example
-
-which can be used as follows:
-
-@example
-...
-    symbol x("x");
-    ex e1 = 42;
-    ex e2 = 4*x-3;
-    ex e3 = 8*x;
-
-    my_visitor v;
-    e1.accept(v);
-     // prints "called with a numeric object"
-    e2.accept(v);
-     // prints "called with an add object"
-    e3.accept(v);
-     // prints "called with a basic object"
-...
-@end example
-
-The @code{visit(const basic &)} method gets called for all objects that are
-not @code{numeric} or @code{add} and acts as an (optional) default.
-
-From a conceptual point of view, the @code{visit()} methods of the visitor
-behave like a newly added virtual function of the visited hierarchy.
-In addition, visitors can store state in member variables, and they can
-be extended by deriving a new visitor from an existing one, thus building
-hierarchies of visitors.
-
-We can now rewrite our index example from above with a visitor:
-
-@example
-class gather_indices_visitor
- : public visitor, public idx::visitor, public varidx::visitor
-@{
-    lst l;
-
-    void visit(const idx & i)
-    @{
-        l.append(i);
-    @}
-
-    void visit(const varidx & vi)
-    @{
-        l.append(vi.is_covariant() ? vi : vi.toggle_variance());
-    @}
-
-public:
-    const lst & get_result() // utility function
-    @{
-        l.sort();
-        l.unique();
-        return l;
-    @}
-@};
-@end example
-
-What's missing is the tree traversal. We could implement it in
-@code{visit(const basic &)}, but GiNaC has predefined methods for this:
-
-@example
-void ex::traverse_preorder(visitor & v) const;
-void ex::traverse_postorder(visitor & v) const;
-void ex::traverse(visitor & v) const;
-@end example
-
-@code{traverse_preorder()} visits a node @emph{before} visiting its
-subexpressions, while @code{traverse_postorder()} visits a node @emph{after}
-visiting its subexpressions. @code{traverse()} is a synonym for
-@code{traverse_preorder()}.
-
-Here is a new implementation of @code{gather_indices()} that uses the visitor
-and @code{traverse()}:
-
-@example
-lst gather_indices(const ex & e)
-@{
-    gather_indices_visitor v;
-    e.traverse(v);
-    return v.get_result();
-@}
-@end example
-
-
-@node Polynomial Arithmetic, Rational Expressions, Visitors and Tree Traversal, Methods and Functions
+@node Polynomial Arithmetic, Rational Expressions, Applying a Function on Subexpressions, Methods and Functions
 @c    node-name, next, previous, up
 @section Polynomial arithmetic
 
 @c    node-name, next, previous, up
 @section Polynomial arithmetic
 
@@ -3936,7 +3518,7 @@ x*z}.
 To bring an expression into expanded form, its method
 
 @example
 To bring an expression into expanded form, its method
 
 @example
-ex ex::expand(unsigned options = 0);
+ex ex::expand();
 @end example
 
 may be called.  In our example above, this corresponds to @math{4*x*y +
 @end example
 
 may be called.  In our example above, this corresponds to @math{4*x*y +
@@ -4010,9 +3592,34 @@ int ex::degree(const ex & s);
 int ex::ldegree(const ex & s);
 @end example
 
 int ex::ldegree(const ex & 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
+These functions only work reliably if the input polynomial is collected in
+terms of the object @samp{s}. Otherwise, they are only guaranteed to return
+the upper/lower bounds of the exponents. If you need accurate results, you
+have to call @code{expand()} and/or @code{collect()} on the input polynomial.
+For example
+
+@example
+> a=(x+1)^2-x^2;
+(1+x)^2-x^2;
+> degree(a,x);
+2
+> degree(expand(a),x);
+1
+@end example
+
+@code{degree()} also works on rational functions, returning the asymptotic
+degree:
+
+@example
+> degree((x+1)/(x^3+1),x);
+-2
+@end example
+
+If the input is not a polynomial or rational function in the variable @samp{s},
+the behavior of @code{degree()} and @code{ldegree()} is undefined.
+
+To extract a coefficient with a certain power from an expanded
+polynomial you use
 
 @example
 ex ex::coeff(const ex & s, int n);
 
 @example
 ex ex::coeff(const ex & s, int n);
@@ -4283,8 +3890,7 @@ If you need both numerator and denominator, calling @code{numer_denom()} is
 faster than using @code{numer()} and @code{denom()} separately.
 
 
 faster than using @code{numer()} and @code{denom()} separately.
 
 
-@subsection Converting to a polynomial or rational expression
-@cindex @code{to_polynomial()}
+@subsection Converting to a rational expression
 @cindex @code{to_rational()}
 
 Some of the methods described so far only work on polynomials or rational
 @cindex @code{to_rational()}
 
 Some of the methods described so far only work on polynomials or rational
@@ -4292,10 +3898,6 @@ 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
 
 general expressions by using the temporary replacement algorithm described
 above. You do this by calling
 
-@example
-ex ex::to_polynomial(lst &l);
-@end example
-or
 @example
 ex ex::to_rational(lst &l);
 @end example
 @example
 ex ex::to_rational(lst &l);
 @end example
@@ -4304,33 +3906,10 @@ 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
 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.
+@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:
-
-@example
-@{
-    symbol x("x"), y("y");
-    ex a = 2*x/sin(x) - y/(3*sin(x));
-    cout << a << endl;
-
-    lst lp;
-    ex p = a.to_polynomial(lp);
-    cout << " = " << p << "\n   with " << lp << endl;
-     // = symbol3*symbol2*y+2*symbol2*x
-     //   with @{symbol2==sin(x)^(-1),symbol3==-1/3@}
-
-    lst lr;
-    ex r = a.to_rational(lr);
-    cout << " = " << r << "\n   with " << lr << endl;
-     // = -1/3*symbol4^(-1)*y+2*symbol4^(-1)*x
-     //   with @{symbol4==sin(x)@}
-@}
-@end example
-
-The following more useful example will print @samp{sin(x)-cos(x)}:
+For example,
 
 @example
 @{
 
 @example
 @{
@@ -4339,11 +3918,13 @@ The following more useful example will print @samp{sin(x)-cos(x)}:
     ex b = sin(x) + cos(x);
     ex q;
     lst l;
     ex b = sin(x) + cos(x);
     ex q;
     lst l;
-    divide(a.to_polynomial(l), b.to_polynomial(l), q);
+    divide(a.to_rational(l), b.to_rational(l), q);
     cout << q.subs(l) << endl;
 @}
 @end example
 
     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
 
 @node Symbolic Differentiation, Series Expansion, Rational Expressions, Methods and Functions
 @c    node-name, next, previous, up
@@ -4461,21 +4042,19 @@ value of Archimedes' constant
 $\pi$
 @end tex
 (for which there already exists the built-in constant @code{Pi}) 
 $\pi$
 @end tex
 (for which there already exists the built-in constant @code{Pi}) 
-using John Machin's amazing formula
+using Machin's amazing formula
 @tex
 $\pi=16$~atan~$\!\left(1 \over 5 \right)-4$~atan~$\!\left(1 \over 239 \right)$.
 @end tex
 @ifnottex
 @math{Pi==16*atan(1/5)-4*atan(1/239)}.
 @end ifnottex
 @tex
 $\pi=16$~atan~$\!\left(1 \over 5 \right)-4$~atan~$\!\left(1 \over 239 \right)$.
 @end tex
 @ifnottex
 @math{Pi==16*atan(1/5)-4*atan(1/239)}.
 @end ifnottex
-This equation (and similar ones) were used for over 200 years for
-computing digits of pi (see @cite{Pi Unleashed}).  We may expand the
-arcus tangent around @code{0} and insert the fractions @code{1/5} and
-@code{1/239}.  However, as we have seen, a series in GiNaC carries an
-order term with it and the question arises what the system is supposed
-to do when the fractions are plugged into that order term.  The solution
-is to use the function @code{series_to_poly()} to simply strip the order
-term off:
+We may expand the arcus tangent around @code{0} and insert the fractions
+@code{1/5} and @code{1/239}.  But, as we have seen, a series in GiNaC
+carries an order term with it and the question arises what the system is
+supposed to do when the fractions are plugged into that order term.  The
+solution is to use the function @code{series_to_poly()} to simply strip
+the order term off:
 
 @example
 #include <ginac/ginac.h>
 
 @example
 #include <ginac/ginac.h>
@@ -4571,7 +4150,7 @@ almost any kind of object (anything that is @code{subs()}able):
 @end example
 
 
 @end example
 
 
-@node Built-in Functions, Solving Linear Systems of Equations, Symmetrization, Methods and Functions
+@node Built-in Functions, Input/Output, Symmetrization, Methods and Functions
 @c    node-name, next, previous, up
 @section Predefined mathematical functions
 
 @c    node-name, next, previous, up
 @section Predefined mathematical functions
 
@@ -4685,48 +4264,7 @@ standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
 
 compatible with C99.
 
 
-@node Solving Linear Systems of Equations, Input/Output, Built-in Functions, Methods and Functions
-@c    node-name, next, previous, up
-@section Solving Linear Systems of Equations
-@cindex @code{lsolve()}
-
-The function @code{lsolve()} provides a convenient wrapper around some
-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);
-@end example
-
-Here, @code{eqns} is a @code{lst} of equalities (i.e. class
-@code{relational}) while @code{symbols} is a @code{lst} of
-indeterminates.  (@xref{The Class Hierarchy}, for an exposition of class
-@code{lst}).
-
-It returns the @code{lst} of solutions as an expression.  As an example,
-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);
-    cout << lsolve(eqns, vars) << endl;
-    // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
-@end example
-
-When the linear equations @code{eqns} are underdetermined, the solution
-will contain one or more tautological entries like @code{x==x},
-depending on the rank of the system.  When they are overdetermined, the
-solution will be an empty @code{lst}.  Note the third optional parameter
-to @code{lsolve()}: it accepts the same parameters as
-@code{matrix::solve()}.  This is because @code{lsolve} is just a wrapper
-around that method.
-
-
-@node Input/Output, Extending GiNaC, Solving Linear Systems of Equations, Methods and Functions
+@node Input/Output, Extending GiNaC, Built-in Functions, Methods and Functions
 @c    node-name, next, previous, up
 @section Input and output of expressions
 @cindex I/O
 @c    node-name, next, previous, up
 @section Input and output of expressions
 @cindex I/O
@@ -4735,99 +4273,70 @@ around that method.
 @cindex printing
 @cindex output of expressions
 
 @cindex printing
 @cindex output of expressions
 
-Expressions can simply be written to any stream:
+The easiest way to print an expression is to write it to a stream:
 
 @example
 @{
     symbol x("x");
 
 @example
 @{
     symbol x("x");
-    ex e = 4.5*I+pow(x,2)*3/2;
-    cout << e << endl;    // prints '4.5*I+3/2*x^2'
+    ex e = 4.5+pow(x,2)*3/2;
+    cout << e << endl;    // prints '(4.5)+3/2*x^2'
     // ...
 @end example
 
     // ...
 @end example
 
-The default output format is identical to the @command{ginsh} input syntax and
+The output format is identical to the @command{ginsh} input syntax and
 to that used by most computer algebra systems, but not directly pastable
 into a GiNaC C++ program (note that in the above example, @code{pow(x,2)}
 is printed as @samp{x^2}).
 
 It is possible to print expressions in a number of different formats with
 to that used by most computer algebra systems, but not directly pastable
 into a GiNaC C++ program (note that in the above example, @code{pow(x,2)}
 is printed as @samp{x^2}).
 
 It is possible to print expressions in a number of different formats with
-a set of stream manipulators;
+the method
 
 @example
 
 @example
-std::ostream & dflt(std::ostream & os);
-std::ostream & latex(std::ostream & os);
-std::ostream & tree(std::ostream & os);
-std::ostream & csrc(std::ostream & os);
-std::ostream & csrc_float(std::ostream & os);
-std::ostream & csrc_double(std::ostream & os);
-std::ostream & csrc_cl_N(std::ostream & os);
-std::ostream & index_dimensions(std::ostream & os);
-std::ostream & no_index_dimensions(std::ostream & os);
+void ex::print(const print_context & c, unsigned level = 0);
 @end example
 
 @end example
 
-The @code{tree}, @code{latex} and @code{csrc} formats are also available in
-@command{ginsh} via the @code{print()}, @code{print_latex()} and
-@code{print_csrc()} functions, respectively.
+@cindex @code{print_context} (class)
+The type of @code{print_context} object passed in determines the format
+of the output. The possible types are defined in @file{ginac/print.h}.
+All constructors of @code{print_context} and derived classes take an
+@code{ostream &} as their first argument.
 
 
-@cindex @code{dflt}
-All manipulators affect the stream state permanently. To reset the output
-format to the default, use the @code{dflt} manipulator:
+To print an expression in a way that can be directly used in a C or C++
+program, you pass a @code{print_csrc} object like this:
 
 @example
     // ...
 
 @example
     // ...
-    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
-    cout << e << endl;        // prints '4.5*I+3/2*x^2'
-    // ...
-@end example
+    cout << "float f = ";
+    e.print(print_csrc_float(cout));
+    cout << ";\n";
 
 
-If you don't want to affect the format of the stream you're working with,
-you can output to a temporary @code{ostringstream} like this:
+    cout << "double d = ";
+    e.print(print_csrc_double(cout));
+    cout << ";\n";
 
 
-@example
-    // ...
-    ostringstream s;
-    s << latex << e;         // format of cout remains unchanged
-    cout << s.str() << endl; // prints '4.5 i+\frac@{3@}@{2@} x^@{2@}'
+    cout << "cl_N n = ";
+    e.print(print_csrc_cl_N(cout));
+    cout << ";\n";
     // ...
 @end example
 
     // ...
 @end example
 
-@cindex @code{csrc}
-@cindex @code{csrc_float}
-@cindex @code{csrc_double}
-@cindex @code{csrc_cl_N}
-The @code{csrc} (an alias for @code{csrc_double}), @code{csrc_float},
-@code{csrc_double} and @code{csrc_cl_N} manipulators set the output to a
-format that can be directly used in a C or C++ program. The three possible
-formats select the data types used for numbers (@code{csrc_cl_N} uses the
-classes provided by the CLN library):
+The three possible types mostly affect the way in which floating point
+numbers are written.
 
 
-@example
-    // ...
-    cout << "f = " << csrc_float << e << ";\n";
-    cout << "d = " << csrc_double << e << ";\n";
-    cout << "n = " << csrc_cl_N << e << ";\n";
-    // ...
-@end example
-
-The above example will produce (note the @code{x^2} being converted to
-@code{x*x}):
+The above example will produce (note the @code{x^2} being converted to @code{x*x}):
 
 @example
 
 @example
-f = (3.0/2.0)*(x*x)+std::complex<float>(0.0,4.5000000e+00);
-d = (3.0/2.0)*(x*x)+std::complex<double>(0.0,4.5000000000000000e+00);
-n = cln::cl_RA("3/2")*(x*x)+cln::complex(cln::cl_I("0"),cln::cl_F("4.5_17"));
+float f = (3.0/2.0)*(x*x)+4.500000e+00;
+double d = (3.0/2.0)*(x*x)+4.5000000000000000e+00;
+cl_N n = cln::cl_RA("3/2")*(x*x)+cln::cl_F("4.5_17");
 @end example
 
 @end example
 
-@cindex @code{tree}
-The @code{tree} manipulator allows dumping the internal structure of an
-expression for debugging purposes:
+The @code{print_context} type @code{print_tree} provides a dump of the
+internal structure of an expression for debugging purposes:
 
 @example
     // ...
 
 @example
     // ...
-    cout << tree << e;
+    e.print(print_tree(cout));
 @}
 @end example
 
 @}
 @end example
 
@@ -4835,63 +4344,41 @@ produces
 
 @example
 add, hash=0x0, flags=0x3, nops=2
 
 @example
 add, hash=0x0, flags=0x3, nops=2
-    power, hash=0x0, flags=0x3, nops=2
-        x (symbol), serial=0, hash=0xc8d5bcdd, flags=0xf
-        2 (numeric), hash=0x6526b0fa, flags=0xf
-    3/2 (numeric), hash=0xf9828fbd, flags=0xf
+    power, hash=0x9, flags=0x3, nops=2
+        x (symbol), serial=3, hash=0x44a113a6, flags=0xf
+        2 (numeric), hash=0x80000042, flags=0xf
+    3/2 (numeric), hash=0x80000061, flags=0xf
     -----
     overall_coeff
     -----
     overall_coeff
-    4.5L0i (numeric), hash=0xa40a97e0, flags=0xf
+    4.5L0 (numeric), hash=0x8000004b, flags=0xf
     =====
 @end example
 
     =====
 @end example
 
-@cindex @code{latex}
-The @code{latex} output format is for LaTeX parsing in mathematical mode.
-It is rather similar to the default format but provides some braces needed
-by LaTeX for delimiting boxes and also converts some common objects to
-conventional LaTeX names. It is possible to give symbols a special name for
-LaTeX output by supplying it as a second argument to the @code{symbol}
-constructor.
+This kind of output is also available in @command{ginsh} as the @code{print()}
+function.
 
 
-For example, the code snippet
-
-@example
-@{
-    symbol x("x", "\\circ");
-    ex e = lgamma(x).series(x==0,3);
-    cout << latex << e << endl;
-@}
-@end example
+Another useful output format is for LaTeX parsing in mathematical mode.
+It is rather similar to the default @code{print_context} but provides
+some braces needed by LaTeX for delimiting boxes and also converts some
+common objects to conventional LaTeX names. It is possible to give symbols
+a special name for LaTeX output by supplying it as a second argument to
+the @code{symbol} constructor.
 
 
-will print
+For example, the code snippet
 
 @example
 
 @example
-    @{(-\ln(\circ))@}+@{(-\gamma_E)@} \circ+@{(\frac@{1@}@{12@} \pi^@{2@})@} \circ^@{2@}+\mathcal@{O@}(\circ^@{3@})
+    // ...
+    symbol x("x");
+    ex foo = lgamma(x).series(x==0,3);
+    foo.print(print_latex(std::cout));
 @end example
 
 @end example
 
-@cindex @code{index_dimensions}
-@cindex @code{no_index_dimensions}
-Index dimensions are normally hidden in the output. To make them visible, use
-the @code{index_dimensions} manipulator. The dimensions will be written in
-square brackets behind each index value in the default and LaTeX output
-formats:
+will print out:
 
 @example
 
 @example
-@{
-    symbol x("x"), y("y");
-    varidx mu(symbol("mu"), 4), nu(symbol("nu"), 4);
-    ex e = indexed(x, mu) * indexed(y, nu);
-
-    cout << e << endl;
-     // prints 'x~mu*y~nu'
-    cout << index_dimensions << e << endl;
-     // prints 'x~mu[4]*y~nu[4]'
-    cout << no_index_dimensions << e << endl;
-     // prints 'x~mu*y~nu'
-@}
+    @{(-\ln(x))@}+@{(-\gamma_E)@} x+@{(1/12 \pi^2)@} x^@{2@}+\mathcal@{O@}(x^3)
 @end example
 
 @end example
 
-
 @cindex Tree traversal
 If you need any fancy special output format, e.g. for interfacing GiNaC
 with other algebra systems or for producing code for different
 @cindex Tree traversal
 If you need any fancy special output format, e.g. for interfacing GiNaC
 with other algebra systems or for producing code for different
@@ -4905,9 +4392,9 @@ static void my_print(const ex & e)
     else
         cout << e.bp->class_name();
     cout << "(";
     else
         cout << e.bp->class_name();
     cout << "(";
-    size_t n = e.nops();
+    unsigned n = e.nops();
     if (n)
     if (n)
-        for (size_t i=0; i<n; i++) @{
+        for (unsigned i=0; i<n; i++) @{
             my_print(e.op(i));
             if (i != n-1)
                 cout << ",";
             my_print(e.op(i));
             if (i != n-1)
                 cout << ",";
@@ -4917,7 +4404,7 @@ static void my_print(const ex & e)
     cout << ")";
 @}
 
     cout << ")";
 @}
 
-int main()
+int main(void)
 @{
     my_print(pow(3, x) - 2 * sin(y / Pi)); cout << endl;
     return 0;
 @{
     my_print(pow(3, x) - 2 * sin(y / Pi)); cout << endl;
     return 0;
@@ -4948,19 +4435,22 @@ and have the @samp{x} and @samp{y} correspond to the symbols @code{x} and
 desired symbols to the @code{>>} stream input operator.
 
 Instead, GiNaC lets you construct an expression from a string, specifying the
 desired symbols to the @code{>>} stream input operator.
 
 Instead, GiNaC lets you construct an expression from a string, specifying the
-list of symbols to be used:
+list of symbols and indices to be used:
 
 @example
 @{
 
 @example
 @{
-    symbol x("x"), y("y");
-    ex e("2*x+sin(y)", lst(x, y));
+    symbol x("x"), y("y"), p("p");
+    idx i(symbol("i"), 3);
+    ex e("2*x+sin(y)+p.i", lst(x, y, p, i));
 @}
 @end example
 
 The input syntax is the same as that used by @command{ginsh} and the stream
 @}
 @end example
 
 The input syntax is the same as that used by @command{ginsh} and the stream
-output operator @code{<<}. The symbols in the string are matched by name to
-the symbols in the list and if GiNaC encounters a symbol not specified in
-the list it will throw an exception.
+output operator @code{<<}. The symbols and indices in the string are matched
+by name to the symbols and indices in the list and if GiNaC encounters a
+symbol or index not specified in the list it will throw an exception. Only
+indices whose values are single symbols can be used (i.e. numeric indices
+or compound indices as in "A.(2*n+1)" are not allowed).
 
 With this constructor, it's also easy to implement interactive GiNaC programs:
 
 
 With this constructor, it's also easy to implement interactive GiNaC programs:
 
@@ -5092,8 +4582,8 @@ static void my_print2(const archive_node & n)
     archive_node::propinfovector p;
     n.get_properties(p);
 
     archive_node::propinfovector p;
     n.get_properties(p);
 
-    size_t num = p.size();
-    for (size_t i=0; i<num; i++) @{
+    unsigned num = p.size();
+    for (unsigned i=0; i<num; i++) @{
         const string &name = p[i].name;
         if (name == "class")
             continue;
         const string &name = p[i].name;
         if (name == "class")
             continue;
@@ -5144,7 +4634,7 @@ static void my_print2(const archive_node & n)
     cout << ")";
 @}
 
     cout << ")";
 @}
 
-int main()
+int main(void)
 @{
     ex e = pow(2, x) - y;
     archive ar(e, "e");
 @{
     ex e = pow(2, x) - y;
     archive ar(e, "e");
@@ -5179,8 +4669,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.
 @menu
 * What does not belong into GiNaC::  What to avoid.
 * Symbolic functions::               Implementing symbolic functions.
-* Structures::                       Defining new algebraic classes (the easy way).
-* Adding classes::                   Defining new algebraic classes (the hard way).
+* Adding classes::                   Defining new algebraic classes.
 @end menu
 
 
 @end menu
 
 
@@ -5208,7 +4697,7 @@ inefficient.  For this purpose, the underlying foundation classes
 provided by CLN are much better suited.
 
 
 provided by CLN are much better suited.
 
 
-@node Symbolic functions, Structures, What does not belong into GiNaC, Extending GiNaC
+@node Symbolic functions, Adding classes, What does not belong into GiNaC, Extending GiNaC
 @c    node-name, next, previous, up
 @section Symbolic functions
 
 @c    node-name, next, previous, up
 @section Symbolic functions
 
@@ -5474,375 +4963,21 @@ specifications. GiNaC will automatically rearrange the arguments of
 symmetric functions into a canonical order.
 
 
 symmetric functions into a canonical order.
 
 
-@node Structures, Adding classes, Symbolic functions, Extending GiNaC
-@c    node-name, next, previous, up
-@section Structures
-
-If you are doing some very specialized things with GiNaC, or if you just
-need some more organized way to store data in your expressions instead of
-anonymous lists, you may want to implement your own algebraic classes.
-('algebraic class' means any class directly or indirectly derived from
-@code{basic} that can be used in GiNaC expressions).
-
-GiNaC offers two ways of accomplishing this: either by using the
-@code{structure<T>} template class, or by rolling your own class from
-scratch. This section will discuss the @code{structure<T>} template which
-is easier to use but more limited, while the implementation of custom
-GiNaC classes is the topic of the next section. However, you may want to
-read both sections because many common concepts and member functions are
-shared by both concepts, and it will also allow you to decide which approach
-is most suited to your needs.
-
-The @code{structure<T>} template, defined in the GiNaC header file
-@file{structure.h}, wraps a type that you supply (usually a C++ @code{struct}
-or @code{class}) into a GiNaC object that can be used in expressions.
-
-@subsection Example: scalar products
-
-Let's suppose that we need a way to handle some kind of abstract scalar
-product of the form @samp{<x|y>} in expressions. Objects of the scalar
-product class have to store their left and right operands, which can in turn
-be arbitrary expressions. Here is a possible way to represent such a
-product in a C++ @code{struct}:
-
-@example
-#include <iostream>
-using namespace std;
-
-#include <ginac/ginac.h>
-using namespace GiNaC;
-
-struct sprod_s @{
-    ex left, right;
-
-    sprod_s() @{@}
-    sprod_s(ex l, ex r) : left(l), right(r) @{@}
-@};
-@end example
-
-The default constructor is required. Now, to make a GiNaC class out of this
-data structure, we need only one line:
-
-@example
-typedef structure<sprod_s> sprod;
-@end example
-
-That's it. This line constructs an algebraic class @code{sprod} which
-contains objects of type @code{sprod_s}. We can now use @code{sprod} in
-expressions like any other GiNaC class:
-
-@example
-...
-    symbol a("a"), b("b");
-    ex e = sprod(sprod_s(a, b));
-...
-@end example
-
-Note the difference between @code{sprod} which is the algebraic class, and
-@code{sprod_s} which is the unadorned C++ structure containing the @code{left}
-and @code{right} data members. As shown above, an @code{sprod} can be
-constructed from an @code{sprod_s} object.
-
-If you find the nested @code{sprod(sprod_s())} constructor too unwieldy,
-you could define a little wrapper function like this:
-
-@example
-inline ex make_sprod(ex left, ex right)
-@{
-    return sprod(sprod_s(left, right));
-@}
-@end example
-
-The @code{sprod_s} object contained in @code{sprod} can be accessed with
-the GiNaC @code{ex_to<>()} function followed by the @code{->} operator or
-@code{get_struct()}:
-
-@example
-...
-    cout << ex_to<sprod>(e)->left << endl;
-     // -> a
-    cout << ex_to<sprod>(e).get_struct().right << endl;
-     // -> b
-...
-@end example
-
-You only have read access to the members of @code{sprod_s}.
-
-The type definition of @code{sprod} is enough to write your own algorithms
-that deal with scalar products, for example:
-
-@example
-ex swap_sprod(ex p)
-@{
-    if (is_a<sprod>(p)) @{
-        const sprod_s & sp = ex_to<sprod>(p).get_struct();
-        return make_sprod(sp.right, sp.left);
-    @} else
-        return p;
-@}
-
-...
-    f = swap_sprod(e);
-     // f is now <b|a>
-...
-@end example
-
-@subsection Structure output
-
-While the @code{sprod} type is useable it still leaves something to be
-desired, most notably proper output:
-
-@example
-...
-    cout << e << endl;
-     // -> [structure object]
-...
-@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:
-
-@example
-void sprod::print(const print_context & c, unsigned level) const
-@{
-    // tree debug output handled by superclass
-    if (is_a<print_tree>(c))
-        inherited::print(c, level);
-
-    // get the contained sprod_s object
-    const sprod_s & sp = get_struct();
-
-    // print_context::s is a reference to an ostream
-    c.s << "<" << sp.left << "|" << sp.right << ">";
-@}
-@end example
-
-Now we can print expressions containing scalar products:
-
-@example
-...
-    cout << e << endl;
-     // -> <a|b>
-    cout << swap_sprod(e) << endl;
-     // -> <b|a>
-...
-@end example
-
-@subsection Comparing structures
-
-The @code{sprod} class defined so far still has one important drawback: all
-scalar products are treated as being equal because GiNaC doesn't know how to
-compare objects of type @code{sprod_s}. This can lead to some confusing
-and undesired behavior:
-
-@example
-...
-    cout << make_sprod(a, b) - make_sprod(a*a, b*b) << endl;
-     // -> 0
-    cout << make_sprod(a, b) + make_sprod(a*a, b*b) << endl;
-     // -> 2*<a|b> or 2*<a^2|b^2> (which one is undefined)
-...
-@end example
-
-To remedy this, we first need to define the operators @code{==} and @code{<}
-for objects of type @code{sprod_s}:
-
-@example
-inline bool operator==(const sprod_s & lhs, const sprod_s & rhs)
-@{
-    return lhs.left.is_equal(rhs.left) && lhs.right.is_equal(rhs.right);
-@}
-
-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;
-@}
-@end example
-
-The ordering established by the @code{<} operator doesn't have to make any
-algebraic sense, but it needs to be well defined. Note that we can't use
-expressions like @code{lhs.left == rhs.left} or @code{lhs.left < rhs.left}
-in the implementation of these operators because they would construct
-GiNaC @code{relational} objects which in the case of @code{<} do not
-establish a well defined ordering (for arbitrary expressions, GiNaC can't
-decide which one is algebraically 'less').
-
-Next, we need to change our definition of the @code{sprod} type to let
-GiNaC know that an ordering relation exists for the embedded objects:
-
-@example
-typedef structure<sprod_s, compare_std_less> sprod;
-@end example
-
-@code{sprod} objects then behave as expected:
-
-@example
-...
-    cout << make_sprod(a, b) - make_sprod(a*a, b*b) << endl;
-     // -> <a|b>-<a^2|b^2>
-    cout << make_sprod(a, b) + make_sprod(a*a, b*b) << endl;
-     // -> <a|b>+<a^2|b^2>
-    cout << make_sprod(a, b) - make_sprod(a, b) << endl;
-     // -> 0
-    cout << make_sprod(a, b) + make_sprod(a, b) << endl;
-     // -> 2*<a|b>
-...
-@end example
-
-The @code{compare_std_less} policy parameter tells GiNaC to use the
-@code{std::less} and @code{std::equal_to} functors to compare objects of
-type @code{sprod_s}. By default, these functors forward their work to the
-standard @code{<} and @code{==} operators, which we have overloaded.
-Alternatively, we could have specialized @code{std::less} and
-@code{std::equal_to} for class @code{sprod_s}.
-
-GiNaC provides two other comparison policies for @code{structure<T>}
-objects: the default @code{compare_all_equal}, and @code{compare_bitwise}
-which does a bit-wise comparison of the contained @code{T} objects.
-This should be used with extreme care because it only works reliably with
-built-in integral types, and it also compares any padding (filler bytes of
-undefined value) that the @code{T} class might have.
-
-@subsection Subexpressions
-
-Our scalar product class has two subexpressions: the left and right
-operands. It might be a good idea to make them accessible via the standard
-@code{nops()} and @code{op()} methods:
-
-@example
-size_t sprod::nops() const
-@{
-    return 2;
-@}
-
-ex sprod::op(size_t i) const
-@{
-    switch (i) @{
-    case 0:
-        return get_struct().left;
-    case 1:
-        return get_struct().right;
-    default:
-        throw std::range_error("sprod::op(): no such operand");
-    @}
-@}
-@end example
-
-Implementing @code{nops()} and @code{op()} for container types such as
-@code{sprod} has two other nice side effects:
-
-@itemize @bullet
-@item
-@code{has()} works as expected
-@item
-GiNaC generates better hash keys for the objects (the default implementation
-of @code{calchash()} takes subexpressions into account)
-@end itemize
-
-@cindex @code{let_op()}
-There is a non-const variant of @code{op()} called @code{let_op()} that
-allows replacing subexpressions:
-
-@example
-ex & sprod::let_op(size_t i)
-@{
-    // every non-const member function must call this
-    ensure_if_modifiable();
-
-    switch (i) @{
-    case 0:
-        return get_struct().left;
-    case 1:
-        return get_struct().right;
-    default:
-        throw std::range_error("sprod::let_op(): no such operand");
-    @}
-@}
-@end example
-
-Once we have provided @code{let_op()} we also get @code{subs()} and
-@code{map()} for free. In fact, every container class that returns a non-null
-@code{nops()} value must either implement @code{let_op()} or provide custom
-implementations of @code{subs()} and @code{map()}.
-
-In turn, the availability of @code{map()} enables the recursive behavior of a
-couple of other default method implementations, in particular @code{evalf()},
-@code{evalm()}, @code{normal()}, @code{diff()} and @code{expand()}. Although
-we probably want to provide our own version of @code{expand()} for scalar
-products that turns expressions like @samp{<a+b|c>} into @samp{<a|c>+<b|c>}.
-This is left as an exercise for the reader.
-
-The @code{structure<T>} template defines many more member functions that
-you can override by specialization to customize the behavior of your
-structures. You are referred to the next section for a description of
-some of these (especially @code{eval()}). There is, however, one topic
-that shall be addressed here, as it demonstrates one peculiarity of the
-@code{structure<T>} template: archiving.
-
-@subsection Archiving structures
-
-If you don't know how the archiving of GiNaC objects is implemented, you
-should first read the next section and then come back here. You're back?
-Good.
-
-To implement archiving for structures it is not enough to provide
-specializations for the @code{archive()} member function and the
-unarchiving constructor (the @code{unarchive()} function has a default
-implementation). You also need to provide a unique name (as a string literal)
-for each structure type you define. This is because in GiNaC archives,
-the class of an object is stored as a string, the class name.
-
-By default, this class name (as returned by the @code{class_name()} member
-function) is @samp{structure} for all structure classes. This works as long
-as you have only defined one structure type, but if you use two or more you
-need to provide a different name for each by specializing the
-@code{get_class_name()} member function. Here is a sample implementation
-for enabling archiving of the scalar product type defined above:
-
-@example
-const char *sprod::get_class_name() @{ return "sprod"; @}
-
-void sprod::archive(archive_node & n) const
-@{
-    inherited::archive(n);
-    n.add_ex("left", get_struct().left);
-    n.add_ex("right", get_struct().right);
-@}
-
-sprod::structure(const archive_node & n, lst & sym_lst) : inherited(n, sym_lst)
-@{
-    n.find_ex("left", get_struct().left, sym_lst);
-    n.find_ex("right", get_struct().right, sym_lst);
-@}
-@end example
-
-Note that the unarchiving constructor is @code{sprod::structure} and not
-@code{sprod::sprod}, and that we don't need to supply an
-@code{sprod::unarchive()} function.
-
-
-@node Adding classes, A Comparison With Other CAS, Structures, Extending GiNaC
+@node Adding classes, A Comparison With Other CAS, Symbolic functions, Extending GiNaC
 @c    node-name, next, previous, up
 @section Adding classes
 
 @c    node-name, next, previous, up
 @section Adding classes
 
-The @code{structure<T>} template provides an way to extend GiNaC with custom
-algebraic classes that is easy to use but has its limitations, the most
-severe of which being that you can't add any new member functions to
-structures. To be able to do this, you need to write a new class definition
-from scratch.
-
-This section will explain how to implement new algebraic classes in GiNaC by
-giving the example of a simple 'string' class. After reading this section
-you will know how to properly declare a GiNaC class and what the minimum
-required member functions are that you have to implement. We only cover the
-implementation of a 'leaf' class here (i.e. one that doesn't contain
-subexpressions). Creating a container class like, for example, a class
-representing tensor products is more involved but this section should give
-you enough information so you can consult the source to GiNaC's predefined
-classes if you want to implement something more complicated.
+If you are doing some very specialized things with GiNaC you may find that
+you have to implement your own algebraic classes to fit your needs. This
+section will explain how to do this by giving the example of a simple
+'string' class. After reading this section you will know how to properly
+declare a GiNaC class and what the minimum required member functions are
+that you have to implement. We only cover the implementation of a 'leaf'
+class here (i.e. one that doesn't contain subexpressions). Creating a
+container class like, for example, a class representing tensor products is
+more involved but this section should give you enough information so you can
+consult the source to GiNaC's predefined classes if you want to implement
+something more complicated.
 
 @subsection GiNaC's run-time type information system
 
 
 @subsection GiNaC's run-time type information system
 
@@ -5945,13 +5080,14 @@ the first line after the opening brace of the class definition. The
 source (at global scope, of course, not inside a function).
 
 @code{GINAC_DECLARE_REGISTERED_CLASS} contains, among other things the
 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
-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.
-
-Now there are seven member functions we have to implement to get a working
+declarations of the default and copy constructor, the destructor, the
+assignment operator and a couple of other functions that 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} implements the copy
+constructor, the destructor and the assignment operator.
+
+Now there are nine member functions we have to implement to get a working
 class:
 
 @itemize
 class:
 
 @itemize
@@ -5959,23 +5095,33 @@ class:
 @item
 @code{mystring()}, the default constructor.
 
 @item
 @code{mystring()}, the default constructor.
 
+@item
+@code{void destroy(bool call_parent)}, which is used in the destructor and the
+assignment operator to free dynamically allocated members. The @code{call_parent}
+specifies whether the @code{destroy()} function of the superclass is to be
+called also.
+
+@item
+@code{void copy(const mystring &other)}, which is used in the copy constructor
+and assignment operator to copy the member variables over from another
+object of the same class.
+
 @item
 @code{void archive(archive_node &n)}, the archiving function. This stores all
 information needed to reconstruct an object of this class inside an
 @code{archive_node}.
 
 @item
 @item
 @code{void archive(archive_node &n)}, the archiving function. This stores all
 information needed to reconstruct an object of this class inside an
 @code{archive_node}.
 
 @item
-@code{mystring(const archive_node &n, lst &sym_lst)}, the unarchiving
+@code{mystring(const archive_node &n, const lst &sym_lst)}, the unarchiving
 constructor. This constructs an instance of the class from the information
 found in an @code{archive_node}.
 
 @item
 constructor. This constructs an instance of the class from the information
 found in an @code{archive_node}.
 
 @item
-@code{ex unarchive(const archive_node &n, lst &sym_lst)}, the static
+@code{ex unarchive(const archive_node &n, const lst &sym_lst)}, the static
 unarchiving function. It constructs a new instance by calling the unarchiving
 constructor.
 
 @item
 unarchiving function. It constructs a new instance by calling the unarchiving
 constructor.
 
 @item
-@cindex @code{compare_same_type()}
 @code{int compare_same_type(const basic &other)}, which is used internally
 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}
 @code{int compare_same_type(const basic &other)}, which is used internally
 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}
@@ -5997,7 +5143,10 @@ which are the two constructors we declared.
 Let's proceed step-by-step. The default constructor looks like this:
 
 @example
 Let's proceed step-by-step. The default constructor looks like this:
 
 @example
-mystring::mystring() : inherited(TINFO_mystring) @{@}
+mystring::mystring() : inherited(TINFO_mystring)
+@{
+    // dynamically allocate resources here if required
+@}
 @end example
 
 The golden rule is that in all constructors you have to set the
 @end example
 
 The golden rule is that in all constructors you have to set the
@@ -6005,13 +5154,51 @@ The golden rule is that in all constructors you have to set the
 it will be set by the constructor of the superclass and all hell will break
 loose in the RTTI. For your convenience, the @code{basic} class provides
 a constructor that takes a @code{tinfo_key} value, which we are using here
 it will be set by the constructor of the superclass and all hell will break
 loose in the RTTI. For your convenience, the @code{basic} class provides
 a constructor that takes a @code{tinfo_key} value, which we are using here
-(remember that in our case @code{inherited == basic}).  If the superclass
+(remember that in our case @code{inherited = basic}).  If the superclass
 didn't have such a constructor, we would have to set the @code{tinfo_key}
 to the right value manually.
 
 In the default constructor you should set all other member variables to
 reasonable default values (we don't need that here since our @code{str}
 didn't have such a constructor, we would have to set the @code{tinfo_key}
 to the right value manually.
 
 In the default constructor you should set all other member variables to
 reasonable default values (we don't need that here since our @code{str}
-member gets set to an empty string automatically).
+member gets set to an empty string automatically). The constructor(s) are of
+course also the right place to allocate any dynamic resources you require.
+
+Next, the @code{destroy()} function:
+
+@example
+void mystring::destroy(bool call_parent)
+@{
+    // free dynamically allocated resources here if required
+    if (call_parent)
+        inherited::destroy(call_parent);
+@}
+@end example
+
+This function is where we free all dynamically allocated resources.  We
+don't have any so we're not doing anything here, but if we had, for
+example, used a C-style @code{char *} to store our string, this would be
+the place to @code{delete[]} the string storage. If @code{call_parent}
+is true, we have to call the @code{destroy()} function of the superclass
+after we're done (to mimic C++'s automatic invocation of superclass
+destructors where @code{destroy()} is called from outside a destructor).
+
+The @code{copy()} function just copies over the member variables from
+another object:
+
+@example
+void mystring::copy(const mystring &other)
+@{
+    inherited::copy(other);
+    str = other.str;
+@}
+@end example
+
+We can simply overwrite the member variables here. There's no need to worry
+about dynamically allocated storage.  The assignment operator (which is
+automatically defined by @code{GINAC_IMPLEMENT_REGISTERED_CLASS}, as you
+recall) calls @code{destroy()} before it calls @code{copy()}. You have to
+explicitly call the @code{copy()} function of the superclass here so
+all the member variables will get copied.
 
 Next are the three functions for archiving. You have to implement them even
 if you don't plan to use archives, but the minimum required implementation
 
 Next are the three functions for archiving. You have to implement them even
 if you don't plan to use archives, but the minimum required implementation
@@ -6036,7 +5223,7 @@ The unarchiving constructor is basically the inverse of the archiving
 function:
 
 @example
 function:
 
 @example
-mystring::mystring(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+mystring::mystring(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 @{
     n.find_string("string", str);
 @}
 @{
     n.find_string("string", str);
 @}
@@ -6050,7 +5237,7 @@ by the unarchiving constructor of the @code{basic} class.
 Finally, the unarchiving function:
 
 @example
 Finally, the unarchiving function:
 
 @example
-ex mystring::unarchive(const archive_node &n, lst &sym_lst)
+ex mystring::unarchive(const archive_node &n, const lst &sym_lst)
 @{
     return (new mystring(n, sym_lst))->setflag(status_flags::dynallocated);
 @}
 @{
     return (new mystring(n, sym_lst))->setflag(status_flags::dynallocated);
 @}
@@ -6091,8 +5278,15 @@ all relevant member variables.
 Now the only thing missing is our two new constructors:
 
 @example
 Now the only thing missing is our two new constructors:
 
 @example
-mystring::mystring(const string &s) : inherited(TINFO_mystring), str(s) @{@}
-mystring::mystring(const char *s) : inherited(TINFO_mystring), str(s) @{@}
+mystring::mystring(const string &s) : inherited(TINFO_mystring), str(s)
+@{
+    // dynamically allocate resources here if required
+@}
+
+mystring::mystring(const char *s) : inherited(TINFO_mystring), str(s)
+@{
+    // dynamically allocate resources here if required
+@}
 @end example
 
 No surprises here. We set the @code{str} member from the argument and
 @end example
 
 No surprises here. We set the @code{str} member from the argument and
@@ -6241,35 +5435,11 @@ cout << e << endl;
  // -> 3*"wow"
 @end example
 
  // -> 3*"wow"
 @end example
 
-@subsection Optional member functions
-
-We have implemented only a small set of member functions to make the class
-work in the GiNaC framework. There are two functions that are not strictly
-required but will make operations with objects of the class more efficient:
-
-@cindex @code{calchash()}
-@cindex @code{is_equal_same_type()}
-@example
-unsigned calchash() const;
-bool is_equal_same_type(const basic &other) const;
-@end example
-
-The @code{calchash()} method returns an @code{unsigned} hash value for the
-object which will allow GiNaC to compare and canonicalize expressions much
-more efficiently. You should consult the implementation of some of the built-in
-GiNaC classes for examples of hash functions. The default implementation of
-@code{calchash()} calculates a hash value out of the @code{tinfo_key} of the
-class and all subexpressions that are accessible via @code{op()}.
-
-@code{is_equal_same_type()} works like @code{compare_same_type()} but only
-tests for equality without establishing an ordering relation, which is often
-faster. The default implementation of @code{is_equal_same_type()} just calls
-@code{compare_same_type()} and tests its result for zero.
-
 @subsection Other member functions
 
 @subsection Other member functions
 
-For a real algebraic class, there are probably some more functions that you
-might want to provide:
+We have implemented only a small set of member functions to make the class
+work in the GiNaC framework. For a real algebraic class, there are probably
+some more functions that you might want to re-implement:
 
 @example
 bool info(unsigned inf) const;
 
 @example
 bool info(unsigned inf) const;
@@ -6278,21 +5448,33 @@ ex series(const relational & r, int order, unsigned options = 0) const;
 ex derivative(const symbol & s) const;
 @end example
 
 ex derivative(const symbol & s) const;
 @end example
 
-If your class stores sub-expressions (see the scalar product example in the
-previous section) you will probably want to override
+If your class stores sub-expressions you will probably want to override
 
 @cindex @code{let_op()}
 @example
 
 @cindex @code{let_op()}
 @example
-size_t nops() cont;
-ex op(size_t i) const;
-ex & let_op(size_t i);
-ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
+unsigned nops() cont;
+ex op(int i) const;
+ex & let_op(int i);
 ex map(map_function & f) const;
 ex map(map_function & f) const;
+ex subs(const lst & ls, const lst & lr, bool no_pattern = false) const;
 @end example
 
 @code{let_op()} is a variant of @code{op()} that allows write access. The
 @end example
 
 @code{let_op()} is a variant of @code{op()} that allows write access. The
-default implementations of @code{subs()} and @code{map()} use it, so you have
-to implement either @code{let_op()}, or @code{subs()} and @code{map()}.
+default implementation of @code{map()} uses it, so you have to implement
+either @code{let_op()} or @code{map()}.
+
+If your class stores any data that is not accessible via @code{op()}, you
+should also implement
+
+@cindex @code{calchash()}
+@example
+unsigned calchash(void) const;
+@end example
+
+This function returns an @code{unsigned} hash value for the object which
+will allow GiNaC to compare and canonicalize expressions much more
+efficiently. You should consult the implementation of some of the built-in
+GiNaC classes for examples of hash functions.
 
 You can, of course, also add your own new member functions. Remember
 that the RTTI may be used to get information about what kinds of objects
 
 You can, of course, also add your own new member functions. Remember
 that the RTTI may be used to get information about what kinds of objects
@@ -6468,19 +5650,12 @@ any other programming language.
 @cindex reference counting
 @cindex copy-on-write
 @cindex garbage collection
 @cindex reference counting
 @cindex copy-on-write
 @cindex garbage collection
-In GiNaC, there is an @emph{intrusive reference-counting} mechanism at work
-where the counter belongs to the algebraic objects derived from class
-@code{basic} but is maintained by the smart pointer class @code{ptr}, of
-which @code{ex} contains an instance. If you understood that, you can safely
-skip the rest of this passage.
-
-Expressions are extremely light-weight since internally they work like
-handles to the actual representation.  They really hold nothing more
-than a pointer to some other object.  What this means in practice is
-that whenever you create two @code{ex} and set the second equal to the
-first no copying process is involved. Instead, the copying takes place
-as soon as you try to change the second.  Consider the simple sequence
-of code:
+An expression is extremely light-weight since internally it works like a
+handle to the actual representation and really holds nothing more than a
+pointer to some other object.  What this means in practice is that
+whenever you create two @code{ex} and set the second equal to the first
+no copying process is involved. Instead, the copying takes place as soon
+as you try to change the second.  Consider the simple sequence of code:
 
 @example
 #include <iostream>
 
 @example
 #include <iostream>
@@ -6545,7 +5720,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
 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.
 
 Marshall Cline.  Chapter 16 covers this issue and presents an
 implementation which is pretty close to the one in GiNaC.
 
@@ -6807,7 +5982,7 @@ and the @samp{AM_PATH_GINAC} macro. The program used here is @file{simple.cpp}:
 @example
 #include <ginac/ginac.h>
 
 @example
 #include <ginac/ginac.h>
 
-int main()
+int main(void)
 @{
     GiNaC::symbol x("x");
     GiNaC::ex a = GiNaC::sin(x);
 @{
     GiNaC::symbol x("x");
     GiNaC::ex a = GiNaC::sin(x);
@@ -6914,7 +6089,7 @@ and George Labahn, ISBN 0-7923-9259-0, 1992, Kluwer Academic Publishers, Norwell
 
 @item
 @cite{Computer Algebra: Systems and Algorithms for Algebraic Computation},
 
 @item
 @cite{Computer Algebra: Systems and Algorithms for Algebraic Computation},
-James H. Davenport, Yvon Siret and Evelyne Tournier, ISBN 0-12-204230-1, 1988, 
+James H. Davenport, Yvon Siret, and Evelyne Tournier, ISBN 0-12-204230-1, 1988, 
 Academic Press, London
 
 @item
 Academic Press, London
 
 @item
@@ -6925,10 +6100,6 @@ Michael J. Wester (editor), ISBN 0-471-98353-5, 1999, Wiley, Chichester
 @cite{The Art of Computer Programming, Vol 2: Seminumerical Algorithms},
 Donald E. Knuth, ISBN 0-201-89684-2, 1998, Addison Wesley
 
 @cite{The Art of Computer Programming, Vol 2: Seminumerical Algorithms},
 Donald E. Knuth, ISBN 0-201-89684-2, 1998, Addison Wesley
 
-@item
-@cite{Pi Unleashed}, J@"org Arndt and Christoph Haenel,
-ISBN 3-540-66572-2, 2001, Springer, Heidelberg
-
 @item
 @cite{The Role of gamma5 in Dimensional Regularization}, Dirk Kreimer, hep-ph/9401354
 
 @item
 @cite{The Role of gamma5 in Dimensional Regularization}, Dirk Kreimer, hep-ph/9401354