]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
Fixed {} bug
[ginac.git] / doc / tutorial / ginac.texi
index 15e5e798e20095b38b35f8e17a438a11d0ca160c..eaae40afd3eb0038f6e56b62a57732c2637e5146 100644 (file)
@@ -4480,7 +4480,7 @@ method. It can also already contain a list of replacements from an earlier
 application of @code{.to_polynomial()} or @code{.to_rational()}, so it's
 possible to use it on multiple expressions and get consistent results.
 
-The difference betwerrn @code{.to_polynomial()} and @code{.to_rational()}
+The difference between @code{.to_polynomial()} and @code{.to_rational()}
 is probably best illustrated with an example:
 
 @example
@@ -4747,6 +4747,8 @@ almost any kind of object (anything that is @code{subs()}able):
 @node Built-in Functions, Solving Linear Systems of Equations, Symmetrization, Methods and Functions
 @c    node-name, next, previous, up
 @section Predefined mathematical functions
+@c
+@subsection Overview
 
 GiNaC contains the following predefined mathematical functions:
 
@@ -4807,22 +4809,34 @@ GiNaC contains the following predefined mathematical functions:
 @tab natural logarithm
 @cindex @code{log()}
 @item @code{Li2(x)}
-@tab Dilogarithm
+@tab dilogarithm
 @cindex @code{Li2()}
-@item @code{zeta(x)}
-@tab Riemann's zeta function
+@item @code{Li(m, x)}
+@tab classical polylogarithm as well as multiple polylogarithm
+@cindex @code{Li()}
+@item @code{S(n, p, x)}
+@tab Nielsen's generalized polylogarithm
+@cindex @code{S()}
+@item @code{H(m, x)}
+@tab harmonic polylogarithm
+@cindex @code{H()}
+@item @code{zeta(m)}
+@tab Riemann's zeta function as well as multiple zeta value
 @cindex @code{zeta()}
-@item @code{zeta(n, x)}
+@item @code{zeta(m, s)}
+@tab alternating Euler sum
+@cindex @code{zeta()}
+@item @code{zetaderiv(n, x)}
 @tab derivatives of Riemann's zeta function
 @item @code{tgamma(x)}
-@tab Gamma function
+@tab gamma function
 @cindex @code{tgamma()}
-@cindex Gamma function
+@cindex gamma function
 @item @code{lgamma(x)}
-@tab logarithm of Gamma function
+@tab logarithm of gamma function
 @cindex @code{lgamma()}
 @item @code{beta(x, y)}
-@tab Beta function (@code{tgamma(x)*tgamma(y)/tgamma(x+y)})
+@tab beta function (@code{tgamma(x)*tgamma(y)/tgamma(x+y)})
 @cindex @code{beta()}
 @item @code{psi(x)}
 @tab psi (digamma) function
@@ -4838,21 +4852,6 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Order(x)}
 @tab order term function in truncated power series
 @cindex @code{Order()}
-@item @code{Li(n, x)}
-@tab polylogarithm
-@cindex @code{Li()}
-@item @code{S(n, p, x)}
-@tab Nielsen's generalized polylogarithm
-@cindex @code{S()}
-@item @code{H(m_lst, x)}
-@tab harmonic polylogarithm
-@cindex @code{H()}
-@item @code{Li(m_lst, x_lst)}
-@tab multiple polylogarithm
-@cindex @code{Li()}
-@item @code{mZeta(m_lst)}
-@tab multiple zeta value
-@cindex @code{mZeta()}
 @end multitable
 @end cartouche
 
@@ -4872,6 +4871,148 @@ serious CAS.  It is to be expected that future revisions of the C++
 standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
