]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
do changes to top-level files get posted to ginac-cvs now?
[ginac.git] / doc / tutorial / ginac.texi
index 6ed69023339a20a225bb1a9a48fbfca61da1a06e..e6993f33dd2ddceb2dd48428bbcd6aa0a55bd1c7 100644 (file)
@@ -519,15 +519,19 @@ want to have the documentation installed in some other directory than
 
 @end itemize
 
 
 @end itemize
 
-In addition, you may specify some environment variables.
-@env{CXX} holds the path and the name of the C++ compiler
-in case you want to override the default in your path.  (The
-@command{configure} script searches your path for @command{c++},
-@command{g++}, @command{gcc}, @command{CC}, @command{cxx}
-and @command{cc++} in that order.)  It may be very useful to
-define some compiler flags with the @env{CXXFLAGS} environment
-variable, like optimization, debugging information and warning
-levels.  If omitted, it defaults to @option{-g -O2}.
+In addition, you may specify some environment variables.  @env{CXX}
+holds the path and the name of the C++ compiler in case you want to
+override the default in your path.  (The @command{configure} script
+searches your path for @command{c++}, @command{g++}, @command{gcc},
+@command{CC}, @command{cxx} and @command{cc++} in that order.)  It may
+be very useful to define some compiler flags with the @env{CXXFLAGS}
+environment variable, like optimization, debugging information and
+warning levels.  If omitted, it defaults to @option{-g
+-O2}.@footnote{The @command{configure} script is itself generated from
+the file @file{configure.in}.  It is only distributed in packaged
+releases of GiNaC.  If you got the naked sources, e.g. from CVS, you
+must generate @command{configure} along with the various
+@file{Makefile.in} by using the @command{autogen.sh} script.}
 
 The whole process is illustrated in the following two
 examples. (Substitute @command{setenv @var{VARIABLE} @var{value}} for
 
 The whole process is illustrated in the following two
 examples. (Substitute @command{setenv @var{VARIABLE} @var{value}} for
@@ -550,7 +554,7 @@ assertions and debugging information are switched on:
 @example
 $ export CXX=/usr/local/gnu/bin/c++
 $ export CPPFLAGS="$(CPPFLAGS) -I$(HOME)/include"
 @example
 $ export CXX=/usr/local/gnu/bin/c++
 $ export CPPFLAGS="$(CPPFLAGS) -I$(HOME)/include"
-$ export CXXFLAGS="$(CXXFLAGS) -DDO_GINAC_ASSERT -ggdb -Wall -ansi -pedantic"
+$ export CXXFLAGS="$(CXXFLAGS) -DDO_GINAC_ASSERT -ggdb -Wall -pedantic"
 $ export LDFLAGS="$(LDFLAGS) -L$(HOME)/lib"
 $ ./configure --disable-shared --prefix=$(HOME)
 @end example
 $ export LDFLAGS="$(LDFLAGS) -L$(HOME)/lib"
 $ ./configure --disable-shared --prefix=$(HOME)
 @end example
@@ -664,6 +668,7 @@ meta-class for storing all mathematical objects.
 @menu
 * Expressions::                  The fundamental GiNaC class.
 * The Class Hierarchy::          Overview of GiNaC's classes.
 @menu
 * Expressions::                  The fundamental GiNaC class.
 * The Class Hierarchy::          Overview of GiNaC's classes.
+* Error handling::               How the library reports errors.
 * Symbols::                      Symbolic objects.
 * Numbers::                      Numerical objects.
 * Constants::                    Pre-defined constants.
 * Symbols::                      Symbolic objects.
 * Numbers::                      Numerical objects.
 * Constants::                    Pre-defined constants.
@@ -711,7 +716,7 @@ hierarchy and describe the classes of objects that are handled by
 @code{ex}.
 
 
 @code{ex}.
 
 
-@node The Class Hierarchy, Symbols, Expressions, Basic Concepts
+@node The Class Hierarchy, Error handling, Expressions, Basic Concepts
 @c    node-name, next, previous, up
 @section The Class Hierarchy
 
 @c    node-name, next, previous, up
 @section The Class Hierarchy
 
@@ -777,7 +782,64 @@ $\sqrt{2}$
 @end multitable
 @end cartouche
 
 @end multitable
 @end cartouche
 
-@node Symbols, Numbers, The Class Hierarchy, Basic Concepts
+
+@node Error handling, Symbols, The Class Hierarchy, Basic Concepts
+@c    node-name, next, previous, up
+@section Error handling
+@cindex exceptions
+@cindex @code{pole_error} (class)
+
+GiNaC reports run-time errors by throwing C++ exceptions. All exceptions
+generated by GiNaC are subclassed from the standard @code{exception} class
+defined in the @file{<stdexcept>} header. In addition to the predefined
+@code{logic_error}, @code{domain_error}, @code{out_of_range},
+@code{invalid_argument}, @code{runtime_error}, @code{range_error} and
+@code{overflow_error} types, GiNaC also defines a @code{pole_error}
+exception that gets thrown when trying to evaluate a mathematical function
+at a singularity.
+
+The @code{pole_error} class has a member function
+
+@example
+int pole_error::degree(void) const;
+@end example
+
+that returns the order of the singularity (or 0 when the pole is
+logarithmic or the order is undefined).
+
+When using GiNaC it is useful to arrange for exceptions to be catched in
+the main program even if you don't want to do any special error handling.
+Otherwise whenever an error occurs in GiNaC, it will be delegated to the
+default exception handler of your C++ compiler's run-time system which
+ususally only aborts the program without giving any information what went
+wrong.
+
+Here is an example for a @code{main()} function that catches and prints
+exceptions generated by GiNaC:
+
+@example
+#include <iostream>
+#include <stdexcept>
+#include <ginac/ginac.h>
+using namespace std;
+using namespace GiNaC;
+
+int main(void)
+@{
+    try @{
+        ...
+        // code using GiNaC
+        ...
+    @} catch (exception &p) @{
+        cerr << p.what() << endl;
+        return 1;
+    @}
+    return 0;
+@}
+@end example
+
+
+@node Symbols, Numbers, Error handling, Basic Concepts
 @c    node-name, next, previous, up
 @section Symbols
 @cindex @code{symbol} (class)
 @c    node-name, next, previous, up
 @section Symbols
 @cindex @code{symbol} (class)
@@ -856,10 +918,10 @@ using namespace GiNaC;
 
 int main()
 @{
 
 int main()
 @{
-    numeric two(2);                       // exact integer 2
+    numeric two = 2;                      // exact integer 2
     numeric r(2,3);                       // exact fraction 2/3
     numeric e(2.71828);                   // floating point number
     numeric r(2,3);                       // exact fraction 2/3
     numeric e(2.71828);                   // floating point number
-    numeric p("3.1415926535897932385");   // floating point number
+    numeric p = "3.14159265358979323846"; // constructor from string
     // Trott's constant in scientific notation:
     numeric trott("1.0841015122311136151E-2");
     
     // Trott's constant in scientific notation:
     numeric trott("1.0841015122311136151E-2");
     
@@ -867,18 +929,6 @@ int main()
 @}
 @end example
 
 @}
 @end example
 
-Note that all those constructors are @emph{explicit} which means you are
-not allowed to write @code{numeric two=2;}.  This is because the basic
-objects to be handled by GiNaC are the expressions @code{ex} and we want
-to keep things simple and wish objects like @code{pow(x,2)} to be
-handled the same way as @code{pow(x,a)}, which means that we need to
-allow a general @code{ex} as base and exponent.  Therefore there is an
-implicit constructor from C-integers directly to expressions handling
-numerics at work in most of our examples.  This design really becomes
-convenient when one declares own functions having more than one
-parameter but it forbids using implicit constructors because that would
-lead to compile-time ambiguities.
-
 It may be tempting to construct numbers writing @code{numeric r(3/2)}.
 This would, however, call C's built-in operator @code{/} for integers
 first and result in a numeric holding a plain integer 1.  @strong{Never
 It may be tempting to construct numbers writing @code{numeric r(3/2)}.
 This would, however, call C's built-in operator @code{/} for integers
 first and result in a numeric holding a plain integer 1.  @strong{Never
@@ -1196,11 +1246,12 @@ There are quite a number of useful functions hard-wired into GiNaC.  For
 instance, all trigonometric and hyperbolic functions are implemented
 (@xref{Built-in Functions}, for a complete list).
 
 instance, all trigonometric and hyperbolic functions are implemented
 (@xref{Built-in Functions}, for a complete list).
 
-These functions are all objects of class @code{function}.  They accept
-one or more expressions as arguments and return one expression.  If the
-arguments are not numerical, the evaluation of the function may be
-halted, as it does in the next example, showing how a function returns
-itself twice and finally an expression that may be really useful:
+These functions (better called @emph{pseudofunctions}) are all objects
+of class @code{function}.  They accept one or more expressions as
+arguments and return one expression.  If the arguments are not
+numerical, the evaluation of the function may be halted, as it does in
+the next example, showing how a function returns itself twice and
+finally an expression that may be really useful:
 
 @cindex Gamma function
 @cindex @code{subs()}
 
 @cindex Gamma function
 @cindex @code{subs()}
@@ -1223,6 +1274,18 @@ Besides evaluation most of these functions allow differentiation, series
 expansion and so on.  Read the next chapter in order to learn more about
 this.
 
 expansion and so on.  Read the next chapter in order to learn more about
 this.
 
+It must be noted that these pseudofunctions are created by inline
+functions, where the argument list is templated.  This means that
+whenever you call @code{GiNaC::sin(1)} it is equivalent to
+@code{sin(ex(1))} and will therefore not result in a floating point
+numeber.  Unless of course the function prototype is explicitly
+overridden -- which is the case for arguments of type @code{numeric}
+(not wrapped inside an @code{ex}).  Hence, in order to obtain a floating
+point number of class @code{numeric} you should call
+@code{sin(numeric(1))}.  This is almost the same as calling
+@code{sin(1).evalf()} except that the latter will return a numeric
+wrapped inside an @code{ex}.
+
 
 @node Relations, Matrices, Mathematical functions, Basic Concepts
 @c    node-name, next, previous, up
 
 @node Relations, Matrices, Mathematical functions, Basic Concepts
 @c    node-name, next, previous, up
@@ -1870,6 +1933,8 @@ that performs some more expensive operations:
 @item it (symbolically) calculates all possible dummy index summations/contractions
   with the predefined tensors (this will be explained in more detail in the
   next section)
 @item it (symbolically) calculates all possible dummy index summations/contractions
   with the predefined tensors (this will be explained in more detail in the
   next section)
+@item it detects contractions that vanish for symmetry reasons, for example
+  the contraction of a symmetric and a totally antisymmetric tensor
 @item as a special case of dummy index summation, it can replace scalar products
   of two tensors with a user-defined value
 @end itemize
 @item as a special case of dummy index summation, it can replace scalar products
   of two tensors with a user-defined value
 @end itemize
@@ -2071,7 +2136,27 @@ The first two functions create an epsilon tensor in 2 or 3 Euclidean
 dimensions, the last function creates an epsilon tensor in a 4-dimensional
 Minkowski space (the last @code{bool} argument specifies whether the metric
 has negative or positive signature, as in the case of the Minkowski metric
 dimensions, the last function creates an epsilon tensor in a 4-dimensional
 Minkowski space (the last @code{bool} argument specifies whether the metric
 has negative or positive signature, as in the case of the Minkowski metric
-tensor).
+tensor):
+
+@example
+@{
+    varidx mu(symbol("mu"), 4), nu(symbol("nu"), 4), rho(symbol("rho"), 4),
+           sig(symbol("sig"), 4), lam(symbol("lam"), 4), bet(symbol("bet"), 4);
+    e = lorentz_eps(mu, nu, rho, sig) *
+        lorentz_eps(mu.toggle_variance(), nu.toggle_variance(), lam, bet);
+    cout << simplify_indexed(e) << endl;
+     // -> 2*eta~bet~rho*eta~sig~lam-2*eta~sig~bet*eta~rho~lam
+
+    idx i(symbol("i"), 3), j(symbol("j"), 3), k(symbol("k"), 3);
+    symbol A("A"), B("B");
+    e = epsilon_tensor(i, j, k) * indexed(A, j) * indexed(B, k);
+    cout << simplify_indexed(e) << endl;
+     // -> -B.k*A.j*eps.i.k.j
+    e = epsilon_tensor(i, j, k) * indexed(A, j) * indexed(A, k);
+    cout << simplify_indexed(e) << endl;
+     // -> 0
+@}
+@end example
 
 @subsection Linear algebra
 
 
 @subsection Linear algebra
 
@@ -2264,8 +2349,14 @@ The unity element of a Clifford algebra is constructed by
 ex dirac_ONE(unsigned char rl = 0);
 @end example
 
 ex dirac_ONE(unsigned char rl = 0);
 @end example
 
+@strong{Note:} You must always use @code{dirac_ONE()} when referring to
+multiples of the unity element, even though it's customary to omit it.
+E.g. instead of @code{dirac_gamma(mu)*(dirac_slash(q,4)+m)} you have to
+write @code{dirac_gamma(mu)*(dirac_slash(q,4)+m*dirac_ONE())}. Otherwise,
+GiNaC may produce incorrect results.
+
 @cindex @code{dirac_gamma5()}
 @cindex @code{dirac_gamma5()}
-and there's a special element @samp{gamma5} that commutes with all other
+There's a special element @samp{gamma5} that commutes with all other
 gammas and in 4 dimensions equals @samp{gamma~0 gamma~1 gamma~2 gamma~3},
 provided by
 
 gammas and in 4 dimensions equals @samp{gamma~0 gamma~1 gamma~2 gamma~3},
 provided by
 
@@ -2292,8 +2383,10 @@ Finally, the function
 ex dirac_slash(const ex & e, const ex & dim, unsigned char rl = 0);
 @end example
 
 ex dirac_slash(const ex & e, const ex & dim, unsigned char rl = 0);
 @end example
 
-creates a term of the form @samp{e.mu gamma~mu} with a new and unique index
-whose dimension is given by the @code{dim} argument.
+creates a term that represents a contraction of @samp{e} with the Dirac
+Lorentz vector (it behaves like a term of the form @samp{e.mu gamma~mu}
+with a unique index whose dimension is given by the @code{dim} argument).
+Such slashed expressions are printed with a trailing backslash, e.g. @samp{e\}.
 
 In products of dirac gammas, superfluous unity elements are automatically
 removed, squares are replaced by their values and @samp{gamma5} is
 
 In products of dirac gammas, superfluous unity elements are automatically
 removed, squares are replaced by their values and @samp{gamma5} is
@@ -2308,13 +2401,12 @@ contractions in gamma strings, for example
     ex e = dirac_gamma(mu) * dirac_slash(a, D)
          * dirac_gamma(mu.toggle_variance());
     cout << e << endl;
     ex e = dirac_gamma(mu) * dirac_slash(a, D)
          * dirac_gamma(mu.toggle_variance());
     cout << e << endl;
-     // -> (gamma~mu*gamma~symbol10*gamma.mu)*a.symbol10
+     // -> gamma~mu*a\*gamma.mu
     e = e.simplify_indexed();
     cout << e << endl;
     e = e.simplify_indexed();
     cout << e << endl;
-     // -> -gamma~symbol10*a.symbol10*D+2*gamma~symbol10*a.symbol10
+     // -> -D*a\+2*a\
     cout << e.subs(D == 4) << endl;
     cout << e.subs(D == 4) << endl;
-     // -> -2*gamma~symbol10*a.symbol10
-     // [ == -2 * dirac_slash(a, D) ]
+     // -> -2*a\
     ...
 @}
 @end example
     ...
 @}
 @end example
@@ -2428,9 +2520,15 @@ The unity element of a color algebra is constructed by
 ex color_ONE(unsigned char rl = 0);
 @end example
 
 ex color_ONE(unsigned char rl = 0);
 @end example
 
+@strong{Note:} You must always use @code{color_ONE()} when referring to
+multiples of the unity element, even though it's customary to omit it.
+E.g. instead of @code{color_T(a)*(color_T(b)*indexed(X,b)+1)} you have to
+write @code{color_T(a)*(color_T(b)*indexed(X,b)+color_ONE())}. Otherwise,
+GiNaC may produce incorrect results.
+
 @cindex @code{color_d()}
 @cindex @code{color_f()}
 @cindex @code{color_d()}
 @cindex @code{color_f()}
-and the functions
+The functions
 
 @example
 ex color_d(const ex & a, const ex & b, const ex & c);
 
 @example
 ex color_d(const ex & a, const ex & b, const ex & c);
@@ -3147,8 +3245,8 @@ GiNaC offers the @code{map()} method to aid in the implementation of such
 operations:
 
 @example
 operations:
 
 @example
-static ex ex::map(map_function & f) const;
-static ex ex::map(ex (*f)(const ex & e)) const;
+ex ex::map(map_function & f) const;
+ex ex::map(ex (*f)(const ex & e)) const;
 @end example
 
 In the first (preferred) form, @code{map()} takes a function object that
 @end example
 
 In the first (preferred) form, @code{map()} takes a function object that
@@ -3188,6 +3286,42 @@ This function object could then be used like this:
 @}
 @end example
 
 @}
 @end example
 
