]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
Alexeis patches for documentation and correct degree of 1/symbol.
[ginac.git] / doc / tutorial / ginac.texi
index d0b12a76817146ae518f6ff5f325241bc4f0066d..26504623d3e0cb31c48e58db27849719ed9bb2fb 100644 (file)
@@ -23,7 +23,7 @@
 This is a tutorial that documents GiNaC @value{VERSION}, an open
 framework for symbolic computation within the C++ programming language.
 
-Copyright (C) 1999-2006 Johannes Gutenberg University Mainz, Germany
+Copyright (C) 1999-2007 Johannes Gutenberg University Mainz, Germany
 
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -51,7 +51,7 @@ notice identical to this one.
 
 @page
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1999-2006 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2007 Johannes Gutenberg University Mainz, Germany
 @sp 2
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -134,7 +134,7 @@ the near future.
 
 @section License
 The GiNaC framework for symbolic computation within the C++ programming
-language is Copyright @copyright{} 1999-2006 Johannes Gutenberg
+language is Copyright @copyright{} 1999-2007 Johannes Gutenberg
 University Mainz, Germany.
 
 This program is free software; you can redistribute it and/or
@@ -3299,13 +3299,11 @@ and contain symbolic entries. Such generators are created by the
 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
@@ -3313,20 +3311,7 @@ indices at all is admitted as @code{metr}. In the later case an @code{indexed}
 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
@@ -3334,9 +3319,6 @@ 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
@@ -3355,14 +3337,14 @@ ways. For example
 @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
@@ -3381,7 +3363,7 @@ 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, bool anticommuting = false);
+                       unsigned char rl = 0);
     ex lst_to_clifford(const ex & v, const ex & e);
 @end example
 
@@ -3403,19 +3385,19 @@ $v^0 e_0 + v^1 e_1 + ... + v^n e_n$
 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
@@ -3546,9 +3528,9 @@ The next provided function is
 @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
@@ -3556,10 +3538,9 @@ linear-fractional) transformation @samp{v -> (av+b)/(cv+d)} defined by
 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
@@ -6175,6 +6156,7 @@ you can output to a temporary @code{ostringstream} like this:
     // ...
 @end example
 
+@anchor{csrc printing}
 @cindex @code{csrc}
 @cindex @code{csrc_float}
 @cindex @code{csrc_double}
@@ -6372,6 +6354,127 @@ int main()
 @}
 @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)
@@ -7630,9 +7733,8 @@ The RTTI in GiNaC is based on two mechanisms:
 
 @item
 The @code{basic} class declares a member variable @code{tinfo_key} which
-holds an unsigned integer that identifies the object's class. These numbers
-are defined in the @file{tinfos.h} header file for the built-in GiNaC
-classes. They all start with @code{TINFO_}.
+holds a variable of @code{tinfo_t} type (which is actually just
+@code{const void*}) that identifies the object's class.
 
 @item
 By means of some clever tricks with static members, GiNaC maintains a list
@@ -7669,17 +7771,6 @@ using namespace std;
 using namespace GiNaC;
 @end example
 
-The first thing we have to do is to define a @code{tinfo_key} for our new
-class. This can be any arbitrary unsigned number that is not already taken
-by one of the existing classes but it's better to come up with something
-that is unlikely to clash with keys that might be added in the future. The
-numbers in @file{tinfos.h} are modeled somewhat after the class hierarchy
-which is not a requirement but we are going to stick with this scheme:
-
-@example
-const unsigned TINFO_mystring = 0x42420001U;
-@end example
-
 Now we can write down the class declaration. The class stores a C++
 @code{string} and the user shall be able to construct a @code{mystring}
 object from a C or C++ string:
@@ -7763,11 +7854,14 @@ which are the two constructors we declared.
 Let's proceed step-by-step. The default constructor looks like this:
 
 @example
-mystring::mystring() : inherited(TINFO_mystring) @{@}
+mystring::mystring() : inherited(&mystring::tinfo_static) @{@}
 @end example
 
 The golden rule is that in all constructors you have to set the
-@code{tinfo_key} member to the @code{TINFO_*} value of your class. Otherwise
+@code{tinfo_key} member to the @code{&your_class_name::tinfo_static}
+@footnote{each GiNaC class has static member called tinfo_static.
+This member is declared by the GINAC_DECLARE_REGISTERED_CLASS macros
+and defined by the GINAC_IMPLEMENT_REGISTERED_CLASS macros}. Otherwise
 it will be set by the constructor of the superclass and all hell will break
 loose in the RTTI. For your convenience, the @code{basic} class provides
 a constructor that takes a @code{tinfo_key} value, which we are using here
@@ -7857,8 +7951,8 @@ all relevant member variables.
 Now the only thing missing is our two new constructors:
 
 @example
-mystring::mystring(const string &s) : inherited(TINFO_mystring), str(s) @{@}
-mystring::mystring(const char *s) : inherited(TINFO_mystring), str(s) @{@}
+mystring::mystring(const string &s) : inherited(&mystring::tinfo_static), str(s) @{@}
+mystring::mystring(const char *s) : inherited(&mystring::tinfo_static), str(s) @{@}
 @end example
 
 No surprises here. We set the @code{str} member from the argument and
@@ -7997,7 +8091,7 @@ public:
 ex mystring::eval(int level) const
 @{
     string new_str;
-    for (int i=0; i<str.length(); i++) @{
+    for (size_t i=0; i<str.length(); i++) @{
         char c = str[i];
         if (c >= 'A' && c <= 'Z') 
             new_str += tolower(c);
@@ -8095,6 +8189,28 @@ should become a need.
 
 That's it. May the source be with you!
 
+@subsection Upgrading extension classes from older version of GiNaC
+
+If you got some extension classes for GiNaC 1.3.X some changes are
+necessary in order to make your code work with GiNaC 1.4.
+
+@itemize @bullet
+@item constructors which set @code{tinfo_key} such as
+
+@example
+myclass::myclass() : inherited(TINFO_myclass) @{@}
+@end example
+
+need to be rewritten as
+
+@example
+myclass::myclass() : inherited(&myclass::tinfo_static) @{@}
+@end example
+
+@item TINO_myclass is not necessary any more and can be removed.
+
+@end itemize
+
 
 @node A comparison with other CAS, Advantages, Adding classes, Top
 @c    node-name, next, previous, up