+@subsection Multiple polylogarithms
+
+@cindex polylogarithm
+@cindex Nielsen's generalized polylogarithm
+@cindex harmonic polylogarithm
+@cindex multiple zeta value
+@cindex alternating Euler sum
+@cindex multiple polylogarithm
+
+The multiple polylogarithm is the most generic member of a family of functions,
+to which others like the harmonic polylogarithm, Nielsen's generalized
+polylogarithm and the multiple zeta value belong.
+Everyone of these functions can also be written as a multiple polylogarithm with specific
+parameters. This whole family of functions is therefore often refered to simply as
+multiple polylogarithms, containing @code{Li}, @code{H}, @code{S} and @code{zeta}.
+
+To facilitate the discussion of these functions we distinguish between indices and
+arguments as parameters. In the table above indices are printed as @code{m}, @code{s},
+@code{n} or @code{p}, whereas arguments are printed as @code{x}.
+
+To define a @code{Li}, @code{H} or @code{zeta} with a depth greater than one, you have to
+pass a GiNaC @code{lst} for the indices @code{m} and @code{s}, and in the case of @code{Li}
+for the argument @code{x} as well.
+Note that @code{Li} and @code{zeta} are polymorphic in this respect. They can stand in for
+the classical polylogarithm and Riemann's zeta function (if depth is one), as well as for
+the multiple polylogarithm and the multiple zeta value, respectively. Note also, that
+GiNaC doesn't check whether the @code{lst}s for two parameters do have the same length.
+It is up to the user to ensure this, otherwise evaluating will result in undefined behavior.
+
+The functions print in LaTeX format as
+@tex
+${\rm Li\;\!}_{m_1,m_2,\ldots,m_k}(x_1,x_2,\ldots,x_k)$, 
+@end tex
+@tex
+${\rm S}_{n,p}(x)$, 
+@end tex
+@tex
+${\rm H\;\!}_{m_1,m_2,\ldots,m_k}(x)$ and 
+@end tex
+@tex
+$\zeta(m_1,m_2,\ldots,m_k)$.
+@end tex
+If @code{zeta} is an alternating zeta sum, i.e. @code{zeta(m,s)}, the indices with negative sign
+are printed with a line above, e.g.
+@tex
+$\zeta(5,\overline{2})$.
+@end tex
+The order of indices and arguments in the GiNaC @code{lst}s and in the output is the same.
+
+Definitions and analytical as well as numerical properties of multiple polylogarithms
+are too numerous to be covered here. Instead, the user is refered to the publications listed at the
+end of this section. The implementation in GiNaC adheres to the definitions and conventions therein,
+except for a few differences which will be explicitly stated in the following.
+
+One difference is about the order of the indices and arguments. For GiNac we adopt the convention
+that the indices and arguments are understood to be in the same order as in which they appear in
+the series representation. This means
+@tex
+${\rm Li\;\!}_{m_1,m_2,m_3}(x,1,1) = {\rm H\;\!}_{m_1,m_2,m_3}(x)$ and 
+@end tex
+@tex
+${\rm Li\;\!}_{2,1}(1,1) = \zeta(2,1) = \zeta(3)$, but
+@end tex
+@tex
+$\zeta(1,2)$ evaluates to infinity.
+@end tex
+So in comparison to the referenced publications the order of indices and arguments for @code{Li}
+is reversed.
+
+The functions only evaluate if the indices are integers greater than zero, except for the indices
+@code{s} in @code{zeta} and @code{m} in @code{H}. Since @code{s} will be interpreted as the sequence
+of signs for the corresponding indices @code{m}, it must contain 1 or -1, e.g.
+@code{zeta(lst(3,4), lst(-1,1))} means
+@tex
+$\zeta(\overline{3},4)$.
+@end tex
+The definition of @code{H} allows indices to be 0, 1 or -1 (in expanded notation) or equally to
+be any integer (in compact notation). With GiNaC expanded and compact notation can be mixed,
+e.g. @code{lst(0,0,-1,0,1,0,0)}, @code{lst(0,0,-1,2,0,0)} and @code{lst(-3,2,0,0)} are equivalent as
+indices. The anonymous evaluator @code{eval()} tries to reduce the functions, if possible, to
+the least-generic multiple polylogarithm. If all arguments are unit, it returns @code{zeta}.
+Arguments equal to zero get considered, too. Riemann's zeta function @code{zeta} (with depth one)
+evaluates also for negative integers and positive even integers. For example:
+
+@example
+> Li(@{3,1@},@{x,1@});
+S(2,2,x)
+> H(@{-3,2@},1);
+-zeta(@{3,2@},@{-1,-1@})
+> S(3,1,1);
+1/90*Pi^4
+@end example
+
+It is easy to tell for a given function into which other function it can be rewritten, may
+it be a less-generic or a more-generic one, except for harmonic polylogarithms @code{H}
+with negative indices or trailing zeros (the example above gives a hint). Signs can
+quickly be messed up, for example. Therefore GiNaC offers a C++ function
+@code{convert_H_to_Li()} to deal with the upgrade of a @code{H} to a multiple polylogarithm
+@code{Li} (@code{eval()} already cares for the possible downgrade):
+
+@example
+> convert_H_to_Li(@{0,-2,-1,3@},x);
+Li(@{3,1,3@},@{-x,1,-1@})
+> convert_H_to_Li(@{2,-1,0@},x);
+-Li(@{2,1@},@{x,-1@})*log(x)+2*Li(@{3,1@},@{x,-1@})+Li(@{2,2@},@{x,-1@})
+@end example
+
+Every function apart from the multiple polylogarithm @code{Li} can be numerically evaluated for
+arbitrary real or complex arguments. @code{Li} only evaluates if for all arguments
+@tex
+$x_i$ the condition
+@end tex
+@tex
+$x_1x_2\cdots x_i < 1$ holds.
+@end tex
+
+@example
+> Digits=100;
+100
+> evalf(zeta(@{3,1,3,1@}));
+0.005229569563530960100930652283899231589890420784634635522547448972148869544...
+@end example
+
+If a function evaluates to infinity, no exceptions are raised, but the function is returned
+unevaluated, e.g.
+@tex
+$\zeta(1)$.
+@end tex
+In long expressions this helps a lot with debugging, because you can easily spot
+the divergencies. But on the other hand, you have to make sure for yourself, that no illegal
+cancellations of divergencies happen.
+
+Useful publications:
+
+@cite{Nested Sums, Expansion of Transcendental Functions and Multi-Scale Multi-Loop Integrals}, 
+S.Moch, P.Uwer, S.Weinzierl, hep-ph/0110083
+
+@cite{Harmonic Polylogarithms}, 
+E.Remiddi, J.A.M.Vermaseren, Int.J.Mod.Phys. A15 (2000), pp. 725-754
+
+@cite{Special Values of Multiple Polylogarithms}, 
+J.Borwein, D.Bradley, D.Broadhurst, P.Lisonek, Trans.Amer.Math.Soc. 353/3 (2001), pp. 907-941
 
 @node Solving Linear Systems of Equations, Input/Output, Built-in Functions, Methods and Functions
 @c    node-name, next, previous, up