+Here is another example for you to meditate over. It removes quadratic
+terms in a variable from an expanded polynomial:
+
+@example
+struct map_rem_quad : public map_function @{
+    ex var;
+    map_rem_quad(const ex & var_) : var(var_) @{@}
+
+    ex operator()(const ex & e)
+    @{
+        if (is_a<add>(e) || is_a<mul>(e))
+           return e.map(*this);
+        else if (is_a<power>(e) && e.op(0).is_equal(var) && e.op(1).info(info_flags::even))
+            return 0;
+        else
+            return e;
+    @}
+@};
+
+...
+
+@{
+    symbol x("x"), y("y");
+
+    ex e;
+    for (int i=0; i<8; i++)
+        e += pow(x, i) * pow(y, 8-i) * (i+1);
+    cout << e << endl;
+     // -> 4*y^5*x^3+5*y^4*x^4+8*y*x^7+7*y^2*x^6+2*y^7*x+6*y^3*x^5+3*y^6*x^2+y^8
+
+    map_rem_quad rem_quad(x);
+    cout << rem_quad(e) << endl;
+     // -> 4*y^5*x^3+8*y*x^7+2*y^7*x+6*y^3*x^5+y^8
+@}
+@end example
+
 @command{ginsh} offers a slightly different implementation of @code{map()}
 that allows applying algebraic functions to operands. The second argument
 to @code{map()} is an expression containing the wildcard @samp{$0} which
 @command{ginsh} offers a slightly different implementation of @code{map()}
 that allows applying algebraic functions to operands. The second argument
 to @code{map()} is an expression containing the wildcard @samp{$0} which
