]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
implemented operator-> for the iterators
[ginac.git] / doc / tutorial / ginac.texi
index 992a3ec26b5910441e85294f93e2d0799f5fbbf2..34b919edb5a1241bb4b9d4efa590f839fec16366 100644 (file)
@@ -742,7 +742,13 @@ evaluation}. GiNaC only performs transformations that are
 
 @itemize @bullet
 @item
-at most of complexity @math{O(n log n)}
+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})
@@ -773,7 +779,7 @@ ex MyEx6 = z*(x + y);   // z*(x+y)
 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{y-x}) but allows for more efficient operation and usually yields
+of @samp{x-y}) but allows for more efficient operation and usually yields
 some immediate simplifications.
 
 @cindex @code{eval()}
@@ -899,7 +905,13 @@ $\sqrt{2}$
 @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{function} @tab A symbolic function like
+@tex
+$\sin 2x$
+@end tex
+@ifnottex
+@math{sin(2*x)}
+@end ifnottex
 @item @code{lst} @tab Lists of expressions @{@math{x}, @math{2*y}, @math{3+z}@}
 @item @code{matrix} @tab @math{m}x@math{n} matrices of expressions
 @item @code{relational} @tab A relation like the identity @math{x}@code{==}@math{y}
@@ -1162,6 +1174,30 @@ can be applied is listed in the following table.
 @end multitable
 @end cartouche
 
+@subsection Converting numbers
+
+Sometimes it is desirable to convert a @code{numeric} object back to a
+built-in arithmetic type (@code{int}, @code{double}, etc.). The @code{numeric}
+class provides a couple of methods for this purpose:
+
+@cindex @code{to_int()}
+@cindex @code{to_long()}
+@cindex @code{to_double()}
+@cindex @code{to_cl_N()}
+@example
+int numeric::to_int() const;
+long numeric::to_long() const;
+double numeric::to_double() const;
+cln::cl_N numeric::to_cl_N() const;
+@end example
+
+@code{to_int()} and @code{to_long()} only work when the number they are
+applied on is an exact integer. Otherwise the program will halt with a
+message like @samp{Not a 32-bit integer}. @code{to_double()} applied on a
+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.
+
 
 @node Constants, Fundamental containers, Numbers, Basic Concepts
 @c    node-name, next, previous, up
@@ -1663,7 +1699,7 @@ computing determinants, traces, and characteristic polynomials:
 @example
 ex matrix::determinant(unsigned algo=determinant_algo::automatic) const;
 ex matrix::trace() const;
-ex matrix::charpoly(const symbol & lambda) const;
+ex matrix::charpoly(const ex & lambda) const;
 @end example
 
 The @samp{algo} argument of @code{determinant()} allows to select
@@ -2876,6 +2912,7 @@ avoided.
 
 @menu
 * Information About Expressions::
+* Numerical Evaluation::
 * Substituting Expressions::
 * Pattern Matching and Advanced Substitutions::
 * Applying a Function on Subexpressions::
@@ -2891,7 +2928,7 @@ avoided.
 @end menu
 
 
-@node Information About Expressions, Substituting Expressions, Methods and Functions, Methods and Functions
+@node Information About Expressions, Numerical Evaluation, Methods and Functions, Methods and Functions
 @c    node-name, next, previous, up
 @section Getting information about expressions
 
@@ -3088,13 +3125,118 @@ bool ex::is_zero();
 for checking whether one expression is equal to another, or equal to zero,
 respectively.
 
