]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
Documentation for generalized clifford algebra.
[ginac.git] / doc / tutorial / ginac.texi
index b36b57fd2c3d6912190ac450db5896b2d894fc6e..16ca3162cfa39d804aec400e17379b66000096f2 100644 (file)
@@ -693,6 +693,7 @@ meta-class for storing all mathematical objects.
 * Lists::                        Lists of expressions.
 * Mathematical functions::       Mathematical functions.
 * Relations::                    Equality, Inequality and all that.
+* Integrals::                    Symbolic integrals.
 * Matrices::                     Matrices.
 * Indexed objects::              Handling indexed quantities.
 * Non-commutative objects::      Algebras with non-commutative products.
@@ -1807,7 +1808,7 @@ point number of class @code{numeric} you should call
 wrapped inside an @code{ex}.
 
 
-@node Relations, Matrices, Mathematical functions, Basic Concepts
+@node Relations, Integrals, Mathematical functions, Basic Concepts
 @c    node-name, next, previous, up
 @section Relations
 @cindex @code{relational} (class)
@@ -1833,8 +1834,68 @@ conversion from @code{relational} to @code{bool} takes place.  Note,
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
+@node Integrals, Matrices, Relations, Basic Concepts
+@c    node-name, next, previous, up
+@section Integrals
+@cindex @code{integral} (class)
+
+An object of class @dfn{integral} can be used to hold a symbolic integral.
+If you want to symbolically represent the integral of @code{x*x} from 0 to
+1, you would write this as
+@example
+integral(x, 0, 1, x*x)
+@end example
+The first argument is the integration variable. It should be noted that
+GiNaC is not very good (yet?) at symbolically evaluating integrals. In
+fact, it can only integrate polynomials. An expression containing integrals
+can be evaluated symbolically by calling the
+@example
+.eval_integ()
+@end example
+method on it. Numerical evaluation is available by calling the
+@example
+.evalf()
+@end example
+method on an expression containing the integral. This will only evaluate
+integrals into a number if @code{subs}ing the integration variable by a
+number in the fourth argument of an integral and then @code{evalf}ing the
+result always results in a number. Of course, also the boundaries of the
+integration domain must @code{evalf} into numbers. It should be noted that
+trying to @code{evalf} a function with discontinuities in the integration
+domain is not recommended. The accuracy of the numeric evaluation of
+integrals is determined by the static member variable
+@example
+ex integral::relative_integration_error
+@end example
+of the class @code{integral}. The default value of this is 10^-8.
+The integration works by halving the interval of integration, until numeric
+stability of the answer indicates that the requested accuracy has been
+reached. The maximum depth of the halving can be set via the static member
+variable
+@example
+int integral::max_integration_level
+@end example
+The default value is 15. If this depth is exceeded, @code{evalf} will simply
+return the integral unevaluated. The function that performs the numerical
+evaluation, is also available as
+@example
+ex adaptivesimpson(const ex & x, const ex & a, const ex & b, const ex & f,
+const ex & error)
+@end example
+This function will throw an exception if the maximum depth is exceeded. The
+last parameter of the function is optional and defaults to the
+@code{relative_integration_error}. To make sure that we do not do too
+much work if an expression contains the same integral multiple times,
+a lookup table is used.
 
-@node Matrices, Indexed objects, Relations, Basic Concepts
+If you know that an expression holds an integral, you can get the
+integration variable, the left boundary, right boundary and integrant by
+respectively calling @code{.op(0)}, @code{.op(1)}, @code{.op(2)}, and
+@code{.op(3)}. Differentiating integrals with respect to variables works
+as expected. Note that it makes no sense to differentiate an integral
+with respect to the integration variable.
+
+@node Matrices, Indexed objects, Integrals, Basic Concepts
 @c    node-name, next, previous, up
 @section Matrices
 @cindex @code{matrix} (class)
@@ -2922,11 +2983,18 @@ non-commutative expressions).
 @cindex @code{clifford} (class)
 @subsection Clifford algebra
 
+
+Clifford algebras are supported in two flavours: Dirac gamma
+matrices (more physical) and generic Clifford algebras (more
+mathematical). 
+
 @cindex @code{dirac_gamma()}
