X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=doc%2Ftutorial%2Fginac.texi;h=de1e7e9d6e680135c200155f8a565547029acd9a;hb=44f71c740cc727dc30436e240b9a27021a6d7fdf;hp=45a14e614de271944b57d33948942e12707b6348;hpb=40d2f5d1ddacf71991adb447b163a19136ee2179;p=ginac.git diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 45a14e61..de1e7e9d 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -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-2008 Johannes Gutenberg University Mainz, Germany +Copyright (C) 1999-2009 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-2008 Johannes Gutenberg University Mainz, Germany +Copyright @copyright{} 1999-2009 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-2008 Johannes Gutenberg +language is Copyright @copyright{} 1999-2009 Johannes Gutenberg University Mainz, Germany. This program is free software; you can redistribute it and/or @@ -1479,7 +1479,7 @@ evaluated immediately: @tab modulus in positive representation (in the range @code{[0, abs(b)-1]} with the sign of b, or zero) @cindex @code{mod()} @item @code{smod(a, b)} -@tab modulus in symmetric representation (in the range @code{[-iquo(abs(b)-1, 2), iquo(abs(b), 2)]}) +@tab modulus in symmetric representation (in the range @code{[-iquo(abs(b), 2), iquo(abs(b), 2)]}) @cindex @code{smod()} @item @code{irem(a, b)} @tab integer remainder (has the sign of @math{a}, or is zero) @@ -3040,8 +3040,8 @@ Information about the commutativity of an object or expression can be obtained with the two member functions @example -unsigned ex::return_type() const; -unsigned ex::return_type_tinfo() const; +unsigned ex::return_type() const; +return_type_t ex::return_type_tinfo() const; @end example The @code{return_type()} function returns one of three values (defined in @@ -3062,31 +3062,27 @@ expressions in GiNaC: @code{noncommutative_composite} expressions. @end itemize -The value returned by the @code{return_type_tinfo()} method is valid only -when the return type of the expression is @code{noncommutative}. It is a -value that is unique to the class of the object, but may vary every time a -GiNaC program is being run (it is dynamically assigned on start-up). +The @code{return_type_tinfo()} method returns an object of type +@code{return_type_t} that contains information about the type of the expression +and, if given, its representation label (see section on dirac gamma matrices for +more details). The objects of type @code{return_type_t} can be tested for +equality to test whether two expressions belong to the same category and +therefore may not commute. Here are a couple of examples: @cartouche -@multitable @columnfractions 0.33 0.33 0.34 -@item @strong{Expression} @tab @strong{@code{return_type()}} @tab @strong{@code{return_type_tinfo()}} -@item @code{42} @tab @code{commutative} @tab - -@item @code{2*x-y} @tab @code{commutative} @tab - -@item @code{dirac_ONE()} @tab @code{noncommutative} @tab @code{TINFO_clifford} -@item @code{dirac_gamma(mu)*dirac_gamma(nu)} @tab @code{noncommutative} @tab @code{TINFO_clifford} -@item @code{2*color_T(a)} @tab @code{noncommutative} @tab @code{TINFO_color} -@item @code{dirac_ONE()*color_T(a)} @tab @code{noncommutative_composite} @tab - +@multitable @columnfractions .6 .4 +@item @strong{Expression} @tab @strong{@code{return_type()}} +@item @code{42} @tab @code{commutative} +@item @code{2*x-y} @tab @code{commutative} +@item @code{dirac_ONE()} @tab @code{noncommutative} +@item @code{dirac_gamma(mu)*dirac_gamma(nu)} @tab @code{noncommutative} +@item @code{2*color_T(a)} @tab @code{noncommutative} +@item @code{dirac_ONE()*color_T(a)} @tab @code{noncommutative_composite} @end multitable @end cartouche -Note: the @code{return_type_tinfo()} of Clifford objects is only equal to -@code{TINFO_clifford} for objects with a representation label of zero. -Other representation labels yield a different @code{return_type_tinfo()}, -but it's the same for any two objects with the same label. This is also true -for color objects. - A last note: With the exception of matrices, positive integer powers of non-commutative objects are automatically expanded in GiNaC. For example, @code{pow(a*b, 2)} becomes @samp{a*b*a*b} if @samp{a} and @samp{b} are @@ -3870,7 +3866,7 @@ bool is_a(const ex & e); bool is_exactly_a(const ex & e); bool ex::info(unsigned flag); unsigned ex::return_type() const; -unsigned ex::return_type_tinfo() const; +return_type_t ex::return_type_tinfo() const; @end example When the test made by @code{is_a()} returns true, it is safe to call @@ -5354,13 +5350,7 @@ int main() @cindex factorization @cindex @code{sqrfree()} -GiNaC still lacks proper factorization support. Some form of -factorization is, however, easily implemented by noting that factors -appearing in a polynomial with power two or more also appear in the -derivative and hence can easily be found by computing the GCD of the -original polynomial and its derivatives. Any decent system has an -interface for this so called square-free factorization. So we provide -one, too: +Square-free decomposition is available in GiNaC: @example ex sqrfree(const ex & a, const lst & l = lst()); @end example @@ -5385,6 +5375,57 @@ some care with subsequent processing of the result: Note also, how factors with the same exponents are not fully factorized with this method. +@subsection Polynomial factorization +@cindex factorization +@cindex polynomial factorization +@cindex @code{factor()} + +Polynomials can also be fully factored with a call to the function +@example +ex factor(const ex & a, unsigned int options = 0); +@end example +The factorization works for univariate and multivariate polynomials with +rational coefficients. The following code snippet shows its capabilities: +@example + ... + cout << factor(pow(x,2)-1) << endl; + // -> (1+x)*(-1+x) + cout << factor(expand((x-y*z)*(x-pow(y,2)-pow(z,3))*(x+y+z))) << endl; + // -> (y+z+x)*(y*z-x)*(y^2-x+z^3) + cout << factor(pow(x,2)-1+sin(pow(x,2)-1)) << endl; + // -> -1+sin(-1+x^2)+x^2 + ... +@end example +The results are as expected except for the last one where no factorization +seems to have been done. This is due to the default option +@command{factor_options::polynomial} (equals zero) to @command{factor()}, which +tells GiNaC to try a factorization only if the expression is a valid polynomial. +In the shown example this is not the case, because one term is a function. + +There exists a second option @command{factor_options::all}, which tells GiNaC to +ignore non-polynomial parts of an expression and also to look inside function +arguments. With this option the example gives: +@example + ... + cout << factor(pow(x,2)-1+sin(pow(x,2)-1), factor_options::all) + << endl; + // -> (-1+x)*(1+x)+sin((-1+x)*(1+x)) + ... +@end example +GiNaC's factorization functions cannot handle algebraic extensions. Therefore +the following example does not factor: +@example + ... + cout << factor(pow(x,2)-2) << endl; + // -> -2+x^2 and not (x-sqrt(2))*(x+sqrt(2)) + ... +@end example +Factorization is useful in many applications. A lot of algorithms in computer +algebra depend on the ability to factor a polynomial. Of course, factorization +can also be used to simplify expressions, but it is costly and applying it to +complicated expressions (high degrees or many terms) may consume far too much +time. So usually, looking for a GCD at strategic points in a calculation is the +cheaper and more appropriate alternative. @node Rational expressions, Symbolic differentiation, Polynomial arithmetic, Methods and functions @c node-name, next, previous, up @@ -7073,15 +7114,30 @@ This tells @code{evalf()} to not recursively evaluate the parameters of the function before calling the @code{evalf_func()}. @example -set_return_type(unsigned return_type, unsigned return_type_tinfo) +set_return_type(unsigned return_type, const return_type_t * return_type_tinfo) @end example This allows you to explicitly specify the commutation properties of the function (@xref{Non-commutative objects}, for an explanation of -(non)commutativity in GiNaC). For example, you can use -@code{set_return_type(return_types::noncommutative, TINFO_matrix)} to make -GiNaC treat your function like a matrix. By default, functions inherit the -commutation properties of their first argument. +(non)commutativity in GiNaC). For example, with an object of type +@code{return_type_t} created like + +@example +return_type_t my_type = make_return_type_t(); +@end example + +you can use @code{set_return_type(return_types::noncommutative, &my_type)} to +make GiNaC treat your function like a matrix. By default, functions inherit the +commutation properties of their first argument. The utilized template function +@code{make_return_type_t<>()} + +@example +template inline return_type_t make_return_type_t(const unsigned rl = 0) +@end example + +can also be called with an argument specifying the representation label of the +non-commutative function (see section on dirac gamma matrices for more +details). @example set_symmetry(const symmetry & s) @@ -8335,7 +8391,7 @@ Of course it also has some disadvantages: advanced features: GiNaC cannot compete with a program like @emph{Reduce} which exists for more than 30 years now or @emph{Maple} which grows since 1981 by the work of dozens of programmers, with -respect to mathematical features. Integration, factorization, +respect to mathematical features. Integration, non-trivial simplifications, limits etc. are missing in GiNaC (and are not planned for the near future).