This is a tutorial that documents GiNaC @value{VERSION}, an open
framework for symbolic computation within the C++ programming language.
-Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
+Copyright (C) 1999-2001 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-2000 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2001 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-2000 Johannes Gutenberg
+language is Copyright @copyright{} 1999-2001 Johannes Gutenberg
University Mainz, Germany.
This program is free software; you can redistribute it and/or
ex MyEx5 = MyEx4 + 1; // similar to above
@end example
-Expressions are handles to other more fundamental objects, that many
-times contain other expressions thus creating a tree of expressions
+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
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. You'll soon learn in this chapter
-how many of the functions on symbols are really classes. This is
-because simple symbolic arithmetic is not supported by languages like
-C++ so in a certain way GiNaC has to implement its own arithmetic.
+containers of expressions and so on.
@cindex container
@cindex atom
To get an idea about what kinds of symbolic composits may be built we
-have a look at the most important classes in the class hierarchy. The
-oval classes are atomic ones and the squared classes are containers.
-The dashed line symbolizes a `points to' or `handles' relationship while
-the solid lines stand for `inherits from' relationship in the class
-hierarchy:
+have a look at the most important classes in the class hierarchy and
+some of the relations among the classes:
@image{classhierarchy}
-Some of the classes shown here (the ones sitting in white boxes) are
-abstract base classes that are of no interest at all for the user. They
-are used internally in order to avoid code duplication if two or more
-classes derived from them share certain features. An example would be
-@code{expairseq}, which is a container for a sequence of pairs each
-consisting of one expression and a number (@code{numeric}). What
-@emph{is} visible to the user are the derived classes @code{add} and
-@code{mul}, representing sums of terms and products, respectively.
-@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:
+The abstract classes shown here (the ones without drop-shadow) are of no
+interest for the user. They are used internally in order to avoid code
+duplication if two or more classes derived from them share certain
+features. An example is @code{expairseq}, a container for a sequence of
+pairs each consisting of one expression and a number (@code{numeric}).
+What @emph{is} visible to the user are the derived classes @code{add}
+and @code{mul}, representing sums and products. @xref{Internal
+Structures}, where these two classes are described in more detail. The
+following table shortly summarizes what kinds of mathematical objects
+are stored in the different classes:
@cartouche
@multitable @columnfractions .22 .78
@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{add} @tab Sums like @math{x+y} or @math{a-(2*b)+3}
+@item @code{mul} @tab Products like @math{x*y} or @math{2*a^2*(x+y+z)/b}
@item @code{power} @tab Exponentials such as @math{x^2}, @math{a^b},
@tex
$\sqrt{2}$
@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{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{color}, @code{coloridx} @tab Element and index 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
+@item @code{idx} @tab Index of a general tensor object
@end multitable
@end cartouche
They are created by simply using the C++ operators @code{==}, @code{!=},
@code{<}, @code{<=}, @code{>} and @code{>=} between two expressions.
-@xref{Mathematical 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. More applications of this class will
-appear throughout the next chapters.
-
+@xref{Mathematical 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 are also used as arguments to the @code{ex::series}
+method, where the left hand side of the relation specifies the variable
+to expand in and the right hand side the expansion point. They can also
+be used for creating systems of equations that are to be solved for
+unknown variables. But the most common usage of objects of this class
+is rather inconspicuous in statements of the form @code{if
+(expand(pow(a+b,2))==a*a+2*a*b+b*b) @{...@}}. Here, an implicit
+conversion from @code{relational} to @code{bool} takes place. Note,
+however, that @code{==} here does not perform any simplifications, hence
+@code{expand()} must be called explicitly.
@node Methods and Functions, Information About Expressions, Relations, Top
@subsection Checking expression types
@cindex @code{is_ex_of_type()}
+@cindex @code{ex_to_numeric()}
+@cindex @code{ex_to_@dots{}}
+@cindex @code{Converting ex to other classes}
@cindex @code{info()}
Sometimes it's useful to check whether a given expression is a plain number,
bool ex::info(unsigned flag);
@end example
+When the test made by @code{is_ex_of_type()} returns true, it is safe to
+call one of the functions @code{ex_to_@dots{}}, where @code{@dots{}} is
+one of the class names (@xref{The Class Hierarchy}, for a list of all
+classes). For example, assuming @code{e} is an @code{ex}:
+
+@example
+@{
+ @dots{}
+ if (is_ex_of_type(e, numeric))
+ numeric n = ex_to_numeric(e);
+ @dots{}
+@}
+@end example
+
@code{is_ex_of_type()} allows you to check whether the top-level object of
an expression @samp{e} is an instance of the GiNaC class @samp{t}
(@xref{The Class Hierarchy}, for a list of all classes). This is most useful,
@item @code{crational_polynomial}
@tab @dots{}a polynomial with (possibly complex) rational coefficients (such as @math{2/3+7/2*I})
@item @code{rational_function}
-@tab @dots{}a rational function
+@tab @dots{}a rational function (@math{x+y}, @math{z/(x+y)})
+@item @code{algebraic}
+@tab @dots{}an algebraic object (@math{sqrt(2)}, @math{sqrt(x)-1})
@end multitable
@end cartouche
for checking whether one expression is equal to another, or equal to zero,
respectively.
-@strong{Warning:} You will also find a @code{ex::compare()} method in the
+@strong{Warning:} You will also find an @code{ex::compare()} method in the
GiNaC header files. This method is however only to be used internally by
GiNaC to establish a canonical sort order for terms, and using it to compare
expressions will give very surprising results.
@cindex simplification
@cindex temporary replacement
-Some basic from of simplification of expressions is called for frequently.
+Some basic form of simplification of expressions is called for frequently.
GiNaC provides the method @code{.normal()}, which converts a rational function
into an equivalent rational function of the form @samp{numerator/denominator}
where numerator and denominator are coprime. If the input expression is already
@tab exponential function
@item @code{log(x)}
@tab natural logarithm
+@item @code{Li2(x)}
+@tab Dilogarithm
@item @code{zeta(x)}
@tab Riemann's zeta function
@item @code{zeta(n, x)}
@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.
+the conventions for C++ as defined in the ANSI standard as far as
+possible. 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 (i.e. continuous with quadrant II). The inverse
+trigonometric and hyperbolic functions are not defined for complex
+arguments by the C++ standard, however. In GiNaC we follow the
+conventions used by CLN, which in turn follow the carefully designed
+definitions in the Common Lisp standard. It should be noted that this
+convention is identical to the one used by the C99 standard and by most
+serious CAS. It is to be expected that future revisions of the C++
+standard incorporate these functions in the complex domain in a manner
+compatible with C99.
@node Input/Output, Extending GiNaC, Built-in Functions, Methods and Functions
@section Symbolic functions
The easiest and most instructive way to start with is probably to
-implement your own function. Objects of class @code{function} are
-inserted into the system via a kind of `registry'. They get a serial
-number that is used internally to identify them but you usually need not
-worry about this. What you have to care for are functions that are
-called when the user invokes certain methods. These are usual
+implement your own function. GiNaC's functions are objects of class
+@code{function}. The preprocessor is then used to convert the function
+names to objects with a corresponding serial number that is used
+internally to identify them. You usually need not worry about this
+number. New functions may be inserted into the system via a kind of
+`registry'. It is your responsibility to care for some functions that
+are called when the user invokes certain methods. These are usual
C++-functions accepting a number of @code{ex} as arguments and returning
one @code{ex}. As an example, if we have a look at a simplified
implementation of the cosine trigonometric function, we first need a
implement does have a pole somewhere in the complex plane, you need to
write another method for Laurent expansion around that point.
-Now that all the ingrediences for @code{cos} have been set up, we need
+Now that all the ingredients for @code{cos} have been set up, we need
to tell the system about it. This is done by a macro and we are not
going to descibe how it expands, please consult your preprocessor if you
are curious:
AC_PROG_INSTALL
AC_LANG_CPLUSPLUS
-AM_PATH_GINAC(0.4.0, [
+AM_PATH_GINAC(0.7.0, [
LIBS="$LIBS $GINACLIB_LIBS"
- CPPFLAGS="$CFLAGS $GINACLIB_CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $GINACLIB_CPPFLAGS"
], AC_MSG_ERROR([need to have GiNaC installed]))
AC_OUTPUT(Makefile)
The only command in this which is not standard for automake
is the @samp{AM_PATH_GINAC} macro.
-That command does the following:
-
-@display
-If a GiNaC version greater than 0.4.0 is found, adds @env{$GINACLIB_LIBS} to
-@env{$LIBS} and @env{$GINACLIB_CPPFLAGS} to @env{$CPPFLAGS}. Otherwise, dies
-with the error message `need to have GiNaC installed'
-@end display
+That command does the following: If a GiNaC version greater or equal
+than 0.7.0 is found, then it adds @env{$GINACLIB_LIBS} to @env{$LIBS}
+and @env{$GINACLIB_CPPFLAGS} to @env{$CPPFLAGS}. Otherwise, it dies with
+the error message `need to have GiNaC installed'
And the @file{Makefile.am}, which will be used to build the Makefile.