-@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.
+
+@subsection Ordering expressions
+@cindex @code{ex_is_less} (class)
+@cindex @code{ex_is_equal} (class)
+@cindex @code{compare()}
+
+Sometimes it is necessary to establish a mathematically well-defined ordering
+on a set of arbitrary expressions, for example to use expressions as keys
+in a @code{std::map<>} container, or to bring a vector of expressions into
+a canonical order (which is done internally by GiNaC for sums and products).
+
+The operators @code{<}, @code{>} etc. described in the last section cannot
+be used for this, as they don't implement an ordering relation in the
+mathematical sense. In particular, they are not guaranteed to be
+antisymmetric: if @samp{a} and @samp{b} are different expressions, and
+@code{a < b} yields @code{false}, then @code{b < a} doesn't necessarily
+yield @code{true}.
+
+By default, STL classes and algorithms use the @code{<} and @code{==}
+operators to compare objects, which are unsuitable for expressions, but GiNaC
+provides two functors that can be supplied as proper binary comparison
+predicates to the STL:
+
+@example
+class ex_is_less : public std::binary_function<ex, ex, bool> @{
+public:
+    bool operator()(const ex &lh, const ex &rh) const;
+@};
+
+class ex_is_equal : public std::binary_function<ex, ex, bool> @{
+public:
+    bool operator()(const ex &lh, const ex &rh) const;
+@};
+@end example
+
+For example, to define a @code{map} that maps expressions to strings you
+have to use
+
+@example
+std::map<ex, std::string, ex_is_less> myMap;
+@end example
+
+Omitting the @code{ex_is_less} template parameter will introduce spurious
+bugs because the map operates improperly.
+
+Other examples for the use of the functors:
+
+@example
+std::vector<ex> v;
+// fill vector
+...
+
+// sort vector
+std::sort(v.begin(), v.end(), ex_is_less());
+
+// count the number of expressions equal to '1'
+unsigned num_ones = std::count_if(v.begin(), v.end(),
+                                  std::bind2nd(ex_is_equal(), 1));
+@end example
+
+The implementation of @code{ex_is_less} uses the member function
+
+@example
+int ex::compare(const ex & other) const;
+@end example
+
+which returns @math{0} if @code{*this} and @code{other} are equal, @math{-1}
+if @code{*this} sorts before @code{other}, and @math{1} if @code{*this} sorts
+after @code{other}.
+
+
+@node Numerical Evaluation, Substituting Expressions, Information About Expressions, Methods and Functions
+@c    node-name, next, previous, up
+@section Numercial Evaluation
+@cindex @code{evalf()}
+
+GiNaC keeps algebraic expressions, numbers and constants in their exact form.
+To evaluate them using floating-point arithmetic you need to call
+
+@example
+ex ex::evalf(int level = 0) const;
+@end example
+
+@cindex @code{Digits}
+The accuracy of the evaluation is controlled by the global object @code{Digits}
+which can be assigned an integer value. The default value of @code{Digits}
+is 17. @xref{Numbers}, for more information and examples.
+
+To evaluate an expression to a @code{double} floating-point number you can
+call @code{evalf()} followed by @code{numeric::to_double()}, like this:
+
+@example
+@{
+    // Approximate sin(x/Pi)
+    symbol x("x");
+    ex e = series(sin(x/Pi), x == 0, 6);
+
+    // Evaluate numerically at x=0.1
+    ex f = evalf(e.subs(x == 0.1));
+
+    // ex_to<numeric> is an unsafe cast, so check the type first
+    if (is_a<numeric>(f)) @{
+        double d = ex_to<numeric>(f).to_double();
+        cout << d << endl;
+         // -> 0.0318256
+    @} else
+        // error
+@}
+@end example
 
 
-@node Substituting Expressions, Pattern Matching and Advanced Substitutions, Information About Expressions, Methods and Functions
+@node Substituting Expressions, Pattern Matching and Advanced Substitutions, Numerical Evaluation, Methods and Functions
 @c    node-name, next, previous, up
 @section Substituting expressions
 @cindex @code{subs()}
@@ -3134,9 +3276,9 @@ contain the same number of elements). Using this form, you would write
 
 The optional last argument to @code{subs()} is a combination of
 @code{subs_options} flags. There are two options available:
-@code{subs_options::subs_no_pattern} disables pattern matching, which makes
+@code{subs_options::no_pattern} disables pattern matching, which makes
 large @code{subs()} operations significantly faster if you are not using
-patterns. The second option, @code{subs_options::subs_algebraic} enables
+patterns. The second option, @code{subs_options::algebraic} enables
 algebraic substitutions in products and powers.
 @ref{Pattern Matching and Advanced Substitutions}, for more information
 about patterns and algebraic substitutions.
@@ -3444,7 +3586,7 @@ The last example would be written in C++ in this way:
 @end example
 
 @subsection Algebraic substitutions
-Supplying the @code{subs_options::subs_algebraic} option to @code{subs()}
+Supplying the @code{subs_options::algebraic} option to @code{subs()}
 enables smarter, algebraic substitutions in products and powers. If you want
 to substitute some factors of a product, you only need to list these factors
 in your pattern. Furthermore, if an (integer) power of some expression occurs
@@ -3456,41 +3598,41 @@ An example clarifies it all (hopefully):
 
 @example
 cout << (a*a*a*a+b*b*b*b+pow(x+y,4)).subs(wild()*wild()==pow(wild(),3),
-                                        subs_options::subs_algebraic) << endl;
+                                        subs_options::algebraic) << endl;
 // --> (y+x)^6+b^6+a^6
 