-Clifford algebra elements (also called Dirac gamma matrices, although GiNaC
-doesn't treat them as matrices) are designated as @samp{gamma~mu} and satisfy
-@samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where @samp{eta~mu~nu}
-is the Minkowski metric tensor. Dirac gammas are constructed by the function
+@subsubsection Dirac gamma matrices
+Dirac gamma matrices (note that GiNaC doesn't treat them
+as matrices) are designated as @samp{gamma~mu} and satisfy
+@samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where
+@samp{eta~mu~nu} is the Minkowski metric tensor. Dirac gammas are
+constructed by the function
 
 @example
 ex dirac_gamma(const ex & mu, unsigned char rl = 0);
@@ -3099,6 +3167,182 @@ You can use this to compare two expressions or for further simplifications:
 @}
 @end example
 
+@cindex @code{clifford_unit()}
+@subsubsection A generic Clifford algebra
+
+A generic Clifford algebra, i.e. a
+@tex
+$2^n$
+@end tex
+dimensional algebra with
+generators @samp{e~k} satisfying the identities 
+@samp{e~i e~j + e~j e~i = B(i, j)} for some symmetric matrix (@code{metric})
+@math{B(i, j)}. Such generators are created by the function
+
+@example
+    ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
+@end example
+
+where @code{mu} should be a @code{varidx} class object indexing the
+generators, @code{metr} defines the metric @math{B(i, j)} and can be
+represented by a square @code{matrix}, @code{tensormetric} or @code{indexed} class
+object, optional parameter @code{rl} allows to distinguish different
+Clifford algebras (which will commute with each other). Note that the call
+@code{clifford_unit(mu, minkmetric())} creates something very close to
+@code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns a
+metric defining this Clifford number.
+
+Individual generators of a Clifford algebra can be accessed in several
+ways. For example 
+
+@example
+@{
+    ... 
+    varidx nu(symbol("nu"), 3);
+    matrix M(3, 3) = 1, 0, 0,
+                     0,-1, 0,
+                     0, 0, 0;
+    ex e = clifford_unit(nu, M);
+    ex e0 = e.subs(nu == 0);
+    ex e1 = e.subs(nu == 1);
+    ex e2 = e.subs(nu == 2);
+    ...
+@}
+@end example
+
+will produce three generators of a Clifford algebra with properties
+@code{pow(e0, 2) = 1},  @code{pow(e1, 2) = -1} and   @code{pow(e2, 2) = 0}. 
+
+@cindex @code{lst_to_clifford()}
+A similar effect can be achieved from the function
+
+@example
+    ex lst_to_clifford(const ex & v, const ex & mu,  const ex & metr,
+                       unsigned char rl = 0);
+@end example
+
+which converts a list or vector @samp{v = (v~0, v~1, ..., v~n)} into
+the Clifford number @samp{v~0 e.0 + v~1 e.1 + ... + v~n e.n} with @samp{e.k}
+being created by @code{clifford_unit(mu, metr, rl)}. The previous code
+may be rewritten with the help of @code{lst_to_clifford()} as follows
+
+@example
+@{
+    ...
+    varidx nu(symbol("nu"), 3);
+    matrix M(3, 3) = 1, 0, 0,
+                     0,-1, 0,
+                     0, 0, 0;
+    ex e0 = lst_to_clifford(lst(1, 0, 0), nu, M);
+    ex e1 = lst_to_clifford(lst(0, 1, 0), nu, M);
+    ex e2 = lst_to_clifford(lst(0, 0, 1), nu, M);
+  ...
+@}
+@end example
+
+@cindex @code{clifford_to_lst()}
+There is the inverse function 
+
+@example
+    lst clifford_to_lst(const ex & e, const ex & c, bool algebraic = true);
+@end example
+
+which takes an expression @code{e} and tries to find a list
+@samp{v = (v~0, v~1, ..., v~n)} such that @samp{e = v~0 c.0 + v~1 c.1 + ...
++ v~n c.n} with respect to the given Clifford units @code{c} and none of
+@samp{v~k} contains the Clifford units @code{c} (of course, this
+may be impossible). This function can use an @code{algebraic} method
+(default) or a symbolic one. With the @code{algebraic} method @samp{v~k} are calculated as
+@samp{(e c.k + c.k e)/pow(c.k, 2)}.  If @samp{pow(c.k, 2) = 0} for some @samp{k}
+then the method will be automatically changed to symbolic. The same effect
+is obtained by the assignment (@code{algebraic = false}) in the procedure call.
+
+@cindex @code{clifford_prime()}
+@cindex @code{clifford_star()}
+@cindex @code{clifford_bar()}
+There are several functions for (anti-)automorphisms of Clifford algebras:
+
+@example
+    ex clifford_prime(const ex & e)
+    inline ex clifford_star(const ex & e) @{ return e.conjugate(); @}
+    inline ex clifford_bar(const ex & e) @{ return clifford_prime(e.conjugate()); @}
+@end example
+
+The automorphism of a Clifford algebra @code{clifford_prime()} simply
+changes signs of all Clifford units in the expression. The reversion
+of a Clifford algebra @code{clifford_star()} coincides with the
+@code{conjugate()} method and effectively reverses the order of Clifford
+units in any product. Finally the main anti-automorphism
+of a Clifford algebra @code{clifford_bar()} is the composition of the
+previous two, i.e. it makes the reversion and changes signs of all Clifford units
+in a product. These functions correspond to the notations
+@math{e'},
+@tex
+$e^*$
+@end tex
+and
+@tex
+$\overline{e}$
+@end tex
+used in Clifford algebra textbooks.
+
+@cindex @code{clifford_norm()}
+The function
+
+@example
+    ex clifford_norm(const ex & e);
+@end example
+
+@cindex @code{clifford_inverse()}
+calculates the norm of a Clifford number from the expression
+@tex
+$||e||^2 = e\overline{e}$
+@end tex
+. The inverse of a Clifford expression is returned
+by the function
+
+@example
+    ex clifford_inverse(const ex & e);
+@end example
+
+which calculates it as 
+@tex
+$e^{-1} = e/||e||^2$
+@end tex
+. If
+@tex
+$||e|| = 0$
+@end tex
+then an exception is raised.
+
+@cindex @code{remove_dirac_ONE()}
+If a Clifford number happens to be a factor of
+@code{dirac_ONE()} then we can convert it to a ``real'' (non-Clifford)
+expression by the function
+
+@example
+    ex remove_dirac_ONE(const ex & e);
+@end example
+
+@cindex @code{canonicalize_clifford()}
+The function @code{canonicalize_clifford()} works for a
+generic Clifford algebra in a similar way as for Dirac gammas.
+
+The last provided function is
+
+@cindex @code{clifford_moebius_map()}
+@example
+    ex clifford_moebius_map(const ex & a, const ex & b, const ex & c,
+                            const ex & d, const ex & v, const ex & G);
+@end example 
+
+It takes a list or vector @code{v} and makes the Moebius
+(conformal or linear-fractional) transformation @samp{v ->
+(av+b)/(cv+d)} defined by the matrix @samp{[[a, b], [c, d]]}. The last
+parameter @code{G} defines the metric of the surrounding
+(pseudo-)Euclidean space. The returned value of this function is a list
+of components of the resulting vector.
+
 
 @cindex @code{color} (class)
 @subsection Color algebra
@@ -4725,6 +4969,7 @@ in which case the value of @code{q} is undefined.
 @cindex @code{unit()}
 @cindex @code{content()}
 @cindex @code{primpart()}
+@cindex @code{unitcontprim()}
 
 The methods
 
@@ -4732,14 +4977,26 @@ The methods
 ex ex::unit(const ex & x);
 ex ex::content(const ex & x);
 ex ex::primpart(const ex & x);
+ex ex::primpart(const ex & x, const ex & c);
 @end example
 
 return the unit part, content part, and primitive polynomial of a multivariate
 polynomial with respect to the variable @samp{x} (the unit part being the sign
 of the leading coefficient, the content part being the GCD of the coefficients,
 and the primitive polynomial being the input polynomial divided by the unit and
-content parts). The product of unit, content, and primitive part is the
-original polynomial.
+content parts). The second variant of @code{primpart()} expects the previously
+calculated content part of the polynomial in @code{c}, which enables it to
+work faster in the case where the content part has already been computed. The
+product of unit, content, and primitive part is the original polynomial.
+
+Additionally, the method
+
+@example
+void ex::unitcontprim(const ex & x, ex & u, ex & c, ex & p);
+@end example
+
+computes the unit, content, and primitive parts in one go, returning them
+in @code{u}, @code{c}, and @code{p}, respectively.
 
 
 @subsection GCD, LCM and resultant