]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
fixed typo
[ginac.git] / doc / tutorial / ginac.texi
index 15e5e798e20095b38b35f8e17a438a11d0ca160c..f9bd79131451dde72a9477afdce0f0f00613f321 100644 (file)
@@ -4809,8 +4809,17 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Li2(x)}
 @tab Dilogarithm
 @cindex @code{Li2()}
+@item @code{Li(n, x)}
+@tab classical polylogarithm as well as multiple polylogarithm
+@cindex @code{Li()}
+@item @code{S(n, p, x)}
+@tab Nielsen's generalized polylogarithm
+@cindex @code{S()}
+@item @code{H(n, x)}
+@tab harmonic polylogarithm
+@cindex @code{H()}
 @item @code{zeta(x)}
-@tab Riemann's zeta function
+@tab Riemann's zeta function as well as multiple zeta value
 @cindex @code{zeta()}
 @item @code{zeta(n, x)}
 @tab derivatives of Riemann's zeta function
@@ -4838,21 +4847,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 +4866,25 @@ serious CAS.  It is to be expected that future revisions of the C++
 standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
+@cindex nested sums
+The functions @code{Li}, @code{S}, @code{H} and @code{zeta} share certain
+properties and are refered to as nested sums functions, because they all
+have a uniform representation as nested sums (for mathematical details and
+conventions see @emph{S.Moch, P.Uwer, S.Weinzierl hep-ph/0110083}).
+@code{Li} and @code{zeta} can take @code{lst}s as arguments, in which case
+they represent not classical polylogarithms or simple zeta functions but
+multiple polylogarithms or multiple zeta values respectively (note that the two
+@code{lst}s for @code{Li} must have the same length). The first parameter
+of the harmonic polylogarithm can also be a @code{lst}.
+For all these functions the arguments in the @code{lst}s are expected to be
+in the same order as they appear in the nested sums representation
+(note that this convention differs from the one in the aforementioned paper 
+in the cases of @code{Li} and @code{zeta}).
+If you want to numerically evaluate the functions, the parameters @code{n}
+and @code{p} as well as @code{x} in the case of @code{zeta} must all be
+positive integers (or @code{lst}s containing them). The multiple polylogarithm
+has the additional restriction that the second parameter must only
+contain arguments with an absolute value smaller than one.
 
 @node Solving Linear Systems of Equations, Input/Output, Built-in Functions, Methods and Functions
 @c    node-name, next, previous, up
@@ -5438,12 +5451,7 @@ that is not further evaluated:
 @example
 DECLARE_FUNCTION_2P(myfcn)
 
-static ex myfcn_eval(const ex & x, const ex & y)
-@{
-    return myfcn(x, y).hold();
-@}
-
-REGISTER_FUNCTION(myfcn, eval_func(myfcn_eval))
+REGISTER_FUNCTION(myfcn, dummy())
 @end example
 
 Any code that has seen the @code{DECLARE_FUNCTION} line can use @code{myfcn()}
@@ -5453,33 +5461,20 @@ in algebraic expressions:
 @{
     ...
     symbol x("x");
-    ex e = 2*myfcn(42, 3*x+1) - x;
-     // this calls myfcn_eval(42, 3*x+1), and inserts its return value into
-     // the actual expression
+    ex e = 2*myfcn(42, 1+3*x) - x;
     cout << e << endl;
      // prints '2*myfcn(42,1+3*x)-x'
     ...
 @}
 @end example
 
-@cindex @code{hold()}
-@cindex evaluation
-The @code{eval_func()} option specifies the C++ function that implements
-the @code{eval()} method, GiNaC's anonymous evaluator. This function takes
-the same number of arguments as the associated symbolic function (two in this
-case) and returns the (possibly transformed or in some way simplified)
-symbolically evaluated function (@xref{Automatic evaluation}, for a description
-of the automatic evaluation process). If no (further) evaluation is to take
-place, the @code{eval_func()} function must return the original function
-with @code{.hold()}, to avoid a potential infinite recursion. If your
-symbolic functions produce a segmentation fault or stack overflow when
-using them in expressions, you are probably missing a @code{.hold()}
-somewhere.
+The @code{dummy()} option in the @code{REGISTER_FUNCTION} line signifies
+"no options". A function with no options specified merely acts as a kind of
+container for its arguments. It is a pure "dummy" function with no associated
+logic (which is, however, sometimes perfectly sufficient).
 
-There is not much you can do with the @code{myfcn} function. It merely acts
-as a kind of container for its arguments (which is, however, sometimes
-perfectly sufficient). Let's have a look at the implementation of GiNaC's
-cosine function.
+Let's now have a look at the implementation of GiNaC's cosine function for an
+example of how to make an "intelligent" function.
 
 @subsection The cosine function
 
@@ -5493,9 +5488,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 +5543,20 @@ static ex cos_eval(const ex & x)
 @}
 @end example
 
+This function is called every time the cosine is used in a symbolic expression:
+
+@example
+@{
+    ...
+    e = cos(Pi);
+     // this calls cos_eval(Pi), and inserts its return value into
+     // the actual expression
+    cout << e << endl;
+     // prints '-1'
+    ...
+@}
+@end example
+
 In this way, @code{cos(4*Pi)} automatically becomes @math{1},
 @code{cos(asin(a+b))} becomes @code{sqrt(1-(a+b)^2)}, etc. If no reasonable
 symbolic transformation can be done, the unmodified function is returned
@@ -5585,26 +5623,13 @@ static ex tan_series(const ex & x, const relational & rel,
 The @code{series()} implementation of a function @emph{must} return a
 @code{pseries} object, otherwise your code will crash.
 
-Now that all the ingredients have been set up, the @code{REGISTER_FUNCTION}
-macro is used to tell the system how the @code{cos()} function behaves:
-
-@example
-REGISTER_FUNCTION(cos, eval_func(cos_eval).
-                       evalf_func(cos_evalf).
-                       derivative_func(cos_deriv).
-                       latex_name("\\cos"));
-@end example
-
-This registers the @code{cos_eval()}, @code{cos_evalf()} and
-@code{cos_deriv()} C++ functions with the @code{cos()} function, and also
-gives it a proper LaTeX name.
-
 @subsection Function options
 
 GiNaC functions understand several more options which are always
 specified as @code{.option(params)}. None of them are required, but you
-need to specify at least one option to @code{REGISTER_FUNCTION()} (usually
-the @code{eval()} method).
+need to specify at least one option to @code{REGISTER_FUNCTION()}. There
+is a do-nothing option called @code{dummy()} which you can use to define
+functions without any special options.
 
 @example
 eval_func(<C++ function>)
@@ -5921,6 +5946,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 +7394,7 @@ The following shows how to build a simple package using automake
 and the @samp{AM_PATH_GINAC} macro. The program used here is @file{simple.cpp}:
 
 @example
+#include <iostream>
 #include <ginac/ginac.h>
 
 int main()