]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
- gamma() -> Gamma().
[ginac.git] / doc / tutorial / ginac.texi
index f69d45107968ec0d2943d05179d43817aeb61efc..89a7b29da32d4df2d78f6bf9654f5c15efc38a02 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 Johannes Gutenberg University Mainz, Germany
+Copyright (C) 1999-2000 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
@@ -52,7 +52,7 @@ notice identical to this one.
 
 @page
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1999 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2000 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
@@ -135,8 +135,8 @@ the near future.
 
 @section License
 The GiNaC framework for symbolic computation within the C++ programming
-language is Copyright @copyright{} 1999 Johannes Gutenberg University Mainz,
-Germany.
+language is Copyright @copyright{} 1999-2000 Johannes Gutenberg
+University Mainz, Germany.
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
@@ -215,11 +215,11 @@ generates Hermite polynomials in a specified free variable.
 #include <ginac/ginac.h>
 using namespace GiNaC;
 
-ex HermitePoly(symbol x, int deg)
+ex HermitePoly(const symbol & x, int n)
 @{
-    ex HKer=exp(-pow(x,2));
-    // uses the identity H_n(x) == (-1)^n exp(x^2) (d/dx)^n exp(-x^2) 
-    return normal(pow(-1,deg) * diff(HKer, x, deg) / HKer);
+    ex HKer=exp(-pow(x, 2));
+    // uses the identity H_n(x) == (-1)^n exp(x^2) (d/dx)^n exp(-x^2)
+    return normal(pow(-1, n) * diff(HKer, x, n) / HKer);
 @}
 
 int main()
@@ -280,8 +280,23 @@ integers:
 1/3
 @end example
 
-All numbers occuring in GiNaC's expressions can be converted into floating
-point numbers with the @code{evalf} method, to arbitrary accuracy:
+Exact numbers are always retained as exact numbers and only evaluated as
+floating point numbers if requested.  For instance, with numeric
+radicals is dealt pretty much as with symbols.  Products of sums of them
+can be expanded:
+
+@example
+> expand((1+a^(1/5)-a^(2/5))^3);
+1+3*a+3*a^(1/5)-5*a^(3/5)-a^(6/5)
+> expand((1+3^(1/5)-3^(2/5))^3);
+10-5*3^(3/5)
+> evalf((1+3^(1/5)-3^(2/5))^3);
+0.33408977534118624228
+@end example
+
+The function @code{evalf} that was used above converts any number in
+GiNaC's expressions into floating point numbers.  This can be done to
+arbitrary predefined accuracy:
 
 @example
 > evalf(1/7);
@@ -302,11 +317,11 @@ numeric expressions (as an inexact number):
 > a=Pi^2+x;
 x+Pi^2
 > evalf(a);
-x+9.869604401089358619L0
+9.869604401089358619+x
 > x=2;
 2
 > evalf(a);
-11.869604401089358619L0
+11.869604401089358619
 @end example
 
 Built-in functions evaluate immediately to exact numbers if
@@ -333,7 +348,7 @@ a matrix class for this purpose but we can see what it can do using
 @example
 > lsolve(a+x*y==z,x);
 y^(-1)*(z-a);
-lsolve([3*x+5*y == 7, -2*x+10*y == -5], [x, y]);
+lsolve([3*x+5*y == 7, -2*x+10*y == -5], [x, y]);
 [x==19/8,y==-1/40]
 > M = [[ [[1, 3]], [[-3, 2]] ]];
 [[ [[1,3]], [[-3,2]] ]]
@@ -372,15 +387,15 @@ tan(x)^2+1
 x-1/6*x^3+Order(x^4)
 > series(1/tan(x),x,0,4);
 x^(-1)-1/3*x+Order(x^2)
