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
@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
@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
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;
* 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
has requested @code{2^3}.)
@end itemize
-@cindex @code{ginsh}
+@cindex @command{ginsh}
All effects are contrary to mathematical notation and differ from the
way most other CAS handle exponentiation, therefore overloading @code{^}
is ruled out for GiNaC's C++ part. The situation is different in
gamma(15/2) -> (135135/128)*Pi^(1/2)
@end example
-Most of these functions can be differentiated, series expanded and so
-on. Read the next chapter in order to learn more about this.
+@cindex branch cut
+For functions that have a branch cut in the complex plane GiNaC follows
+the conventions for C++ as defined in the ANSI standard. In particular:
+the natural logarithm (@code{log}) and the square root (@code{sqrt})
+both have their branch cuts running along the negative real axis where
+the points on the axis itself belong to the upper part.
+
+Besides evaluation most of these functions allow differentiation, series
+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})
as arguments. There they provide an intuitive syntax for substitutions.
-@node Important Algorithms, Polynomial Expansion, Relations, Top
+@node Archiving, Important Algorithms, Relations, Basic Concepts
+@c node-name, next, previous, up
+@section Archiving Expressions
+@cindex archives (class @code{archive})
+
+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}.
+
+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
@cindex Laurent expansion
Expressions know how to expand themselves as a Taylor series or (more
-generally) a Laurent series. Similar to 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. A sample program could read:
+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:
@example
#include <ginac/ginac.h>
int main()
@{
- symbol x("x");
- numeric point(0);
- ex MyExpr1 = sin(x);
- ex MyExpr2 = 1/(x - pow(x, 2) - pow(x, 3));
- ex MyTailor, MySeries;
+ symbol v("v"), c("c");
+
+ ex gamma = 1/sqrt(1 - pow(v/c,2));
+ ex mass_nonrel = gamma.series(v, 0, 10);
+
+ cout << "the relativistic mass increase with v is " << endl
+ << mass_nonrel << endl;
+
+ cout << "the inverse square of this series is " << endl
+ << pow(mass_nonrel,-2).series(v, 0, 10) << endl;
- MyTailor = MyExpr1.series(x, point, 5);
- cout << MyExpr1 << " == " << MyTailor
- << " for small " << x << endl;
- MySeries = MyExpr2.series(x, point, 7);
- cout << MyExpr2 << " == " << MySeries
- << " for small " << x << endl;
// ...
@}
@end example
+Only calling the series method makes the last output simplify to
+@math{1-v^2/c^2+O(v^10)}, without that call we would just have a long
+series raised to the power @math{-2}.
+
@cindex M@'echain's formula
-As an instructive application, let us calculate the numerical value of
-Archimedes' constant
+As another instructive application, let us calculate the numerical
+value of Archimedes' constant
@tex
$\pi$
@end tex
@c node-name, next, previous, up
@section What doesn't belong into GiNaC
-@cindex @code{ginsh}
+@cindex @command{ginsh}
First of all, GiNaC's name must be read literally. It is designed to be
a library for use within C++. The tiny @command{ginsh} accompanying
GiNaC makes this even more clear: it doesn't even attempt to provide a