@title GiNaC @value{VERSION}
@subtitle An open framework for symbolic computation within the C++ programming language
@subtitle @value{UPDATED}
-@author The GiNaC Group:
-@author Christian Bauer, Alexander Frink, Richard Kreckel, Jens Vollinga
+@author @uref{http://www.ginac.de}
@page
@vskip 0pt plus 1filll
for example (@pxref{Complex expressions}), do @emph{not} evaluate if applied
to such symbols. Likewise @code{log(exp(x))} does not evaluate to @code{x},
because of the unknown imaginary part of @code{x}.
-On the other hand, if you are sure that your symbols will hold only real values, you
-would like to have such functions evaluated. Therefore GiNaC allows you to specify
+On the other hand, if you are sure that your symbols will hold only real
+values, you would like to have such functions evaluated. Therefore GiNaC
+allows you to specify
the domain of the symbol. Instead of @code{symbol x("x");} you can write
@code{realsymbol x("x");} to tell GiNaC that @code{x} stands in for real values.
+@cindex @code{possymbol()}
+Furthermore, it is also possible to declare a symbol as positive. This will,
+for instance, enable the automatic simplification of @code{abs(x)} into
+@code{x}. This is done by declaying the symbol as @code{possymbol x("x");}.
+
@node Numbers, Constants, Symbols, Basic concepts
@c node-name, next, previous, up
The @code{scalar_products} object @code{sp} acts as a storage for the
scalar products added to it with the @code{.add()} method. This method
takes three arguments: the two expressions of which the scalar product is
-taken, and the expression to replace it with. After @code{sp.add(A, B, 0)},
-@code{simplify_indexed()} will replace all scalar products of indexed
-objects that have the symbols @code{A} and @code{B} as base expressions
-with the single value 0. The number, type and dimension of the indices
-don't matter; @samp{A~mu~nu*B.mu.nu} would also be replaced by 0.
+taken, and the expression to replace it with.
@cindex @code{expand()}
The example above also illustrates a feature of the @code{expand()} method:
function
@example
- ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0,
- bool anticommuting = false);
+ 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, an index @code{mu} with a numeric value may be of type
-@code{idx} as well.
+where @code{mu} should be a @code{idx} (or descendant) class object
+indexing the generators.
Parameter @code{metr} defines the metric @math{M(i, j)} and can be
represented by a square @code{matrix}, @code{tensormetric} or @code{indexed} class
object. In fact, any expression either with two free indices or without
object with two newly created indices with @code{metr} as its
@code{op(0)} will be used.
Optional parameter @code{rl} allows to distinguish different
-Clifford algebras, which will commute with each other. The last
-optional parameter @code{anticommuting} defines if the anticommuting
-assumption (i.e.
-@tex
-$e_i e_j + e_j e_i = 0$)
-@end tex
-@ifnottex
-e~i e~j + e~j e~i = 0)
-@end ifnottex
-will be used for contraction of Clifford units. If the @code{metric} is
-supplied by a @code{matrix} object, then the value of
-@code{anticommuting} is calculated automatically and the supplied one
-will be ignored. One can overcome this by giving @code{metric} through
-matrix wrapped into an @code{indexed} object.
+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)}, although
@cindex @code{clifford::get_metric()}
The method @code{clifford::get_metric()} returns a metric defining this
Clifford number.
-@cindex @code{clifford::is_anticommuting()}
-The method @code{clifford::is_anticommuting()} returns the
-@code{anticommuting} property of a unit.
If the matrix @math{M(i, j)} is in fact symmetric you may prefer to create
the Clifford algebra units with a call like that
@example
@{
...
- varidx nu(symbol("nu"), 4);
+ idx i(symbol("i"), 4);
realsymbol s("s");
ex M = diag_matrix(lst(1, -1, 0, s));
- ex e = clifford_unit(nu, M);
- ex e0 = e.subs(nu == 0);
- ex e1 = e.subs(nu == 1);
- ex e2 = e.subs(nu == 2);
- ex e3 = e.subs(nu == 3);
+ ex e = clifford_unit(i, M);
+ ex e0 = e.subs(i == 0);
+ ex e1 = e.subs(i == 1);
+ ex e2 = e.subs(i == 2);
+ ex e3 = e.subs(i == 3);
...
@}
@end example
@example
ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr,
- unsigned char rl = 0, bool anticommuting = false);
+ unsigned char rl = 0);
ex lst_to_clifford(const ex & v, const ex & e);
@end example
with @samp{e.k}
directly supplied in the second form of the procedure. In the first form
the Clifford unit @samp{e.k} is generated by the call of
-@code{clifford_unit(mu, metr, rl, anticommuting)}. The previous code may be rewritten
+@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"), 4);
+ idx i(symbol("i"), 4);
realsymbol s("s");
ex M = diag_matrix(lst(1, -1, 0, s));
- ex e0 = lst_to_clifford(lst(1, 0, 0, 0), nu, M);
- ex e1 = lst_to_clifford(lst(0, 1, 0, 0), nu, M);
- ex e2 = lst_to_clifford(lst(0, 0, 1, 0), nu, M);
- ex e3 = lst_to_clifford(lst(0, 0, 0, 1), nu, M);
+ ex e0 = lst_to_clifford(lst(1, 0, 0, 0), i, M);
+ ex e1 = lst_to_clifford(lst(0, 1, 0, 0), i, M);
+ ex e2 = lst_to_clifford(lst(0, 0, 1, 0), i, M);
+ ex e3 = lst_to_clifford(lst(0, 0, 0, 1), i, M);
...
@}
@end example
@example
ex clifford_moebius_map(const ex & a, const ex & b, const ex & c,
const ex & d, const ex & v, const ex & G,
- unsigned char rl = 0, bool anticommuting = false);
+ unsigned char rl = 0);
ex clifford_moebius_map(const ex & M, const ex & v, const ex & G,
- unsigned char rl = 0, bool anticommuting = false);
+ unsigned char rl = 0);
@end example
It takes a list or vector @code{v} and makes the Moebius (conformal or
the matrix @samp{M = [[a, b], [c, d]]}. The parameter @code{G} defines
the metric of the surrounding (pseudo-)Euclidean space. This can be an
indexed object, tensormetric, matrix or a Clifford unit, in the later
-case the optional parameters @code{rl} and @code{anticommuting} are
-ignored even if supplied. Depending from the type of @code{v} the
-returned value of this function is either a vector or a list holding vector's
-components.
+case the optional parameter @code{rl} is ignored even if supplied.
+Depending from the type of @code{v} the returned value of this function
+is either a vector or a list holding vector's components.
@cindex @code{clifford_max_label()}
Finally the function
// ...
@end example
+@anchor{csrc printing}
@cindex @code{csrc}
@cindex @code{csrc_float}
@cindex @code{csrc_double}
@}
@end example
+@subsection Compiling expressions to C function pointers
+@cindex compiling expressions
+
+Numerical evaluation of algebraic expressions is seamlessly integrated into
+GiNaC by help of the CLN library. While CLN allows for very fast arbitrary
+precision numerics, which is more than sufficient for most users, sometimes only
+the speed of built-in floating point numbers is fast enough, e.g. for Monte
+Carlo integration. The only viable option then is the following: print the
+expression in C syntax format, manually add necessary C code, compile that
+program and run is as a separate application. This is not only cumbersome and
+involves a lot of manual intervention, but it also separates the algebraic and
+the numerical evaluation into different execution stages.
+
+GiNaC offers a couple of functions that help to avoid these inconveniences and
+problems. The functions automatically perform the printing of a GiNaC expression
+and the subsequent compiling of its associated C code. The created object code
+is then dynamically linked to the currently running program. A function pointer
+to the C function that performs the numerical evaluation is returned and can be
+used instantly. This all happens automatically, no user intervention is needed.
+
+The following example demonstrates the use of @code{compile_ex}:
+
+@example
+ // ...
+ symbol x("x");
+ ex myexpr = sin(x) / x;
+
+ FUNCP_1P fp;
+ compile_ex(myexpr, x, fp);
+
+ cout << fp(3.2) << endl;
+ // ...
+@end example
+
+The function @code{compile_ex} is called with the expression to be compiled and
+its only free variable @code{x}. Upon successful completion the third parameter
+contains a valid function pointer to the corresponding C code module. If called
+like in the last line only built-in double precision numerics is involved.
+
+@cindex FUNCP_1P
+@cindex FUNCP_2P
+@cindex FUNCP_CUBA
+The function pointer has to be defined in advance. GiNaC offers three function
+pointer types at the moment:
+
+@example
+ typedef double (*FUNCP_1P) (double);
+ typedef double (*FUNCP_2P) (double, double);
+ typedef void (*FUNCP_CUBA) (const int*, const double[], const int*, double[]);
+@end example
+
+@cindex CUBA library
+@cindex Monte Carlo integration
+@code{FUNCP_2P} allows for two variables in the expression. @code{FUNCP_CUBA} is
+the correct type to be used with the CUBA library
+(@uref{http://www.feynarts/cuba}) for numerical integrations. The details for the
+parameters of @code{FUNCP_CUBA} are explained in the CUBA manual.
+
+@cindex compile_ex
+For every function pointer type there is a matching @code{compile_ex} available:
+
+@example
+ void compile_ex(const ex& expr, const symbol& sym, FUNCP_1P& fp,
+ const std::string filename = "");
+ void compile_ex(const ex& expr, const symbol& sym1, const symbol& sym2,
+ FUNCP_2P& fp, const std::string filename = "");
+ void compile_ex(const lst& exprs, const lst& syms, FUNCP_CUBA& fp,
+ const std::string filename = "");
+@end example
+
+When the last parameter @code{filename} is not supplied, @code{compile_ex} will
+choose a unique random name for the intermediate source and object files it
+produces. On program termination these files will be deleted. If one wishes to
+keep the C code and the object files, one can supply the @code{filename}
+parameter. The intermediate files will use that filename and will not be
+deleted.
+
+@cindex link_ex
+@code{link_ex} is a function that allows to dynamically link an existing object
+file and to make it available via a function pointer. This is useful if you
+have already used @code{compile_ex} on an expression and want to avoid the
+compilation step to be performed over and over again when you restart your
+program. The precondition for this is of course, that you have chosen a
+filename when you did call @code{compile_ex}. For every above mentioned
+function pointer type there exists a corresponding @code{link_ex} function:
+
+@example
+ void link_ex(const std::string filename, FUNCP_1P& fp);
+ void link_ex(const std::string filename, FUNCP_2P& fp);
+ void link_ex(const std::string filename, FUNCP_CUBA& fp);
+@end example
+
+The complete filename (including the suffix @code{.so}) of the object file has
+to be supplied.
+
+The function
+
+@cindex unlink_ex
+@example
+ void unlink_ex(const std::string filename);
+@end example
+
+is supplied for the rare cases when one wishes to close the dynamically linked
+object files directly and have the intermediate files (only if filename has not
+been given) deleted. Normally one doesn't need this function, because all the
+clean-up will be done automatically upon (regular) program termination.
+
+All the described functions will throw an exception in case they cannot perform
+correctly, like for example when writing the file or starting the compiler
+fails. Since internally the same printing methods as described in section
+@ref{csrc printing} are used, only functions and objects that are available in
+standard C will compile successfully (that excludes polylogarithms for example
+at the moment). Another precondition for success is, of course, that it must be
+possible to evaluate the expression numerically. No free variables despite the
+ones supplied to @code{compile_ex} should appear in the expression.
+
+@cindex ginac-excompiler
+@code{compile_ex} uses the shell script @code{ginac-excompiler} to start the C
+compiler and produce the object files. This shell script comes with GiNaC and
+will be installed together with GiNaC in the configured @code{$PREFIX/bin}
+directory.
@subsection Archiving
@cindex @code{archive} (class)