]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
Remove exhashmap<T> class.
[ginac.git] / doc / tutorial / ginac.texi
index 03365d0584719dec019839f802057f57e424f4a2..b348b89ba5290209a098b4c308b28da6c96d5a52 100644 (file)
@@ -24,7 +24,7 @@
 This is a tutorial that documents GiNaC @value{VERSION}, an open
 framework for symbolic computation within the C++ programming language.
 
-Copyright (C) 1999-2017 Johannes Gutenberg University Mainz, Germany
+Copyright (C) 1999-2019 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-2017 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2019 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,7 +135,7 @@ the near future.
 
 @section License
 The GiNaC framework for symbolic computation within the C++ programming
-language is Copyright @copyright{} 1999-2017 Johannes Gutenberg
+language is Copyright @copyright{} 1999-2019 Johannes Gutenberg
 University Mainz, Germany.
 
 This program is free software; you can redistribute it and/or
@@ -201,7 +201,7 @@ 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
+$ c++ hello.cc -o hello -lginac -lcln
 $ ./hello
 355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2
 @end example
@@ -717,7 +717,6 @@ meta-class for storing all mathematical objects.
 * 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
 
 
@@ -1146,7 +1145,7 @@ This creates a symbol that is printed as "@code{x}" in normal output, but
 as "@code{\Box}" in LaTeX code (@xref{Input/output}, for more
 information about the different output formats of expressions in GiNaC).
 GiNaC automatically creates proper LaTeX code for symbols having names of
-greek letters (@samp{alpha}, @samp{mu}, etc.). You can retrive the name
+greek letters (@samp{alpha}, @samp{mu}, etc.). You can retrieve the name
 and the LaTeX name of a symbol using the respective methods:
 @cindex @code{get_name()}
 @cindex @code{get_TeX_name()}
@@ -1533,6 +1532,15 @@ rational number will return a floating-point approximation. Both
 @code{to_int()/to_long()} and @code{to_double()} discard the imaginary
 part of complex numbers.
 
+Note the signature of the above methods, you may need to apply a type
+conversion and call @code{evalf()} as shown in the following example:
+@example
+    ...
+    ex e1 = 1, e2 = sin(Pi/5);
+    cout << ex_to<numeric>(e1).to_int() << endl
+         << ex_to<numeric>(e2.evalf()).to_double() << endl;
+    ...
+@end example
 
 @node Constants, Fundamental containers, Numbers, Basic concepts
 @c    node-name, next, previous, up
@@ -1659,8 +1667,7 @@ Lists can be constructed from an initializer list of expressions:
 @example
 @{
     symbol x("x"), y("y");
-    lst l;
-    l = @{x, 2, y, x+y@};
+    lst l = @{x, 2, y, x+y@};
     // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y',
     // in that order
     ...
@@ -1767,9 +1774,8 @@ You can bring the elements of a list into a canonical order with @code{sort()}:
 
 @example
     ...
-    lst l1, l2;
-    l1 = x, 2, y, x+y;
-    l2 = 2, x+y, x, y;
+    lst l1 = @{x, 2, y, x+y@};
+    lst l2 = @{2, x+y, x, y@};
     l1.sort();
     l2.sort();
     // l1 and l2 are now equal
@@ -1781,8 +1787,7 @@ elements with @code{unique()}:
 
 @example
     ...
-    lst l3;
-    l3 = x, 2, 2, 2, y, x+y, y+x;
+    lst l3 = @{x, 2, 2, 2, y, x+y, y+x@};
     l3.unique();        // l3 is now @{x, 2, y, x+y@}
 @}
 @end example
@@ -2172,22 +2177,20 @@ computing determinants, traces, characteristic polynomials and ranks:
 ex matrix::determinant(unsigned algo=determinant_algo::automatic) const;
 ex matrix::trace() const;
 ex matrix::charpoly(const ex & lambda) const;
-unsigned matrix::rank() const;
+unsigned matrix::rank(unsigned algo=solve_algo::automatic) const;
 @end example
 
-The @samp{algo} argument of @code{determinant()} allows to select
-between different algorithms for calculating the determinant.  The
-asymptotic speed (as parametrized by the matrix size) can greatly differ
-between those algorithms, depending on the nature of the matrix'
-entries.  The possible values are defined in the @file{flags.h} header
-file.  By default, GiNaC uses a heuristic to automatically select an
-algorithm that is likely (but not guaranteed) to give the result most
-quickly.
+The optional @samp{algo} argument of @code{determinant()} and @code{rank()}
+functions allows to select between different algorithms for calculating the
+determinant and rank respectively. The asymptotic speed (as parametrized
+by the matrix size) can greatly differ between those algorithms, depending
+on the nature of the matrix' entries. The possible values are defined in
+the @file{flags.h} header file. By default, GiNaC uses a heuristic to
+automatically select an algorithm that is likely (but not guaranteed)
+to give the result most quickly.
 
-@cindex @code{inverse()} (matrix)
 @cindex @code{solve()}
