@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
@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
@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.
@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
@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)
@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
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
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
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
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
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
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;
@}
@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