\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename ginac.info
@settitle GiNaC, an open framework for symbolic computation within the C++ programming language
@setchapternewpage on
@afourpaper
@c For `info' only.
@paragraphindent 0
@c For TeX only.
@iftex
@c I hate putting "@noindent" in front of every paragraph.
@parindent=0pt
@end iftex
@c %**end of header
@include version.texi
@dircategory Mathematics
@direntry
* ginac: (ginac). C++ library for symbolic computation.
@end direntry
@ifinfo
This is a tutorial that documents GiNaC @value{VERSION}, an open
framework for symbolic computation within the C++ programming language.
Copyright (C) 1999-2016 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
are preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
@end ifinfo
@finalout
@c finalout prevents ugly black rectangles on overfull hbox lines
@titlepage
@title GiNaC @value{VERSION}
@subtitle An open framework for symbolic computation within the C++ programming language
@subtitle @value{UPDATED}
@author @uref{http://www.ginac.de}
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1999-2016 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
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
@end titlepage
@page
@contents
@page
@node Top, Introduction, (dir), (dir)
@c node-name, next, previous, up
@top GiNaC
This is a tutorial that documents GiNaC @value{VERSION}, an open
framework for symbolic computation within the C++ programming language.
@menu
* Introduction:: GiNaC's purpose.
* A tour of GiNaC:: A quick tour of the library.
* Installation:: How to install the package.
* Basic concepts:: Description of fundamental classes.
* Methods and functions:: Algorithms for symbolic manipulations.
* Extending GiNaC:: How to extend the library.
* A comparison with other CAS:: Compares GiNaC to traditional CAS.
* Internal structures:: Description of some internal structures.
* Package tools:: Configuring packages to work with GiNaC.
* Bibliography::
* Concept index::
@end menu
@node Introduction, A tour of GiNaC, Top, Top
@c node-name, next, previous, up
@chapter Introduction
@cindex history of GiNaC
The motivation behind GiNaC derives from the observation that most
present day computer algebra systems (CAS) are linguistically and
semantically impoverished. Although they are quite powerful tools for
learning math and solving particular problems they lack modern
linguistic structures that allow for the creation of large-scale
projects. GiNaC is an attempt to overcome this situation by extending a
well established and standardized computer language (C++) by some
fundamental symbolic capabilities, thus allowing for integrated systems
that embed symbolic manipulations together with more established areas
of computer science (like computation-intense numeric applications,
graphical interfaces, etc.) under one roof.
The particular problem that led to the writing of the GiNaC framework is
still a very active field of research, namely the calculation of higher
order corrections to elementary particle interactions. There,
theoretical physicists are interested in matching present day theories
against experiments taking place at particle accelerators. The
computations involved are so complex they call for a combined symbolical
and numerical approach. This turned out to be quite difficult to
accomplish with the present day CAS we have worked with so far and so we
tried to fill the gap by writing GiNaC. But of course its applications
are in no way restricted to theoretical physics.
This tutorial is intended for the novice user who is new to GiNaC but
already has some background in C++ programming. However, since a
hand-made documentation like this one is difficult to keep in sync with
the development, the actual documentation is inside the sources in the
form of comments. That documentation may be parsed by one of the many
Javadoc-like documentation systems. If you fail at generating it you
may access it from @uref{http://www.ginac.de/reference/, the GiNaC home
page}. It is an invaluable resource not only for the advanced user who
wishes to extend the system (or chase bugs) but for everybody who wants
to comprehend the inner workings of GiNaC. This little tutorial on the
other hand only covers the basic things that are unlikely to change in
the near future.
@section License
The GiNaC framework for symbolic computation within the C++ programming
language is Copyright @copyright{} 1999-2016 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
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
@node A tour of GiNaC, How to use it from within C++, Introduction, Top
@c node-name, next, previous, up
@chapter A Tour of GiNaC
This quick tour of GiNaC wants to arise your interest in the
subsequent chapters by showing off a bit. Please excuse us if it
leaves many open questions.
@menu
* How to use it from within C++:: Two simple examples.
* What it can do for you:: A Tour of GiNaC's features.
@end menu
@node How to use it from within C++, What it can do for you, A tour of GiNaC, A tour of GiNaC
@c node-name, next, previous, up
@section How to use it from within C++
The GiNaC open framework for symbolic computation within the C++ programming
language does not try to define a language of its own as conventional
CAS do. Instead, it extends the capabilities of C++ by symbolic
manipulations. Here is how to generate and print a simple (and rather
pointless) bivariate polynomial with some large coefficients:
@example
#include
#include
using namespace std;
using namespace GiNaC;
int main()
@{
symbol x("x"), y("y");
ex poly;
for (int i=0; i<3; ++i)
poly += factorial(i+16)*pow(x,i)*pow(y,2-i);
cout << poly << endl;
return 0;
@}
@end example
Assuming the file is called @file{hello.cc}, on our system we can compile
and run it like this:
@example
$ c++ hello.cc -o hello -lcln -lginac
$ ./hello
355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2
@end example
(@xref{Package tools}, for tools that help you when creating a software
package that uses GiNaC.)
@cindex Hermite polynomial
Next, there is a more meaningful C++ program that calls a function which
generates Hermite polynomials in a specified free variable.
@example
#include
#include
using namespace std;
using namespace GiNaC;
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, n) * diff(HKer, x, n) / HKer);
@}
int main()
@{
symbol z("z");
for (int i=0; i<6; ++i)
cout << "H_" << i << "(z) == " << HermitePoly(z,i) << endl;
return 0;
@}
@end example
When run, this will type out
@example
H_0(z) == 1
H_1(z) == 2*z
H_2(z) == 4*z^2-2
H_3(z) == -12*z+8*z^3
H_4(z) == -48*z^2+16*z^4+12
H_5(z) == 120*z-160*z^3+32*z^5
@end example
This method of generating the coefficients is of course far from optimal
for production purposes.
In order to show some more examples of what GiNaC can do we will now use
the @command{ginsh}, a simple GiNaC interactive shell that provides a
convenient window into GiNaC's capabilities.
@node What it can do for you, Installation, How to use it from within C++, A tour of GiNaC
@c node-name, next, previous, up
@section What it can do for you
@cindex @command{ginsh}
After invoking @command{ginsh} one can test and experiment with GiNaC's
features much like in other Computer Algebra Systems except that it does
not provide programming constructs like loops or conditionals. For a
concise description of the @command{ginsh} syntax we refer to its
accompanied man page. Suffice to say that assignments and comparisons in
@command{ginsh} are written as they are in C, i.e. @code{=} assigns and
@code{==} compares.
It can manipulate arbitrary precision integers in a very fast way.
Rational numbers are automatically converted to fractions of coprime
integers:
@example
> x=3^150;
369988485035126972924700782451696644186473100389722973815184405301748249
> y=3^149;
123329495011708990974900260817232214728824366796574324605061468433916083
> x/y;
3
> y/x;
1/3
@end example
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);
0.14285714285714285714
> Digits=150;
150
> evalf(1/7);
0.1428571428571428571428571428571428571428571428571428571428571428571428
5714285714285714285714285714285714285
@end example
Exact numbers other than rationals that can be manipulated in GiNaC
include predefined constants like Archimedes' @code{Pi}. They can both
be used in symbolic manipulations (as an exact number) as well as in
numeric expressions (as an inexact number):
@example
> a=Pi^2+x;
x+Pi^2
> evalf(a);
9.869604401089358619+x
> x=2;
2
> evalf(a);
11.869604401089358619
@end example
Built-in functions evaluate immediately to exact numbers if
this is possible. Conversions that can be safely performed are done
immediately; conversions that are not generally valid are not done:
@example
> cos(42*Pi);
1
> cos(acos(x));
x
> acos(cos(x));
acos(cos(x))
@end example
(Note that converting the last input to @code{x} would allow one to
conclude that @code{42*Pi} is equal to @code{0}.)
Linear equation systems can be solved along with basic linear
algebra manipulations over symbolic expressions. In C++ GiNaC offers
a matrix class for this purpose but we can see what it can do using
@command{ginsh}'s bracket notation to type them in:
@example
> lsolve(a+x*y==z,x);
y^(-1)*(z-a);
> 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]]
> determinant(M);
11
> charpoly(M,lambda);
lambda^2-3*lambda+11
> A = [ [1, 1], [2, -1] ];
[[1,1],[2,-1]]
> A+2*M;
[[1,1],[2,-1]]+2*[[1,3],[-3,2]]
> evalm(%);
[[3,7],[-4,3]]
> B = [ [0, 0, a], [b, 1, -b], [-1/a, 0, 0] ];
> evalm(B^(2^12345));
[[1,0,0],[0,1,0],[0,0,1]]
@end example
Multivariate polynomials and rational functions may be expanded,
collected and normalized (i.e. converted to a ratio of two coprime
polynomials):
@example
> a = x^4 + 2*x^2*y^2 + 4*x^3*y + 12*x*y^3 - 3*y^4;
12*x*y^3+2*x^2*y^2+4*x^3*y-3*y^4+x^4
> b = x^2 + 4*x*y - y^2;
4*x*y-y^2+x^2
> expand(a*b);
8*x^5*y+17*x^4*y^2+43*x^2*y^4-24*x*y^5+16*x^3*y^3+3*y^6+x^6
> collect(a+b,x);
4*x^3*y-y^2-3*y^4+(12*y^3+4*y)*x+x^4+x^2*(1+2*y^2)
> collect(a+b,y);
12*x*y^3-3*y^4+(-1+2*x^2)*y^2+(4*x+4*x^3)*y+x^2+x^4
> normal(a/b);
3*y^2+x^2
@end example
You can differentiate functions and expand them as Taylor or Laurent
series in a very natural syntax (the second argument of @code{series} is
a relation defining the evaluation point, the third specifies the
order):
@cindex Zeta function
@example
> diff(tan(x),x);
tan(x)^2+1
> series(sin(x),x==0,4);
x-1/6*x^3+Order(x^4)
> series(1/tan(x),x==0,4);
x^(-1)-1/3*x+Order(x^2)
> series(tgamma(x),x==0,3);
x^(-1)-Euler+(1/12*Pi^2+1/2*Euler^2)*x+
(-1/3*zeta(3)-1/12*Pi^2*Euler-1/6*Euler^3)*x^2+Order(x^3)
> evalf(%);
x^(-1)-0.5772156649015328606+(0.9890559953279725555)*x
-(0.90747907608088628905)*x^2+Order(x^3)
> series(tgamma(2*sin(x)-2),x==Pi/2,6);
-(x-1/2*Pi)^(-2)+(-1/12*Pi^2-1/2*Euler^2-1/240)*(x-1/2*Pi)^2
-Euler-1/12+Order((x-1/2*Pi)^3)
@end example
Here we have made use of the @command{ginsh}-command @code{%} to pop the
previously evaluated element from @command{ginsh}'s internal stack.
Often, functions don't have roots in closed form. Nevertheless, it's
quite easy to compute a solution numerically, to arbitrary precision:
@cindex fsolve
@example
> Digits=50:
> fsolve(cos(x)==x,x,0,2);
0.7390851332151606416553120876738734040134117589007574649658
> f=exp(sin(x))-x:
> X=fsolve(f,x,-10,10);
2.2191071489137460325957851882042901681753665565320678854155
> subs(f,x==X);
-6.372367644529809108115521591070847222364418220770475144296E-58
@end example
Notice how the final result above differs slightly from zero by about
@math{6*10^(-58)}. This is because with 50 decimal digits precision the
root cannot be represented more accurately than @code{X}. Such
inaccuracies are to be expected when computing with finite floating
point values.
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 now easy:
@example
> in=.0254*m;
0.0254*m
> lb=.45359237*kg;
0.45359237*kg
> 200*lb/in^2;
140613.91592783185568*kg*m^(-2)
@end example
@node Installation, Prerequisites, What it can do for you, Top
@c node-name, next, previous, up
@chapter Installation
@cindex CLN
GiNaC's installation follows the spirit of most GNU software. It is
easily installed on your system by three steps: configuration, build,
installation.
@menu
* Prerequisites:: Packages upon which GiNaC depends.
* Configuration:: How to configure GiNaC.
* Building GiNaC:: How to compile GiNaC.
* Installing GiNaC:: How to install GiNaC on your system.
@end menu
@node Prerequisites, Configuration, Installation, 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
ISO standard @cite{ISO/IEC 14882:2011(E)}. We used 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. The pkg-config utility is
required for the configuration, it can be downloaded from
@uref{http://pkg-config.freedesktop.org}.
Last but not least, the CLN library
is used extensively and needs to be installed on your system.
Please get it from @uref{http://www.ginac.de/CLN/} (it is licensed under
the 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.
@node Configuration, Building GiNaC, Prerequisites, Installation
@c node-name, next, previous, up
@section Configuration
@cindex configuration
@cindex Autoconf
To configure GiNaC means to prepare the source distribution for
building. It is done via a shell script called @command{configure} that
is shipped with the sources and was originally generated by GNU
Autoconf. Since a configure script generated by GNU Autoconf never
prompts, all customization must be done either via command line
parameters or environment variables. It accepts a list of parameters,
the complete set of which can be listed by calling it with the
@option{--help} option. The most important ones will be shortly
described in what follows:
@itemize @bullet
@item
@option{--disable-shared}: When given, this option switches off the
build of a shared library, i.e. a @file{.so} file. This may be convenient
when developing because it considerably speeds up compilation.
@item
@option{--prefix=@var{PREFIX}}: The directory where the compiled library
and headers are installed. It defaults to @file{/usr/local} which means
that the library is installed in the directory @file{/usr/local/lib},
the header files in @file{/usr/local/include/ginac} and the documentation
(like this one) into @file{/usr/local/share/doc/GiNaC}.
@item
@option{--libdir=@var{LIBDIR}}: Use this option in case you want to have
the library installed in some other directory than
@file{@var{PREFIX}/lib/}.
@item
@option{--includedir=@var{INCLUDEDIR}}: Use this option in case you want
to have the header files installed in some other directory than
@file{@var{PREFIX}/include/ginac/}. For instance, if you specify
@option{--includedir=/usr/include} you will end up with the header files
sitting in the directory @file{/usr/include/ginac/}. Note that the
subdirectory @file{ginac} is enforced by this process in order to
keep the header files separated from others. This avoids some
clashes and allows for an easier deinstallation of GiNaC. This ought
to be considered A Good Thing (tm).
@item
@option{--datadir=@var{DATADIR}}: This option may be given in case you
want to have the documentation installed in some other directory than
@file{@var{PREFIX}/share/doc/GiNaC/}.
@end itemize
In addition, you may specify some environment variables. @env{CXX}
holds the path and the name of the C++ compiler in case you want to
override the default in your path. (The @command{configure} script
searches your path for @command{c++}, @command{g++}, @command{gcc},
@command{CC}, @command{cxx} and @command{cc++} in that order.) It may
be very useful to define some compiler flags with the @env{CXXFLAGS}
environment variable, like optimization, debugging information and
warning levels. If omitted, it defaults to @option{-g
-O2}.@footnote{The @command{configure} script is itself generated from
the file @file{configure.ac}. It is only distributed in packaged
releases of GiNaC. If you got the naked sources, e.g. from git, you
must generate @command{configure} along with the various
@file{Makefile.in} by using the @command{autoreconf} utility. This will
require a fair amount of support from your local toolchain, though.}
The whole process is illustrated in the following two
examples. (Substitute @command{setenv @var{VARIABLE} @var{value}} for
@command{export @var{VARIABLE}=@var{value}} if the Berkeley C shell is
your login shell.)
Here is a simple configuration for a site-wide GiNaC library assuming
everything is in default paths:
@example
$ export CXXFLAGS="-Wall -O2"
$ ./configure
@end example
And here is a configuration for a private static GiNaC library with
several components sitting in custom places (site-wide GCC and private
CLN). The compiler is persuaded to be picky and full assertions and
debugging information are switched on:
@example
$ export CXX=/usr/local/gnu/bin/c++
$ export CPPFLAGS="$(CPPFLAGS) -I$(HOME)/include"
$ export CXXFLAGS="$(CXXFLAGS) -DDO_GINAC_ASSERT -ggdb -Wall -pedantic"
$ export LDFLAGS="$(LDFLAGS) -L$(HOME)/lib"
$ ./configure --disable-shared --prefix=$(HOME)
@end example
@node Building GiNaC, Installing GiNaC, Configuration, Installation
@c node-name, next, previous, up
@section Building GiNaC
@cindex building GiNaC
After proper configuration you should just build the whole
library by typing
@example
$ make
@end example
at the command prompt and go for a cup of coffee. The exact time it
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 collection of
regression tests by typing
@example
$ make check
@end example
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. Some
of the tests in sections @emph{checks} and @emph{timings} may require
insane amounts of memory and CPU time. Feel free to kill them if your
machine catches fire. Another quite important intent is to allow people
to fiddle around with optimization.
By default, the only documentation that will be built is this tutorial
in @file{.info} format. To build the GiNaC tutorial and reference manual
in HTML, DVI, PostScript, or PDF formats, use one of
@example
$ make html
$ make dvi
$ make ps
$ make pdf
@end example
Generally, the top-level Makefile runs recursively to the
subdirectories. It is therefore safe to go into any subdirectory
(@code{doc/}, @code{ginsh/}, @dots{}) and simply type @code{make}
@var{target} there in case something went wrong.
@node Installing GiNaC, Basic concepts, Building GiNaC, Installation
@c node-name, next, previous, up
@section Installing GiNaC
@cindex installation
To install GiNaC on your system, simply type
@example
$ make install
@end example
As described in the section about configuration the files will be
installed in the following directories (the directories will be created
if they don't already exist):
@itemize @bullet
@item
@file{libginac.a} will go into @file{@var{PREFIX}/lib/} (or
@file{@var{LIBDIR}}) which defaults to @file{/usr/local/lib/}.
So will @file{libginac.so} unless the configure script was
given the option @option{--disable-shared}. The proper symlinks
will be established as well.
@item
All the header files will be installed into @file{@var{PREFIX}/include/ginac/}
(or @file{@var{INCLUDEDIR}/ginac/}, if specified).
@item
All documentation (info) will be stuffed into
@file{@var{PREFIX}/share/doc/GiNaC/} (or
@file{@var{DATADIR}/doc/GiNaC/}, if @var{DATADIR} was specified).
@end itemize
For the sake of completeness we will list some other useful make
targets: @command{make clean} deletes all files generated by
@command{make}, i.e. all the object files. In addition @command{make
distclean} removes all files generated by the configuration and
@command{make maintainer-clean} goes one step further and deletes files
that may require special tools to rebuild (like the @command{libtool}
for instance). Finally @command{make uninstall} removes the installed
library, header files and documentation@footnote{Uninstallation does not
work after you have called @command{make distclean} since the
@file{Makefile} is itself generated by the configuration from
@file{Makefile.in} and hence deleted by @command{make distclean}. There
are two obvious ways out of this dilemma. First, you can run the
configuration again with the same @var{PREFIX} thus creating a
@file{Makefile} with a working @samp{uninstall} target. Second, you can
do it by hand since you now know where all the files went during
installation.}.
@node Basic concepts, Expressions, Installing GiNaC, Top
@c node-name, next, previous, up
@chapter Basic concepts
This chapter will describe the different fundamental objects that can be
handled by GiNaC. But before doing so, it is worthwhile introducing you
to the more commonly used class of expressions, representing a flexible
meta-class for storing all mathematical objects.
@menu
* Expressions:: The fundamental GiNaC class.
* Automatic evaluation:: Evaluation and canonicalization.
* Error handling:: How the library reports errors.
* The class hierarchy:: Overview of GiNaC's classes.
* Symbols:: Symbolic objects.
* Numbers:: Numerical objects.
* Constants:: Pre-defined constants.
* Fundamental containers:: Sums, products and powers.
* 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.
* Hash maps:: A faster alternative to std::map<>.
@end menu
@node Expressions, Automatic evaluation, Basic concepts, Basic concepts
@c node-name, next, previous, up
@section Expressions
@cindex expression (class @code{ex})
@cindex @code{has()}
The most common class of objects a user deals with is the expression
@code{ex}, representing a mathematical object like a variable, number,
function, sum, product, etc@dots{} Expressions may be put together to form
new expressions, passed as arguments to functions, and so on. Here is a
little collection of valid expressions:
@example
ex MyEx1 = 5; // simple number
ex MyEx2 = x + 2*y; // polynomial in x and y
ex MyEx3 = (x + 1)/(x - 1); // rational expression
ex MyEx4 = sin(x + 2*y) + 3*z + 41; // containing a function
ex MyEx5 = MyEx4 + 1; // similar to above
@end example
Expressions are handles to other more fundamental objects, that often
contain other expressions thus creating a tree of expressions
(@xref{Internal structures}, for particular examples). Most methods on
@code{ex} therefore run top-down through such an expression tree. For
example, the method @code{has()} scans recursively for occurrences of
something inside an expression. Thus, if you have declared @code{MyEx4}
as in the example above @code{MyEx4.has(y)} will find @code{y} inside
the argument of @code{sin} and hence return @code{true}.
The next sections will outline the general picture of GiNaC's class
hierarchy and describe the classes of objects that are handled by
@code{ex}.
@subsection Note: Expressions and STL containers
GiNaC expressions (@code{ex} objects) have value semantics (they can be
assigned, reassigned and copied like integral types) but the operator
@code{<} doesn't provide a well-defined ordering on them. In STL-speak,
expressions are @samp{Assignable} but not @samp{LessThanComparable}.
This implies that in order to use expressions in sorted containers such as
@code{std::map<>} and @code{std::set<>} you have to supply a suitable
comparison predicate. GiNaC provides such a predicate, called
@code{ex_is_less}. For example, a set of expressions should be defined
as @code{std::set}.
Unsorted containers such as @code{std::vector<>} and @code{std::list<>}
don't pose a problem. A @code{std::vector} works as expected.
@xref{Information about expressions}, for more about comparing and ordering
expressions.
@node Automatic evaluation, Error handling, Expressions, Basic concepts
@c node-name, next, previous, up
@section Automatic evaluation and canonicalization of expressions
@cindex evaluation
GiNaC performs some automatic transformations on expressions, to simplify
them and put them into a canonical form. Some examples:
@example
ex MyEx1 = 2*x - 1 + x; // 3*x-1
ex MyEx2 = x - x; // 0
ex MyEx3 = cos(2*Pi); // 1
ex MyEx4 = x*y/x; // y
@end example
This behavior is usually referred to as @dfn{automatic} or @dfn{anonymous
evaluation}. GiNaC only performs transformations that are
@itemize @bullet
@item
at most of complexity
@tex
$O(n\log n)$
@end tex
@ifnottex
@math{O(n log n)}
@end ifnottex
@item
algebraically correct, possibly except for a set of measure zero (e.g.
@math{x/x} is transformed to @math{1} although this is incorrect for @math{x=0})
@end itemize
There are two types of automatic transformations in GiNaC that may not
behave in an entirely obvious way at first glance:
@itemize
@item
The terms of sums and products (and some other things like the arguments of
symmetric functions, the indices of symmetric tensors etc.) are re-ordered
into a canonical form that is deterministic, but not lexicographical or in
any other way easy to guess (it almost always depends on the number and
order of the symbols you define). However, constructing the same expression
twice, either implicitly or explicitly, will always result in the same
canonical form.
@item
Expressions of the form 'number times sum' are automatically expanded (this
has to do with GiNaC's internal representation of sums and products). For
example
@example
ex MyEx5 = 2*(x + y); // 2*x+2*y
ex MyEx6 = z*(x + y); // z*(x+y)
@end example
@end itemize
The general rule is that when you construct expressions, GiNaC automatically
creates them in canonical form, which might differ from the form you typed in
your program. This may create some awkward looking output (@samp{-y+x} instead
of @samp{x-y}) but allows for more efficient operation and usually yields
some immediate simplifications.
@cindex @code{eval()}
Internally, the anonymous evaluator in GiNaC is implemented by the methods
@example
ex ex::eval() const;
ex basic::eval() const;
@end example
but unless you are extending GiNaC with your own classes or functions, there
should never be any reason to call them explicitly. All GiNaC methods that
transform expressions, like @code{subs()} or @code{normal()}, automatically
re-evaluate their results.
@node Error handling, The class hierarchy, Automatic evaluation, Basic concepts
@c node-name, next, previous, up
@section Error handling
@cindex exceptions
@cindex @code{pole_error} (class)
GiNaC reports run-time errors by throwing C++ exceptions. All exceptions
generated by GiNaC are subclassed from the standard @code{exception} class
defined in the @file{} header. In addition to the predefined
@code{logic_error}, @code{domain_error}, @code{out_of_range},
@code{invalid_argument}, @code{runtime_error}, @code{range_error} and
@code{overflow_error} types, GiNaC also defines a @code{pole_error}
exception that gets thrown when trying to evaluate a mathematical function
at a singularity.
The @code{pole_error} class has a member function
@example
int pole_error::degree() const;
@end example
that returns the order of the singularity (or 0 when the pole is
logarithmic or the order is undefined).
When using GiNaC it is useful to arrange for exceptions to be caught in
the main program even if you don't want to do any special error handling.
Otherwise whenever an error occurs in GiNaC, it will be delegated to the
default exception handler of your C++ compiler's run-time system which
usually only aborts the program without giving any information what went
wrong.
Here is an example for a @code{main()} function that catches and prints
exceptions generated by GiNaC:
@example
#include
#include
#include
using namespace std;
using namespace GiNaC;
int main()
@{
try @{
...
// code using GiNaC
...
@} catch (exception &p) @{
cerr << p.what() << endl;
return 1;
@}
return 0;
@}
@end example
@node The class hierarchy, Symbols, Error handling, Basic concepts
@c node-name, next, previous, up
@section The class hierarchy
GiNaC's class hierarchy consists of several classes representing
mathematical objects, all of which (except for @code{ex} and some
helpers) are internally derived from one abstract base class called
@code{basic}. You do not have to deal with objects of class
@code{basic}, instead you'll be dealing with symbols, numbers,
containers of expressions and so on.
@cindex container
@cindex atom
To get an idea about what kinds of symbolic composites may be built we
have a look at the most important classes in the class hierarchy and
some of the relations among the classes:
@ifnotinfo
@image{classhierarchy}
@end ifnotinfo
@ifinfo