@@ -3844,7 +3978,7 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{csgn(x)}
 @tab complex sign
 @item @code{sqrt(x)}
 @item @code{csgn(x)}
 @tab complex sign
 @item @code{sqrt(x)}
-@tab square root (not a GiNaC function proper but equivalent to @code{pow(x, numeric(1, 2)})
+@tab square root (not a GiNaC function, rather an alias for @code{pow(x, numeric(1, 2))})
 @item @code{sin(x)}
 @tab sine
 @item @code{cos(x)}
 @item @code{sin(x)}
 @tab sine
 @item @code{cos(x)}
@@ -3897,8 +4031,6 @@ GiNaC contains the following predefined mathematical functions:
 @tab binomial coefficients
 @item @code{Order(x)}
 @tab order term function in truncated power series
 @tab binomial coefficients
 @item @code{Order(x)}
 @tab order term function in truncated power series
-@item @code{Derivative(x, l)}
-@tab inert partial differentiation operator (used internally)
 @end multitable
 @end cartouche
 
 @end multitable
 @end cartouche
 
@@ -4116,19 +4248,19 @@ using namespace GiNaC;
 
 int main()
 @{
 
 int main()
 @{
-     symbol x("x");
-     string s;
-
-     cout << "Enter an expression containing 'x': ";
-     getline(cin, s);
-
-     try @{
-         ex e(s, lst(x));
-         cout << "The derivative of " << e << " with respect to x is ";
-         cout << e.diff(x) << ".\n";
-     @} catch (exception &p) @{
-         cerr << p.what() << endl;
-     @}
+    symbol x("x");
+    string s;
+
+    cout << "Enter an expression containing 'x': ";
+    getline(cin, s);
+
+    try @{
+        ex e(s, lst(x));
+        cout << "The derivative of " << e << " with respect to x is ";
+        cout << e.diff(x) << ".\n";
+    @} catch (exception &p) @{
+        cerr << p.what() << endl;
+    @}
 @}
 @end example
 
 @}
 @end example
 
@@ -4249,19 +4381,19 @@ static void my_print2(const archive_node & n)
             switch (p[i].type) @{
                 case archive_node::PTYPE_BOOL: @{
                     bool x;
             switch (p[i].type) @{
                 case archive_node::PTYPE_BOOL: @{
                     bool x;
-                    n.find_bool(name, x);
+                    n.find_bool(name, x, j);
                     cout << (x ? "true" : "false");
                     break;
                 @}
                 case archive_node::PTYPE_UNSIGNED: @{
                     unsigned x;
                     cout << (x ? "true" : "false");
                     break;
                 @}
                 case archive_node::PTYPE_UNSIGNED: @{
                     unsigned x;
-                    n.find_unsigned(name, x);
+                    n.find_unsigned(name, x, j);
                     cout << x;
                     break;
                 @}
                 case archive_node::PTYPE_STRING: @{
                     string x;
                     cout << x;
                     break;
                 @}
                 case archive_node::PTYPE_STRING: @{
                     string x;
-                    n.find_string(name, x);
+                    n.find_string(name, x, j);
                     cout << '\"' << x << '\"';
                     break;
                 @}
                     cout << '\"' << x << '\"';
                     break;
                 @}
@@ -4390,7 +4522,10 @@ function that does so, in this case the one in class @code{numeric}:
 @example
 static ex cos_evalf(const ex & x)
 @{
 @example
 static ex cos_evalf(const ex & x)
 @{
-    return cos(ex_to<numeric>(x));
+    if (is_a<numeric>(x))
+        return cos(ex_to<numeric>(x));
+    else
+        return cos(x).hold();
 @}
 @end example
 
 @}
 @end example
 
@@ -5555,6 +5690,10 @@ and George Labahn, ISBN 0-7923-9259-0, 1992, Kluwer Academic Publishers, Norwell
 J.H. Davenport, Y. Siret, and E. Tournier, ISBN 0-12-204230-1, 1988, 
 Academic Press, London
 
 J.H. Davenport, Y. Siret, and E. Tournier, ISBN 0-12-204230-1, 1988, 
 Academic Press, London
 
+@item
+@cite{The Art of Computer Programming, Vol 2: Seminumerical Algorithms},
+D.E. Knuth, ISBN 0-201-89684-2, 1998, Addison Wesley
+
 @item
 @cite{The Role of gamma5 in Dimensional Regularization}, D. Kreimer, hep-ph/9401354
 
 @item
 @cite{The Role of gamma5 in Dimensional Regularization}, D. Kreimer, hep-ph/9401354