-> series(gamma(x),x,0,3);
-x^(-1)-EulerGamma+(1/12*Pi^2+1/2*EulerGamma^2)*x
-+(-1/3*zeta(3)-1/12*Pi^2*EulerGamma-1/6*EulerGamma^3)*x^2+Order(x^3)
+> series(Gamma(x),x,0,3);
+x^(-1)-gamma+(1/12*Pi^2+1/2*gamma^2)*x+
+(-1/3*zeta(3)-1/12*Pi^2*gamma-1/6*gamma^3)*x^2+Order(x^3)
 > evalf(");
-x^(-1.0)-0.5772156649015328606+(0.98905599532797255544)*x
--(0.90747907608088628905)*x^2+Order(x^(3.0))
-> series(gamma(2*sin(x)-2),x,Pi/2,6);
--(x-1/2*Pi)^(-2)+(-1/12*Pi^2-1/2*EulerGamma^2-1/240)*(x-1/2*Pi)^2
--EulerGamma-1/12+Order((x-1/2*Pi)^3)
+x^(-1)-0.5772156649015328606+(0.9890559953279725555)*x
+-(0.90747907608088628905)*x^2+Order(x^3)
+> series(Gamma(2*sin(x)-2),x,Pi/2,6);
+-(x-1/2*Pi)^(-2)+(-1/12*Pi^2-1/2*gamma^2-1/240)*(x-1/2*Pi)^2
+-gamma-1/12+Order((x-1/2*Pi)^3)
 @end example
 
 Here we have made use of the @command{ginsh}-command @code{"} to pop the
@@ -389,7 +404,7 @@ previously evaluated element from @command{ginsh}'s internal stack.
 If you ever wanted to convert units in C or C++ and found this is
 cumbersome, here is the solution.  Symbolic types can always be used as
 tags for different types of objects.  Converting from wrong units to the
-metric system is therefore easy:
+metric system is now easy:
 
 @example
 > in=.0254*m;
@@ -422,19 +437,21 @@ installation.
 @c    node-name, next, previous, up
 @section Prerequisites
 
-In order to install GiNaC on your system, some prerequisites need
-to be met.  First of all, you need to have a C++-compiler adhering to
-the ANSI-standard @cite{ISO/IEC 14882:1998(E)}.  We used @acronym{GCC} for
+In order to install GiNaC on your system, some prerequisites need to be
+met.  First of all, you need to have a C++-compiler adhering to the
+ANSI-standard @cite{ISO/IEC 14882:1998(E)}.  We used @acronym{GCC} for
 development so if you have a different compiler you are on your own.
 For the configuration to succeed you need a Posix compliant shell
 installed in @file{/bin/sh}, GNU @command{bash} is fine.  Perl is needed
-by the built process as well, since some of the source files are automatically
-generated by Perl scripts.  Last but not least, Bruno Haible's library
-@acronym{CLN} is extensively used and needs to be installed on your system.
-Please get it from @uref{ftp://ftp.santafe.edu/pub/gnu/} or from
-@uref{ftp://ftp.ilog.fr/pub/Users/haible/gnu/, Bruno Haible's FTP site}
-(it is covered by GPL) and install it prior to trying to install GiNaC.
-The configure script checks if it can find it and if it cannot
+by the built process as well, since some of the source files are
+automatically generated by Perl scripts.  Last but not least, Bruno
+Haible's library @acronym{CLN} is extensively used and needs to be
+installed on your system.  Please get it either from
+@uref{ftp://ftp.santafe.edu/pub/gnu/}, from
+@uref{ftp://ftpthep.physik.uni-mainz.de/pub/gnu/, GiNaC's FTP site} or
+from @uref{ftp://ftp.ilog.fr/pub/Users/haible/gnu/, Bruno Haible's FTP
+site} (it is covered by GPL) and install it prior to trying to install
+GiNaC.  The configure script checks if it can find it and if it cannot
 it will refuse to continue.
 
 
@@ -543,21 +560,24 @@ takes to compile GiNaC depends not only on the speed of your machines
 but also on other parameters, for instance what value for @env{CXXFLAGS}
 you entered.  Optimization may be very time-consuming.
 
-Just to make sure GiNaC works properly you may run a simple test
-suite by typing
+Just to make sure GiNaC works properly you may run a collection of
+regression tests by typing
 
 @example
 $ make check
 @end example
 
-This will compile some sample programs, run them and compare the output
-to reference output. Each of the checks should return a message @samp{passed}
-together with the CPU time used for that particular test.  If it does
-not, something went wrong.  This is mostly intended to be a QA-check
-if something was broken during the development, not a sanity check
-of your system.  Another intent is to allow people to fiddle around
-with optimization.  If @acronym{CLN} was installed all right
-this step is unlikely to return any errors.
+This will compile some sample programs, run them and check the output
+for correctness.  The regression tests fall in three categories.  First,
+the so called @emph{exams} are performed, simple tests where some
+predefined input is evaluated (like a pupils' exam).  Second, the
+@emph{checks} test the coherence of results among each other with
+possible random input.  Third, some @emph{timings} are performed, which
+benchmark some predefined problems with different sizes and display the
+CPU time used in seconds.  Each individual test should return a message
+@samp{passed}.  This is mostly intended to be a QA-check if something
+was broken during development, not a sanity check of your system.
+Another intent is to allow people to fiddle around with optimization.
 
 Generally, the top-level Makefile runs recursively to the
 subdirectories.  It is therfore safe to go into any subdirectory
@@ -636,6 +656,7 @@ meta-class for storing all mathematical objects.
 * Fundamental containers::       The power, add and mul classes.
 * Built-in functions::           Mathematical functions.
 * Relations::                    Equality, Inequality and all that.
+* Archiving::                    Storing expression libraries in files.
 @end menu
 
 
@@ -709,11 +730,47 @@ consisting of one expression and a number (@code{numeric}).  What
 @xref{Internal Structures}, where these two classes are described in
 more detail.
 
+At this point, we only summarize what kind of mathematical objects are
+stored in the different classes in above diagram in order to give you a
+overview:
+
+@cartouche
+@multitable @columnfractions .22 .78
+@item @code{symbol} @tab Algebraic symbols @math{a}, @math{x}, @math{y}@dots{}
+@item @code{constant} @tab Constants like 
+@tex
+$\pi$
+@end tex
+@ifnottex
+@math{Pi}
+@end ifnottex
+@item @code{numeric} @tab All kinds of numbers, @math{42}, @math{7/3*I}, @math{3.14159}@dots{}
+@item @code{add} @tab Sums like @math{x+y} or @math{a+(2*b)+3}
+@item @code{mul} @tab Products like @math{x*y} or @math{a*(x+y+z)*b*2}
+@item @code{power} @tab Exponentials such as @math{x^2}, @math{a^b}, 
+@tex
+$\sqrt{2}$
+@end tex
+@ifnottex
+@code{sqrt(}@math{2}@code{)}
+@end ifnottex
+@dots{}
+@item @code{pseries} @tab Power Series, e.g. @math{x+1/6*x^3+1/120*x^5+O(x^7)}
+@item @code{function} @tab A symbolic function like @math{sin(2*x)}
+@item @code{lst} @tab Lists of expressions [@math{x}, @math{2*y}, @math{3+z}]
+@item @code{matrix} @tab @math{n}x@math{m} matrices of expressions
+@item @code{relational} @tab A relation like the identity @math{x}@code{==}@math{y}
+@item @code{color} @tab Element of the @math{SU(3)} Lie-algebra
+@item @code{isospin} @tab Element of the @math{SU(2)} Lie-algebra
+@item @code{idx} @tab Index of a tensor object
+@item @code{coloridx} @tab Index of a @math{SU(3)} tensor
+@end multitable
+@end cartouche
 
 @node Symbols, Numbers, The Class Hierarchy, Basic Concepts
 @c    node-name, next, previous, up
 @section Symbols
-@cindex Symbols (class @code{symbol})
+@cindex @code{symbol} (class)
 @cindex hierarchy of classes
 
 @cindex atom
@@ -752,7 +809,7 @@ can use the expression's @code{.subs()} method.
 @node Numbers, Constants, Symbols, Basic Concepts
 @c    node-name, next, previous, up
 @section Numbers
-@cindex numbers (class @code{numeric})
+@cindex @code{numeric} (class)
 
 @cindex GMP
 @cindex CLN
@@ -789,11 +846,13 @@ using namespace GiNaC;
 
 int main()
 @{
-    numeric two(2);                     // exact integer 2
-    numeric r(2,3);                     // exact fraction 2/3
-    numeric e(2.71828);                 // floating point number
-    numeric p("3.1415926535897932385"); // floating point number
-
+    numeric two(2);                       // exact integer 2
+    numeric r(2,3);                       // exact fraction 2/3
+    numeric e(2.71828);                   // floating point number
+    numeric p("3.1415926535897932385");   // floating point number
+    // Trott's constant in scientific notation:
+    numeric trott("1.0841015122311136151E-2");
+    
     cout << two*p << endl;  // floating point 6.283...
     // ...
 @}
@@ -950,11 +1009,11 @@ following table.
 @node Constants, Fundamental containers, Numbers, Basic Concepts
 @c    node-name, next, previous, up
 @section Constants
-@cindex constants (class @code{constant})
+@cindex @code{constant} (class)
 
 @cindex @code{Pi}
 @cindex @code{Catalan}
-@cindex @code{EulerGamma}
+@cindex @code{gamma}
 @cindex @code{evalf()}
 Constants behave pretty much like symbols except that they return some
 specific number when the method @code{.evalf()} is called.
@@ -970,7 +1029,7 @@ The predefined known constants are:
 @item @code{Catalan}
 @tab Catalan's constant
 @tab 0.91596559417721901505460351493238411
-@item @code{EulerGamma}
+@item @code{gamma}
 @tab Euler's (or Euler-Mascheroni) constant
 @tab 0.57721566490153286060651209008240243
 @end multitable
@@ -1065,7 +1124,7 @@ canonical form.
 @node Built-in functions, Relations, Fundamental containers, Basic Concepts
 @c    node-name, next, previous, up
 @section Built-in functions
-@cindex functions (class @code{function})
+@cindex @code{function} (class)
 @cindex trigonometric function
 @cindex hyperbolic function
 
@@ -1087,11 +1146,11 @@ int main()
     symbol x("x"), y("y");
     
     ex foo = x+y/2;
-    cout << "gamma(" << foo << ") -> " << gamma(foo) << endl;
+    cout << "Gamma(" << foo << ") -> " << Gamma(foo) << endl;
     ex bar = foo.subs(y==1);
-    cout << "gamma(" << bar << ") -> " << gamma(bar) << endl;
+    cout << "Gamma(" << bar << ") -> " << Gamma(bar) << endl;
     ex foobar = bar.subs(x==7);
-    cout << "gamma(" << foobar << ") -> " << gamma(foobar) << endl;
+    cout << "Gamma(" << foobar << ") -> " << Gamma(foobar) << endl;
     // ...
 @}
 @end example
@@ -1100,9 +1159,9 @@ This program shows how the function returns itself twice and finally an
 expression that may be really useful:
 
 @example
-gamma(x+(1/2)*y) -> gamma(x+(1/2)*y)
-gamma(x+1/2) -> gamma(x+1/2)
-gamma(15/2) -> (135135/128)*Pi^(1/2)
+Gamma(x+(1/2)*y) -> Gamma(x+(1/2)*y)
+Gamma(x+1/2) -> Gamma(x+1/2)
+Gamma(15/2) -> (135135/128)*Pi^(1/2)
 @end example
 
 @cindex branch cut
@@ -1117,10 +1176,10 @@ expansion and so on.  Read the next chapter in order to learn more about
 this.
 
 
-@node Relations, Important Algorithms, Built-in functions, Basic Concepts
+@node Relations, Archiving, Built-in functions, Basic Concepts
 @c    node-name, next, previous, up
 @section Relations
-@cindex relations (class @code{relational})
+@cindex @code{relational} (class)
 
 Sometimes, a relation holding between two expressions must be stored
 somehow.  The class @code{relational} is a convenient container for such
@@ -1132,9 +1191,102 @@ They are created by simply using the C++ operators @code{==}, @code{!=},
 @xref{Built-in functions}, for examples where various applications of
 the @code{.subs()} method show how objects of class relational are used
 as arguments.  There they provide an intuitive syntax for substitutions.
+They can also used for creating systems of equations that are to be
+solved for unknown variables.
 
 
-@node Important Algorithms, Polynomial Expansion, Relations, Top
+@node Archiving, Important Algorithms, Relations, Basic Concepts
+@c    node-name, next, previous, up
+@section Archiving Expressions
+@cindex I/O
+@cindex @code{archive} (class)
+
+GiNaC allows creating @dfn{archives} of expressions which can be stored
+to or retrieved from files. To create an archive, you declare an object
+of class @code{archive} and archive expressions in it, giving each
+expressions a unique name:
+
+@example
+#include <ginac/ginac.h>
+#include <fstream>
+using namespace GiNaC;
+
+int main()
+@{
+    symbol x("x"), y("y"), z("z");
+
+    ex foo = sin(x + 2*y) + 3*z + 41;
+    ex bar = foo + 1;
+
+    archive a;
+    a.archive_ex(foo, "foo");
+    a.archive_ex(bar, "the second one");
+    // ...
+@end example
+
+The archive can then be written to a file:
+
+@example
+    // ...
+    ofstream out("foobar.gar");
+    out << a;
+    out.close();
+    // ...
+@end example
+
+The file @file{foobar.gar} contains all information that is needed to
+reconstruct the expressions @code{foo} and @code{bar}.
+
+@cindex @command{viewgar}
+The tool @command{viewgar} that comes with GiNaC can be used to view
+the contents of GiNaC archive files:
+
+@example
+$ viewgar foobar.gar
+foo = 41+sin(x+2*y)+3*z
+the second one = 42+sin(x+2*y)+3*z
+@end example
+
+The point of writing archive files is of course that they can later be
+read in again:
+
+@example
+    // ...
+    archive a2;
+    ifstream in("foobar.gar");
+    in >> a2;
+    // ...
+@end example
+
+And the stored expressions can be retrieved by their name:
+
+@example
+    // ...
+    lst syms;
+    syms.append(x); syms.append(y);
+
+    ex ex1 = a2.unarchive_ex(syms, "foo");
+    ex ex2 = a2.unarchive_ex(syms, "the second one");
+
+    cout << ex1 << endl;              // prints "41+sin(x+2*y)+3*z"
+    cout << ex2 << endl;              // prints "42+sin(x+2*y)+3*z"
+    cout << ex1.subs(x == 2) << endl; // prints "41+sin(2+2*y)+3*z"
+    // ...
+@}
+@end example
+
+Note that you have to supply a list of the symbols which are to be inserted
+in the expressions. Symbols in archives are stored by their name only and
+if you don't specify which symbols you have, unarchiving the expression will
+create new symbols with that name. E.g. if you hadn't included @code{x} in
+the @code{syms} list above, the @code{ex1.subs(x == 2)} statement would
+have had no effect because the @code{x} in @code{ex1} would have been a
+different symbol than the @code{x} which was defined at the beginning of
+the program, altough both would appear as @samp{x} when printed.
+
+
+
+@node Important Algorithms, Polynomial Expansion, Archiving, Top
 @c    node-name, next, previous, up
 @chapter Important Algorithms
 @cindex polynomial
@@ -1172,7 +1324,7 @@ would require @code{A=x+1; subs(A,x==2);} (after proper declaration of
 @code{A:=x^2+3; coeff(A,x,0);} (GiNaC: @code{A=pow(x,2)+3;
 coeff(A,x,0);}) it is clear that MapleV is not trying to be consistent
 here.  Also, users of MuPAD will in most cases feel more comfortable
-with GiNaC's convention.  All function wrappers are always implemented
+with GiNaC's convention.  All function wrappers are implemented
 as simple inline functions which just call the corresponding method and
 are only provided for users uncomfortable with OO who are dead set to
 avoid method invocations.  Generally, nested function wrappers are much
@@ -1226,7 +1378,7 @@ being polynomials in the remaining variables.  The method
 @code{collect()} accomplishes this task.  Here is its declaration:
 
 @example
-ex ex::collect(symbol const & s);
+ex ex::collect(const symbol & s);
 @end example
 
 Note that the original polynomial needs to be in expanded form in order
@@ -1236,8 +1388,8 @@ coefficients can be checked using the two methods
 @cindex @code{degree()}
 @cindex @code{ldegree()}
 @example
-int ex::degree(symbol const & s);
-int ex::ldegree(symbol const & s);
+int ex::degree(const symbol & s);
+int ex::ldegree(const symbol & s);
 @end example
 
 where @code{degree()} returns the highest coefficient and
@@ -1408,7 +1560,7 @@ using namespace GiNaC;
 ex EulerNumber(unsigned n)
 @{
     symbol x;
-    ex generator = pow(cosh(x),-1);
+    const ex generator = pow(cosh(x),-1);
     return generator.diff(x,n).subs(x==0);
 @}
 
@@ -1428,19 +1580,20 @@ When you run it, it produces the sequence @code{1}, @code{-1}, @code{5},
 @node Series Expansion, Extending GiNaC, Symbolic Differentiation, Important Algorithms
 @c    node-name, next, previous, up
 @section Series Expansion
-@cindex series expansion
+@cindex @code{series()}
 @cindex Taylor expansion
 @cindex Laurent expansion
+@cindex @code{pseries} (class)
 
 Expressions know how to expand themselves as a Taylor series or (more
 generally) a Laurent series.  As in most conventional Computer Algebra
 Systems, no distinction is made between those two.  There is a class of
-its own for storing such series as well as a class for storing the order
-of the series.  As a consequence, if you want to work with series,
-i.e. multiply two series, you need to call the method @code{ex::series}
-again to convert it to a series object with the usual structure
-(expansion plus order term).  A sample application from special
-relativity could read:
+its own for storing such series (@code{class pseries}) and a built-in
+function (called @code{Order}) for storing the order term of the series.
+As a consequence, if you want to work with series, i.e. multiply two
+series, you need to call the method @code{ex::series} again to convert
+it to a series object with the usual structure (expansion plus order
+term).  A sample application from special relativity could read:
 
 @example
 #include <ginac/ginac.h>
@@ -1587,7 +1740,7 @@ function that is called when one wishes to @code{eval} it.  It could
 look something like this:
 
 @example
-static ex cos_eval_method(ex const & x)
+static ex cos_eval_method(const ex & x)
 @{
     // if (!x%(2*Pi)) return 1
     // if (!x%Pi) return -1
@@ -1600,25 +1753,28 @@ static ex cos_eval_method(ex const & x)
 @cindex @code{hold()}
 @cindex evaluation
 The last line returns @code{cos(x)} if we don't know what else to do and
-stops a potential recursive evaluation by saying @code{.hold()}.  We
+stops a potential recursive evaluation by saying @code{.hold()}, which
+sets a flag to the expression signaling that it has been evaluated.  We
 should also implement a method for numerical evaluation and since we are
 lazy we sweep the problem under the rug by calling someone else's
 function that does so, in this case the one in class @code{numeric}:
 
 @example
-static ex cos_evalf_method(ex const & x)
+static ex cos_evalf(const ex & x)
 @{
-    return sin(ex_to_numeric(x));
+    return cos(ex_to_numeric(x));
 @}
 @end example
 
-Differentiation will surely turn up and so we need to tell
-@code{sin} how to differentiate itself:
+Differentiation will surely turn up and so we need to tell @code{cos}
+what the first derivative is (higher derivatives (@code{.diff(x,3)} for
+instance are then handled automatically by @code{basic::diff} and
+@code{ex::diff}):
 
 @example
-static ex cos_diff_method(ex const & x, unsigned diff_param)
+static ex cos_deriv(const ex & x, unsigned diff_param)
 @{
-    return cos(x);
+    return -sin(x);
 @}
 @end example
 
@@ -1637,20 +1793,26 @@ going to descibe how it expands, please consult your preprocessor if you
 are curious:
 
 @example
-REGISTER_FUNCTION(cos, cos_eval_method, cos_evalf_method, cos_diff, NULL);
+REGISTER_FUNCTION(cos, eval_func(cos_eval).
+                       evalf_func(cos_evalf).
+                       derivative_func(cos_deriv));
 @end example
 
-The first argument is the function's name, the second, third and fourth
-bind the corresponding methods to this objects and the fifth is a slot
-for inserting a method for series expansion.  (If set to @code{NULL} it
-defaults to simple Taylor expansion, which is correct if there are no
-poles involved.  The way GiNaC handles poles in case there are any is
-best understood by studying one of the examples, like the Gamma function
-for instance.  In essence the function first checks if there is a pole
-at the evaluation point and falls back to Taylor expansion if there
-isn't.  Then, the pole is regularized by some suitable transformation.)
-Also, the new function needs to be declared somewhere.  This may also be
-done by a convenient preprocessor macro:
+The first argument is the function's name used for calling it and for
+output.  The second binds the corresponding methods as options to this
+object.  Options are separated by a dot and can be given in an arbitrary
+order.  GiNaC functions understand several more options which are always
+specified as @code{.option(params)}, for example a method for series
+expansion @code{.series_func(cos_series)}.  Again, if no series
+expansion method is given, GiNaC defaults to simple Taylor expansion,
+which is correct if there are no poles involved as is the case for the
+@code{cos} function.  The way GiNaC handles poles in case there are any
+is best understood by studying one of the examples, like the Gamma
+function for instance.  (In essence the function first checks if there
+is a pole at the evaluation point and falls back to Taylor expansion if
+there isn't.  Then, the pole is regularized by some suitable
+transformation.)  Also, the new function needs to be declared somewhere.
+This may also be done by a convenient preprocessor macro:
 
 @example
 DECLARE_FUNCTION_1P(cos)
@@ -1661,7 +1823,7 @@ implementation of @code{cos} is very incomplete and lacks several safety
 mechanisms.  Please, have a look at the real implementation in GiNaC.
 (By the way: in case you are worrying about all the macros above we can
 assure you that functions are GiNaC's most macro-intense classes.  We
-have done our best to avoid them where we can.)
+have done our best to avoid macros where we can.)
 
 That's it. May the source be with you!
 
@@ -1729,6 +1891,18 @@ usually only extend on a high level by writing in the language defined
 by the parser.  In particular, it turns out to be almost impossible to
 fix bugs in a traditional system.
 
+@item
+multiple interfaces: Though real GiNaC programs have to be written in
+some editor, then be compiled, linked and executed, there are more ways
+to work with the GiNaC engine.  Many people want to play with
+expressions interactively, as in traditional CASs.  Currently, two such
+windows into GiNaC have been implemented and many more are possible: the
+tiny @command{ginsh} that is part of the distribution exposes GiNaC's
+types to a command line and second, as a more consistent approach, an
+interactive interface to the @acronym{Cint} C++ interpreter has been put
+together (called @acronym{GiNaC-cint}) that allows an interactive
+scripting interface consistent with the C++ language.
+
 @item
 seemless integration: it is somewhere between difficult and impossible
 to call CAS functions from within a program written in C++ or any other
@@ -1757,16 +1931,6 @@ Of course it also has some disadvantages:
 
 @itemize @bullet
 
-@item
-not interactive: GiNaC programs have to be written in an editor,
-compiled and executed.  You cannot play with expressions interactively.
-However, such an extension is not inherently forbidden by design.  In
-fact, two interactive interfaces are possible: First, a shell that
-exposes GiNaC's types to a command line can readily be written (the tiny
-@command{ginsh} that is part of the distribution being an example) and
-second, as a more consistent approach we are working on an integration
-with the @acronym{CINT} C++ interpreter.
-
 @item
 advanced features: GiNaC cannot compete with a program like
 @emph{Reduce} which exists for more than 30 years now or @emph{Maple}
@@ -2129,7 +2293,7 @@ name of the executable
 
 @item
 If you move the GiNaC package from its installed location,
-you will need either need to modify @command{ginac-config} script
+you will either need to modify @command{ginac-config} script
 manually to point to the new location or rebuild GiNaC.
 
 @end itemize