-cout << ((a+b+c)*(a+b+c)).subs(a+b==x,subs_options::subs_algebraic) << endl;
+cout << ((a+b+c)*(a+b+c)).subs(a+b==x,subs_options::algebraic) << endl;
 // --> (c+b+a)^2
 // Powers and products are smart, but addition is just the same.
 
-cout << ((a+b+c)*(a+b+c)).subs(a+b+wild()==x+wild(), subs_options::subs_algebraic)
+cout << ((a+b+c)*(a+b+c)).subs(a+b+wild()==x+wild(), subs_options::algebraic)
                                                                       << endl;
 // --> (x+c)^2
 // As I said: addition is just the same.
 
-cout << (pow(a,5)*pow(b,7)+2*b).subs(b*b*a==x,subs_options::subs_algebraic) << endl;
+cout << (pow(a,5)*pow(b,7)+2*b).subs(b*b*a==x,subs_options::algebraic) << endl;
 // --> x^3*b*a^2+2*b
 
-cout << (pow(a,-5)*pow(b,-7)+2*b).subs(1/(b*b*a)==x,subs_options::subs_algebraic)
+cout << (pow(a,-5)*pow(b,-7)+2*b).subs(1/(b*b*a)==x,subs_options::algebraic)
                                                                        << endl;
 // --> 2*b+x^3*b^(-1)*a^(-2)
 
-cout << (4*x*x*x-2*x*x+5*x-1).subs(x==a,subs_options::subs_algebraic) << endl;
+cout << (4*x*x*x-2*x*x+5*x-1).subs(x==a,subs_options::algebraic) << endl;
 // --> -1-2*a^2+4*a^3+5*a
 
 cout << (4*x*x*x-2*x*x+5*x-1).subs(pow(x,wild())==pow(a,wild()),
-                                subs_options::subs_algebraic) << endl;
+                                subs_options::algebraic) << endl;
 // --> -1+5*x+4*x^3-2*x^2
 // You should not really need this kind of patterns very often now.
 // But perhaps this it's-not-a-bug-it's-a-feature (c/sh)ould still change.
 
 cout << ex(sin(1+sin(x))).subs(sin(wild())==cos(wild()),
-                                subs_options::subs_algebraic) << endl;
+                                subs_options::algebraic) << endl;
 // --> cos(1+cos(x))
 
 cout << expand((a*sin(x+y)*sin(x+y)+a*cos(x+y)*cos(x+y)+b)
         .subs((pow(cos(wild()),2)==1-pow(sin(wild()),2)),
-                                subs_options::subs_algebraic)) << endl;
+                                subs_options::algebraic)) << endl;
 // --> b+a
 @end example
 
@@ -4033,8 +4175,8 @@ constants, functions and indexed objects as well:
 The two functions
 
 @example
-ex quo(const ex & a, const ex & b, const symbol & x);
-ex rem(const ex & a, const ex & b, const symbol & x);
+ex quo(const ex & a, const ex & b, const ex & x);
+ex rem(const ex & a, const ex & b, const ex & x);
 @end example
 
 compute the quotient and remainder of univariate polynomials in the variable
@@ -4043,7 +4185,7 @@ compute the quotient and remainder of univariate polynomials in the variable
 The additional function
 
 @example
-ex prem(const ex & a, const ex & b, const symbol & x);
+ex prem(const ex & a, const ex & b, const ex & x);
 @end example
 
 computes the pseudo-remainder of @samp{a} and @samp{b} which satisfies
@@ -4068,9 +4210,9 @@ in which case the value of @code{q} is undefined.
 The methods
 
 @example
-ex ex::unit(const symbol & x);
-ex ex::content(const symbol & x);
-ex ex::primpart(const symbol & x);
+ex ex::unit(const ex & x);
+ex ex::content(const ex & x);
+ex ex::primpart(const ex & x);
 @end example
 
 return the unit part, content part, and primitive polynomial of a multivariate
@@ -4600,6 +4742,21 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Order(x)}
 @tab order term function in truncated power series
 @cindex @code{Order()}
+@item @code{Li(n,x)}
+@tab polylogarithm
+@cindex @code{Li()}
+@item @code{S(n,p,x)}
+@tab Nielsen's generalized polylogarithm
+@cindex @code{S()}
+@item @code{H(m_lst,x)}
+@tab harmonic polylogarithm
+@cindex @code{H()}
+@item @code{Li(m_lst,x_lst)}
+@tab multiple polylogarithm
+@cindex @code{Li()}
+@item @code{mZeta(m_lst)}
+@tab multiple zeta value
+@cindex @code{mZeta()}
 @end multitable
 @end cartouche