@@ -5090,7 +5231,7 @@ static void my_print(const ex & e)
     if (is_a<function>(e))
         cout << ex_to<function>(e).get_name();
     else
-        cout << e.bp->class_name();
+        cout << ex_to<basic>(e).class_name();
     cout << "(";
     size_t n = e.nops();
     if (n)
@@ -5438,12 +5579,7 @@ that is not further evaluated:
 @example
 DECLARE_FUNCTION_2P(myfcn)
 
-static ex myfcn_eval(const ex & x, const ex & y)
-@{
-    return myfcn(x, y).hold();
-@}
-
-REGISTER_FUNCTION(myfcn, eval_func(myfcn_eval))
+REGISTER_FUNCTION(myfcn, dummy())
 @end example
 
 Any code that has seen the @code{DECLARE_FUNCTION} line can use @code{myfcn()}
@@ -5453,33 +5589,20 @@ in algebraic expressions:
 @{
     ...
     symbol x("x");
-    ex e = 2*myfcn(42, 3*x+1) - x;
-     // this calls myfcn_eval(42, 3*x+1), and inserts its return value into
-     // the actual expression
+    ex e = 2*myfcn(42, 1+3*x) - x;
     cout << e << endl;
      // prints '2*myfcn(42,1+3*x)-x'
     ...
 @}
 @end example
 
-@cindex @code{hold()}
-@cindex evaluation
-The @code{eval_func()} option specifies the C++ function that implements
-the @code{eval()} method, GiNaC's anonymous evaluator. This function takes
-the same number of arguments as the associated symbolic function (two in this
-case) and returns the (possibly transformed or in some way simplified)
-symbolically evaluated function (@xref{Automatic evaluation}, for a description
-of the automatic evaluation process). If no (further) evaluation is to take
-place, the @code{eval_func()} function must return the original function
-with @code{.hold()}, to avoid a potential infinite recursion. If your
-symbolic functions produce a segmentation fault or stack overflow when
-using them in expressions, you are probably missing a @code{.hold()}
-somewhere.
+The @code{dummy()} option in the @code{REGISTER_FUNCTION} line signifies
+"no options". A function with no options specified merely acts as a kind of
+container for its arguments. It is a pure "dummy" function with no associated
+logic (which is, however, sometimes perfectly sufficient).
 
