+These specify the C++ functions that implement symbolic evaluation,
+numeric evaluation, partial derivatives, and series expansion, respectively.
+They correspond to the GiNaC methods @code{eval()}, @code{evalf()},
+@code{diff()} and @code{series()}.
+
+The @code{eval_func()} function needs to use @code{.hold()} if no further
+automatic evaluation is desired or possible.
+
+If no @code{series_func()} is given, GiNaC defaults to simple Taylor
+expansion, which is correct if there are no poles involved. If the function
+has poles in the complex plane, the @code{series_func()} needs to check
+whether the expansion point is on a pole and fall back to Taylor expansion
+if it isn't. Otherwise, the pole usually needs to be regularized by some
+suitable transformation.
+
+@example
+latex_name(const string & n)
+@end example
+
+specifies the LaTeX code that represents the name of the function in LaTeX
+output. The default is to put the function name in an @code{\mbox@{@}}.
+
+@example
+do_not_evalf_params()
+@end example
+
+This tells @code{evalf()} to not recursively evaluate the parameters of the
+function before calling the @code{evalf_func()}.
+
+@example
+set_return_type(unsigned return_type, unsigned return_type_tinfo)
+@end example
+
+This allows you to explicitly specify the commutation properties of the
+function (@xref{Non-commutative objects}, for an explanation of
+(non)commutativity in GiNaC). For example, you can use
+@code{set_return_type(return_types::noncommutative, TINFO_matrix)} to make
+GiNaC treat your function like a matrix. By default, functions inherit the
+commutation properties of their first argument.
+
+@example
+set_symmetry(const symmetry & s)
+@end example
+
+specifies the symmetry properties of the function with respect to its
+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;
+
+ // 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