X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=doc%2Ftutorial%2Fginac.texi;h=e6993f33dd2ddceb2dd48428bbcd6aa0a55bd1c7;hp=5934347c7ddb7e21fa1278d553cfc62ec3fbea2d;hb=d2d45a3f3e8a42bbd4c0ad96fd4b6d4b6b86af9c;hpb=ad5f751e9387ba148cc54c9961d50c37ee879fae diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 5934347c..e6993f33 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -519,15 +519,19 @@ want to have the documentation installed in some other directory than @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 @@ -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" -$ 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 @@ -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. +* Error handling:: How the library reports errors. * 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}. -@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 @@ -777,7 +782,64 @@ $\sqrt{2}$ @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{} 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 +#include +#include +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) @@ -1871,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 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 @@ -2072,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 -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 @@ -2265,8 +2349,14 @@ The unity element of a Clifford algebra is constructed by 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()} -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 @@ -2293,8 +2383,10 @@ Finally, the function 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 @@ -2309,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; - // -> (gamma~mu*gamma~symbol10*gamma.mu)*a.symbol10 + // -> gamma~mu*a\*gamma.mu 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; - // -> -2*gamma~symbol10*a.symbol10 - // [ == -2 * dirac_slash(a, D) ] + // -> -2*a\ ... @} @end example @@ -2429,9 +2520,15 @@ The unity element of a color algebra is constructed by 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()} -and the functions +The functions @example ex color_d(const ex & a, const ex & b, const ex & c); @@ -3148,8 +3245,8 @@ GiNaC offers the @code{map()} method to aid in the implementation of such 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 @@ -3189,6 +3286,42 @@ This function object could then be used like this: @} @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(e) || is_a(e)) + return e.map(*this); + else if (is_a(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 @@ -3845,7 +3978,7 @@ GiNaC contains the following predefined mathematical functions: @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)} @@ -3898,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 -@item @code{Derivative(x, l)} -@tab inert partial differentiation operator (used internally) @end multitable @end cartouche @@ -4117,19 +4248,19 @@ using namespace GiNaC; 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 @@ -4250,19 +4381,19 @@ static void my_print2(const archive_node & n) 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; - n.find_unsigned(name, x); + n.find_unsigned(name, x, j); cout << x; break; @} case archive_node::PTYPE_STRING: @{ string x; - n.find_string(name, x); + n.find_string(name, x, j); cout << '\"' << x << '\"'; break; @} @@ -4391,7 +4522,10 @@ function that does so, in this case the one in class @code{numeric}: @example static ex cos_evalf(const ex & x) @{ - return cos(ex_to(x)); + if (is_a(x)) + return cos(ex_to(x)); + else + return cos(x).hold(); @} @end example @@ -5556,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 +@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