X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=doc%2Ftutorial%2Fginac.texi;h=aa01956aa3157df50e02ef38ca1daf8bceff1bc3;hp=1021a32a22760cced31fd114e686d27e8a1c01cd;hb=94719f5adbfa69fed0023284811da9d749ddf9f1;hpb=5745deb8dbcee040d1012b8260ed317eb2a32f4b diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 1021a32a..aa01956a 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -476,7 +476,7 @@ installation. 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 -ANSI-standard @cite{ISO/IEC 14882:1998(E)}. We used GCC for development +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 @@ -484,10 +484,10 @@ 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{ftp://ftpthep.physik.uni-mainz.de/pub/gnu/} -(it is covered by 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. +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 @@ -838,8 +838,8 @@ some immediate simplifications. Internally, the anonymous evaluator in GiNaC is implemented by the methods @example -ex ex::eval(int level = 0) const; -ex basic::eval(int level = 0) const; +ex ex::eval() const; +ex basic::eval() const; @end example but unless you are extending GiNaC with your own classes or functions, there @@ -1647,30 +1647,18 @@ packages, but are sometimes used to supply a variable number of arguments of the same type to GiNaC methods such as @code{subs()} and some @code{matrix} constructors, so you should have a basic understanding of them. -Lists can be constructed by assigning a comma-separated sequence of -expressions: +Lists can be constructed from an initializer list of expressions: @example @{ symbol x("x"), y("y"); lst l; - l = x, 2, y, x+y; + l = @{x, 2, y, x+y@}; // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y', // in that order ... @end example -There are also constructors that allow direct creation of lists of up to -16 expressions, which is often more convenient but slightly less efficient: - -@example - ... - // This produces the same list 'l' as above: - // lst l(x, 2, y, x+y); - // lst l = lst(x, 2, y, x+y); - ... -@end example - Use the @code{nops()} method to determine the size (number of expressions) of a list and the @code{op()} method or the @code{[]} operator to access individual elements: @@ -1952,9 +1940,17 @@ matrix::matrix(unsigned r, unsigned c); creates a matrix with @samp{r} rows and @samp{c} columns with all elements set to zero. -The fastest way to create a matrix with preinitialized elements is to assign -a list of comma-separated expressions to an empty matrix (see below for an -example). But you can also specify the elements as a (flat) list with +The easiest way to create a matrix is using an initializer list of +initializer lists, all of the same size: + +@example +@{ + matrix m = @{@{1, -a@}, + @{a, 1@}@}; +@} +@end example + +You can also specify the elements as a (flat) list with @example matrix::matrix(unsigned r, unsigned c, const lst & l); @@ -1977,6 +1973,7 @@ matrices: @cindex @code{symbolic_matrix()} @example ex diag_matrix(const lst & l); +ex diag_matrix(initializer_list l); ex unit_matrix(unsigned x); ex unit_matrix(unsigned r, unsigned c); ex symbolic_matrix(unsigned r, unsigned c, const string & base_name); @@ -1984,7 +1981,7 @@ ex symbolic_matrix(unsigned r, unsigned c, const string & base_name, const string & tex_base_name); @end example -@code{diag_matrix()} constructs a diagonal matrix given the list of diagonal +@code{diag_matrix()} constructs a square diagonal matrix given the diagonal elements. @code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r} by @samp{c}) unit matrix. And finally, @code{symbolic_matrix} constructs a matrix filled with newly generated symbols made of the specified base name @@ -2011,10 +2008,9 @@ that specify which row and column to remove: @example @{ - matrix m(3,3); - m = 11, 12, 13, - 21, 22, 23, - 31, 32, 33; + matrix m = @{@{11, 12, 13@}, + @{21, 22, 23@}, + @{31, 32, 33@}@}; cout << reduced_matrix(m, 1, 1) << endl; // -> [[11,13],[31,33]] cout << sub_matrix(m, 1, 2, 1, 2) << endl; @@ -2040,9 +2036,8 @@ Here are a couple of examples for constructing matrices: @{ symbol a("a"), b("b"); - matrix M(2, 2); - M = a, 0, - 0, b; + matrix M = @{@{a, 0@}, + @{0, b@}@}; cout << M << endl; // -> [[a,0],[0,b]] @@ -2052,13 +2047,13 @@ Here are a couple of examples for constructing matrices: cout << M2 << endl; // -> [[a,0],[0,b]] - cout << matrix(2, 2, lst(a, 0, 0, b)) << endl; + cout << matrix(2, 2, lst@{a, 0, 0, b@}) << endl; // -> [[a,0],[0,b]] - cout << lst_to_matrix(lst(lst(a, 0), lst(0, b))) << endl; + cout << lst_to_matrix(lst@{lst@{a, 0@}, lst@{0, b@}@}) << endl; // -> [[a,0],[0,b]] - cout << diag_matrix(lst(a, b)) << endl; + cout << diag_matrix(lst@{a, b@}) << endl; // -> [[a,0],[0,b]] cout << unit_matrix(3) << endl; @@ -2094,13 +2089,12 @@ and @math{C}: @example @{ - matrix A(2, 2), B(2, 2), C(2, 2); - A = 1, 2, - 3, 4; - B = -1, 0, - 2, 1; - C = 8, 4, - 2, 1; + matrix A = @{@{ 1, 2@}, + @{ 3, 4@}@}; + matrix B = @{@{-1, 0@}, + @{ 2, 1@}@}; + matrix C = @{@{ 8, 4@}, + @{ 2, 1@}@}; matrix result = A.mul(B).sub(C.mul_scalar(2)); cout << result << endl; @@ -2940,10 +2934,9 @@ and scalar products): symbol x("x"), y("y"); // A is a 2x2 matrix, X is a 2x1 vector - matrix A(2, 2), X(2, 1); - A = 1, 2, - 3, 4; - X = x, y; + matrix A = @{@{1, 2@}, + @{3, 4@}@}; + matrix X = @{@{x, y@}@}; cout << indexed(A, i, i) << endl; // -> 5 @@ -3033,6 +3026,8 @@ canonicalize themselves according to rules specified in the implementation of the non-commutative classes. The drawback is that to work with other than the built-in algebras you have to implement new classes yourself. Both symbols and user-defined functions can be specified as being non-commutative. +For symbols, this is done by subclassing class symbol; for functions, +by explicitly setting the return type (@pxref{Symbolic functions}). @cindex @code{return_type()} @cindex @code{return_type_tinfo()} @@ -3265,7 +3260,7 @@ QED: dirac_gamma(mu.toggle_variance()) * (dirac_slash(l, D) + m * dirac_ONE()); e = dirac_trace(e).simplify_indexed(sp); - e = e.collect(lst(l, ldotq, m)); + e = e.collect(lst@{l, ldotq, m@}); cout << e << endl; // -> (8-4*D)*l^2+(8-4*D)*ldotq+4*D*m^2 @} @@ -3357,7 +3352,7 @@ ways. For example ... idx i(symbol("i"), 4); realsymbol s("s"); - ex M = diag_matrix(lst(1, -1, 0, s)); + ex M = diag_matrix(lst@{1, -1, 0, s@}); ex e = clifford_unit(i, M); ex e0 = e.subs(i == 0); ex e1 = e.subs(i == 1); @@ -3423,11 +3418,11 @@ The previous code may be rewritten with the help of @code{lst_to_clifford()} as ... idx i(symbol("i"), 4); realsymbol s("s"); - ex M = diag_matrix(lst(1, -1, 0, s)); - ex e0 = lst_to_clifford(lst(1, 0, 0, 0), i, M); - ex e1 = lst_to_clifford(lst(0, 1, 0, 0), i, M); - ex e2 = lst_to_clifford(lst(0, 0, 1, 0), i, M); - ex e3 = lst_to_clifford(lst(0, 0, 0, 1), i, M); + ex M = diag_matrix(@{1, -1, 0, s@}); + ex e0 = lst_to_clifford(lst@{1, 0, 0, 0@}, i, M); + ex e1 = lst_to_clifford(lst@{0, 1, 0, 0@}, i, M); + ex e2 = lst_to_clifford(lst@{0, 0, 1, 0@}, i, M); + ex e3 = lst_to_clifford(lst@{0, 0, 0, 1@}, i, M); ... @} @end example @@ -3974,8 +3969,6 @@ table: @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 (@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 @@ -4068,7 +4061,7 @@ The following example illustrates the differences between @example @{ symbol A("A"), B("B"), C("C"); - ex e = lst(lst(A, B), C); + ex e = lst@{lst@{A, B@}, C@}; std::copy(e.begin(), e.end(), std::ostream_iterator(cout, "\n")); @@ -4268,13 +4261,13 @@ In the first form, @code{subs()} accepts a relational of the form // -> 73 ex e2 = x*y + x; - cout << "e2(-2, 4) = " << e2.subs(lst(x == -2, y == 4)) << endl; + cout << "e2(-2, 4) = " << e2.subs(lst@{x == -2, y == 4@}) << endl; // -> -10 @} @end example If you specify multiple substitutions, they are performed in parallel, so e.g. -@code{subs(lst(x == y, y == x))} exchanges @samp{x} and @samp{y}. +@code{subs(lst@{x == y, y == x@})} exchanges @samp{x} and @samp{y}. The second form of @code{subs()} takes an @code{exmap} object which is a pair associative container that maps expressions to expressions (currently @@ -4305,7 +4298,7 @@ contain the same number of elements). Using this form, you would write symbol x("x"), y("y"); ex e2 = x*y + x; - cout << "e2(-2, 4) = " << e2.subs(lst(x, y), lst(-2, 4)) << endl; + cout << "e2(-2, 4) = " << e2.subs(lst@{x, y@}, lst@{-2, 4@}) << endl; @} @end example @@ -5025,7 +5018,7 @@ one variable, the variables are given as a list. @example (x*y*sin(y)).is_polynomial(x) // Returns true. -(x*y*sin(y)).is_polynomial(lst(x,y)) // Returns false. +(x*y*sin(y)).is_polynomial(lst@{x,y@}) // Returns false. @end example @subsection Expanding and collecting @@ -5352,7 +5345,7 @@ int main() Square-free decomposition is available in GiNaC: @example -ex sqrfree(const ex & a, const lst & l = lst()); +ex sqrfree(const ex & a, const lst & l = lst@{@}); @end example Here is an example that by the way illustrates how the exact form of the result may slightly depend on the order of differentiation, calling for @@ -5362,10 +5355,10 @@ some care with subsequent processing of the result: symbol x("x"), y("y"); ex BiVarPol = expand(pow(2-2*y,3) * pow(1+x*y,2) * pow(x-2*y,2) * (x+y)); - cout << sqrfree(BiVarPol, lst(x,y)) << endl; + cout << sqrfree(BiVarPol, lst@{x,y@}) << endl; // -> 8*(1-y)^3*(y*x^2-2*y+x*(1-2*y^2))^2*(y+x) - cout << sqrfree(BiVarPol, lst(y,x)) << endl; + cout << sqrfree(BiVarPol, lst@{y,x@}) << endl; // -> 8*(1-y)^3*(-y*x^2+2*y+x*(-1+2*y^2))^2*(y+x) cout << sqrfree(BiVarPol) << endl; @@ -5774,9 +5767,9 @@ almost any kind of object (anything that is @code{subs()}able): cout << ex(indexed(A, i, j)).symmetrize() << endl; // -> 1/2*A.j.i+1/2*A.i.j - cout << ex(indexed(A, i, j, k)).antisymmetrize(lst(i, j)) << endl; + cout << ex(indexed(A, i, j, k)).antisymmetrize(lst@{i, j@}) << endl; // -> -1/2*A.j.i.k+1/2*A.i.j.k - cout << ex(lst(a, b, c)).symmetrize_cyclic(lst(a, b, c)) << endl; + cout << ex(lst@{a, b, c@}).symmetrize_cyclic(lst@{a, b, c@}) << endl; // -> 1/3*@{a,b,c@}+1/3*@{b,c,a@}+1/3*@{c,a,b@} @} @end example @@ -6079,7 +6072,7 @@ The functions only evaluate if the indices are integers greater than zero, excep will be interpreted as the sequence of signs for the corresponding indices @code{m} or the sign of the imaginary part for the corresponding arguments @code{a}, it must contain 1 or -1, e.g. -@code{zeta(lst(3,4), lst(-1,1))} means +@code{zeta(lst@{3,4@}, lst@{-1,1@})} means @tex $\zeta(\overline{3},4)$ @end tex @@ -6087,7 +6080,7 @@ $\zeta(\overline{3},4)$ @command{zeta(\overline@{3@},4)} @end ifnottex and -@code{G(lst(a,b), lst(-1,1), c)} means +@code{G(lst@{a,b@}, lst@{-1,1@}, c)} means @tex $G(a-0\epsilon,b+0\epsilon;c)$. @end tex @@ -6096,7 +6089,7 @@ $G(a-0\epsilon,b+0\epsilon;c)$. @end ifnottex The definition of @code{H} allows indices to be 0, 1 or -1 (in expanded notation) or equally to be any integer (in compact notation). With GiNaC expanded and compact notation can be mixed, -e.g. @code{lst(0,0,-1,0,1,0,0)}, @code{lst(0,0,-1,2,0,0)} and @code{lst(-3,2,0,0)} are equivalent as +e.g. @code{lst@{0,0,-1,0,1,0,0@}}, @code{lst@{0,0,-1,2,0,0@}} and @code{lst@{-3,2,0,0@}} are equivalent as indices. The anonymous evaluator @code{eval()} tries to reduce the functions, if possible, to the least-generic multiple polylogarithm. If all arguments are unit, it returns @code{zeta}. Arguments equal to zero get considered, too. Riemann's zeta function @code{zeta} (with depth one) @@ -6505,7 +6498,7 @@ to map input (sub)strings to arbitrary expressions: table["x"] = x+log(y)+1; parser reader(table); ex e = reader("5*x^3 - x^2"); - // e = 5*(x+log(y)+1)^3 + (x+log(y)+1)^2 + // e = 5*(x+log(y)+1)^3 - (x+log(y)+1)^2 @} @end example @@ -6518,8 +6511,8 @@ with @code{get_syms()} method: parser reader; ex e = reader("2*x+sin(y)"); symtab table = reader.get_syms(); - symbol x = reader["x"]; - symbol y = reader["y"]; + symbol x = ex_to(table["x"]); + symbol y = ex_to(table["y"]); @} @end example @@ -8246,11 +8239,11 @@ class mystring : public basic @{ ... public: - ex eval(int level = 0) const; + ex eval() const override; ... @}; -ex mystring::eval(int level) const +ex mystring::eval() const @{ string new_str; for (size_t i=0; ihold();}. +The @code{hold()} member function sets a flag in the object that prevents +further evaluation. Otherwise we might end up in an endless loop. When you +want to return the object unmodified, use @code{return this->hold();}. + +If our class had subobjects, we would have to evaluate them first (unless +they are all of type @code{ex}, which are automatically evaluated). We don't +have any subexpressions in the @code{mystring} class, so we are not concerned +with this. Let's confirm that it works: @@ -8298,8 +8291,8 @@ required but will make operations with objects of the class more efficient: @cindex @code{calchash()} @cindex @code{is_equal_same_type()} @example -unsigned calchash() const; -bool is_equal_same_type(const basic & other) const; +unsigned calchash() const override; +bool is_equal_same_type(const basic & other) const override; @end example The @code{calchash()} method returns an @code{unsigned} hash value for the @@ -8320,10 +8313,10 @@ For a real algebraic class, there are probably some more functions that you might want to provide: @example -bool info(unsigned inf) const; -ex evalf(int level = 0) const; -ex series(const relational & r, int order, unsigned options = 0) const; -ex derivative(const symbol & s) const; +bool info(unsigned inf) const override; +ex evalf(int level = 0) const override; +ex series(const relational & r, int order, unsigned options = 0) const override; +ex derivative(const symbol & s) const override; @end example If your class stores sub-expressions (see the scalar product example in the @@ -8331,11 +8324,11 @@ previous section) you will probably want to override @cindex @code{let_op()} @example -size_t nops() cont; -ex op(size_t i) const; -ex & let_op(size_t i); -ex subs(const lst & ls, const lst & lr, unsigned options = 0) const; -ex map(map_function & f) const; +size_t nops() const override; +ex op(size_t i) const override; +ex & let_op(size_t i) override; +ex subs(const lst & ls, const lst & lr, unsigned options = 0) const override; +ex map(map_function & f) const override; @end example @code{let_op()} is a variant of @code{op()} that allows write access. The @@ -8434,14 +8427,9 @@ fix bugs in a traditional system. multiple interfaces: Though real GiNaC programs have to be written in some editor, then be compiled, linked and executed, there are more ways to work with the GiNaC engine. Many people want to play with -expressions interactively, as in traditional CASs. Currently, two such -windows into GiNaC have been implemented and many more are possible: the -tiny @command{ginsh} that is part of the distribution exposes GiNaC's -types to a command line and second, as a more consistent approach, an -interactive interface to the Cint C++ interpreter has been put together -(called GiNaC-cint) that allows an interactive scripting interface -consistent with the C++ language. It is available from the usual GiNaC -FTP-site. +expressions interactively, as in traditional CASs: The tiny +@command{ginsh} that comes with the distribution exposes many, but not +all, of GiNaC's types to a command line. @item seamless integration: it is somewhere between difficult and impossible @@ -8492,8 +8480,7 @@ really believe that you need to use a different compiler. We have occasionally used other compilers and may be able to give you advice.} GiNaC uses recent language features like explicit constructors, mutable members, RTTI, @code{dynamic_cast}s and STL, so ANSI compliance is meant -literally. Recent GCC versions starting at 2.95.3, although itself not -yet ANSI compliant, support all needed features. +literally. @end itemize @@ -8914,7 +8901,7 @@ $ make install @itemize @minus{} @item -@cite{ISO/IEC 14882:1998: Programming Languages: C++} +@cite{ISO/IEC 14882:2011: Programming Languages: C++} @item @cite{CLN: A Class Library for Numbers}, @email{haible@@ilog.fr, Bruno Haible}