-There is not much you can do with the @code{myfcn} function. It merely acts
-as a kind of container for its arguments (which is, however, sometimes
-perfectly sufficient). Let's have a look at the implementation of GiNaC's
-cosine function.
+Let's now have a look at the implementation of GiNaC's cosine function for an
+example of how to make an "intelligent" function.
 
 @subsection The cosine function
 
@@ -5493,9 +5616,38 @@ which declares to all programs using GiNaC that there is a function @samp{cos}
 that takes one @code{ex} as an argument. This is all they need to know to use
 this function in expressions.
 
-The implementation of the cosine function is in @file{inifcns_trans.cpp}. The
-@code{eval_func()} function looks something like this (actually, it doesn't
-look like this at all, but it should give you an idea what is going on):
+The implementation of the cosine function is in @file{inifcns_trans.cpp}. Here
+is its @code{REGISTER_FUNCTION} line:
+
+@example
+REGISTER_FUNCTION(cos, eval_func(cos_eval).
+                       evalf_func(cos_evalf).
+                       derivative_func(cos_deriv).
+                       latex_name("\\cos"));
+@end example
+
+There are four options defined for the cosine function. One of them
+(@code{latex_name}) gives the function a proper name for LaTeX output; the
+other three indicate the C++ functions in which the "brains" of the cosine
+function are defined.
+
+@cindex @code{hold()}
+@cindex evaluation
+The @code{eval_func()} option specifies the C++ function that implements
+the @code{eval()} method, GiNaC's anonymous evaluator. This function takes
+the same number of arguments as the associated symbolic function (one in this
+case) and returns the (possibly transformed or in some way simplified)
+symbolically evaluated function (@xref{Automatic evaluation}, for a description
+of the automatic evaluation process). If no (further) evaluation is to take
+place, the @code{eval_func()} function must return the original function
+with @code{.hold()}, to avoid a potential infinite recursion. If your
+symbolic functions produce a segmentation fault or stack overflow when
+using them in expressions, you are probably missing a @code{.hold()}
+somewhere.
+
+The @code{eval_func()} function for the cosine looks something like this
+(actually, it doesn't look like this at all, but it should give you an idea
+what is going on):
 
 @example
 static ex cos_eval(const ex & x)
@@ -5519,6 +5671,20 @@ static ex cos_eval(const ex & x)
 @}
 @end example
 
+This function is called every time the cosine is used in a symbolic expression:
+
+@example
+@{
+    ...
+    e = cos(Pi);
+     // this calls cos_eval(Pi), and inserts its return value into
+     // the actual expression
+    cout << e << endl;
+     // prints '-1'
+    ...
+@}
+@end example
+
 In this way, @code{cos(4*Pi)} automatically becomes @math{1},
 @code{cos(asin(a+b))} becomes @code{sqrt(1-(a+b)^2)}, etc. If no reasonable
 symbolic transformation can be done, the unmodified function is returned
@@ -5585,26 +5751,13 @@ static ex tan_series(const ex & x, const relational & rel,
 The @code{series()} implementation of a function @emph{must} return a
 @code{pseries} object, otherwise your code will crash.
 
-Now that all the ingredients have been set up, the @code{REGISTER_FUNCTION}
-macro is used to tell the system how the @code{cos()} function behaves:
-
-@example
-REGISTER_FUNCTION(cos, eval_func(cos_eval).
-                       evalf_func(cos_evalf).
-                       derivative_func(cos_deriv).
-                       latex_name("\\cos"));
-@end example
-
-This registers the @code{cos_eval()}, @code{cos_evalf()} and
-@code{cos_deriv()} C++ functions with the @code{cos()} function, and also
-gives it a proper LaTeX name.
-
 @subsection Function options
 
 GiNaC functions understand several more options which are always
 specified as @code{.option(params)}. None of them are required, but you
-need to specify at least one option to @code{REGISTER_FUNCTION()} (usually
-the @code{eval()} method).
+need to specify at least one option to @code{REGISTER_FUNCTION()}. There
+is a do-nothing option called @code{dummy()} which you can use to define
+functions without any special options.
 
 @example
 eval_func(<C++ function>)
@@ -5921,6 +6074,89 @@ 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
+
 
 @node Structures, Adding classes, Printing, Extending GiNaC
 @c    node-name, next, previous, up
@@ -7286,6 +7522,7 @@ The following shows how to build a simple package using automake
 and the @samp{AM_PATH_GINAC} macro. The program used here is @file{simple.cpp}:
 
 @example
+#include <iostream>
 #include <ginac/ginac.h>
 
 int main()