-Matrices may also be inverted using the @code{ex matrix::inverse()}
-method and linear systems may be solved with:
+Linear systems can be solved with:
 
 @example
 matrix matrix::solve(const matrix & vars, const matrix & rhs,
@@ -2202,6 +2205,15 @@ times @code{p} and in the case of an underdetermined system will still
 contain some of the indeterminates from @code{vars}.  If the system is
 overdetermined, an exception is thrown.
 
+@cindex @code{inverse()} (matrix)
+To invert a matrix, use the method:
+
+@example
+matrix matrix::inverse(unsigned algo=solve_algo::automatic) const;
+@end example
+
+The @samp{algo} argument is optional.  If given, it must be one of
+@code{solve_algo} defined in @file{flags.h}.
 
 @node Indexed objects, Non-commutative objects, Matrices, Basic concepts
 @c    node-name, next, previous, up
@@ -2974,7 +2986,7 @@ one form for @samp{F} and explicitly multiply it with a matrix representation
 of the metric tensor.
 
 
-@node Non-commutative objects, Hash maps, Indexed objects, Basic concepts
+@node Non-commutative objects, Methods and functions, Indexed objects, Basic concepts
 @c    node-name, next, previous, up
 @section Non-commutative objects
 
@@ -3338,7 +3350,7 @@ something very close to @code{dirac_gamma(mu)}, although
 @code{dirac_gamma} have more efficient simplification mechanism. 
 @cindex @code{get_metric()}
 Also, the object created by @code{clifford_unit(mu, minkmetric())} is
-not aware about the symmetry of its metric, see the start of the pevious
+not aware about the symmetry of its metric, see the start of the previous
 paragraph. A more accurate analog of 'dirac_gamma(mu)' should be
 specifies as follows:
 
@@ -3758,43 +3770,7 @@ example:
 @end example
 
 
-@node Hash maps, Methods and functions, Non-commutative objects, Basic concepts
-@c    node-name, next, previous, up
-@section Hash Maps
-@cindex hash maps
-@cindex @code{exhashmap} (class)
-
-For your convenience, GiNaC offers the container template @code{exhashmap<T>}
-that can be used as a drop-in replacement for the STL
-@code{std::map<ex, T, ex_is_less>}, using hash tables to provide faster,
-typically constant-time, element look-up than @code{map<>}.
-
-@code{exhashmap<>} supports all @code{map<>} members and operations, with the
-following differences:
-
-@itemize @bullet
-@item
-no @code{lower_bound()} and @code{upper_bound()} methods
-@item
-no reverse iterators, no @code{rbegin()}/@code{rend()}
-@item 
-no @code{operator<(exhashmap, exhashmap)}
-@item
-the comparison function object @code{key_compare} is hardcoded to
-@code{ex_is_less}
-@item
-the constructor @code{exhashmap(size_t n)} allows specifying the minimum
-initial hash table size (the actual table size after construction may be
-larger than the specified value)
-@item
-the method @code{size_t bucket_count()} returns the current size of the hash
-table
-@item 
-@code{insert()} and @code{erase()} operations invalidate all iterators
-@end itemize
-
-
-@node Methods and functions, Information about expressions, Hash maps, Top
+@node Methods and functions, Information about expressions, Non-commutative objects, Top
 @c    node-name, next, previous, up
 @chapter Methods and functions
 @cindex polynomial
@@ -5124,18 +5100,17 @@ a*(2*x*y+y^2+x^2)
 @cindex @code{ldegree()}
 @cindex @code{coeff()}
 
-The degree and low degree of a polynomial can be obtained using the two
-methods
+The degree and low degree of a polynomial in expanded form can be obtained
+using the two methods
 
 @example
 int ex::degree(const ex & s);
 int ex::ldegree(const ex & s);
 @end example
 
-which also work reliably on non-expanded input polynomials (they even work
-on rational functions, returning the asymptotic degree). By definition, the
-degree of zero is zero. To extract a coefficient with a certain power from
-an expanded polynomial you use
+These functions even work on rational functions, returning the asymptotic
+degree. By definition, the degree of zero is zero. To extract a coefficient
+with a certain power from an expanded polynomial you use
 
 @example
 ex ex::coeff(const ex & s, int n);
@@ -5493,8 +5468,11 @@ ex ex::numer_denom();
 
 These functions will first normalize the expression as described above and
 then return the numerator, denominator, or both as a list, respectively.
-If you need both numerator and denominator, calling @code{numer_denom()} is
-faster than using @code{numer()} and @code{denom()} separately.
+If you need both numerator and denominator, call @code{numer_denom()}: it
+is faster than using @code{numer()} and @code{denom()} separately. And even
+more important: a separate evaluation of @code{numer()} and @code{denom()}
+may result in a spurious sign, e.g. for $x/(x^2-1)$ @code{numer()} may
+return $x$ and @code{denom()} $1-x^2$.
 
 
 @subsection Converting to a polynomial or rational expression
@@ -6243,9 +6221,8 @@ let us solve the two equations @code{a*x+b*y==3} and @code{x-y==b}:
 @example
 @{
     symbol a("a"), b("b"), x("x"), y("y");
-    lst eqns, vars;
-    eqns = a*x+b*y==3, x-y==b;
-    vars = x, y;
+    lst eqns = @{a*x+b*y==3, x-y==b@};
+    lst vars = @{x, y@};
     cout << lsolve(eqns, vars) << endl;
      // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
 @end example
@@ -6738,14 +6715,16 @@ The archive can then be written to a file:
 
 @example
     // ...
-    ofstream out("foobar.gar");
+    ofstream out("foobar.gar", ios::binary);
     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}.
+reconstruct the expressions @code{foo} and @code{bar}. The flag
+@code{ios::binary} prevents locales setting of your OS tampers the
+archive file structure.
 
 @cindex @command{viewgar}
 The tool @command{viewgar} that comes with GiNaC can be used to view
@@ -6763,7 +6742,7 @@ read in again:
 @example
     // ...
     archive a2;
-    ifstream in("foobar.gar");
+    ifstream in("foobar.gar", ios::binary);
     in >> a2;
     // ...
 @end example
@@ -6772,8 +6751,7 @@ And the stored expressions can be retrieved by their name:
 
 @example
     // ...
-    lst syms;
-    syms = x, y;
+    lst syms = @{x, y@};
 
     ex ex1 = a2.unarchive_ex(syms, "foo");
     ex ex2 = a2.unarchive_ex(syms, "the second one");