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-2010 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-2008 Johannes Gutenberg University Mainz, Germany
+Copyright @copyright{} 1999-2010 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-2008 Johannes Gutenberg
+language is Copyright @copyright{} 1999-2010 Johannes Gutenberg
University Mainz, Germany.
This program is free software; you can redistribute it and/or
@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)
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
@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
bool is_exactly_a<T>(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<T>()} returns true, it is safe to call
@{
symbol x("x"), y("y");
- ex e1 = 2*x^2-4*x+3;
+ ex e1 = 2*x*x-4*x+3;
cout << "e1(7) = " << e1.subs(x == 7) << endl;
// -> 73
@code{(x^(-3)*y^(-2)*z).subs(1/(x*y)==c, subs_options::algebraic)} will
return @code{x^(-1)*c^2*z}.
-@strong{Note:} this only works for multiplications
+@strong{Please notice:} this only works for multiplications
and not for locating @code{x+y} within @code{x+y+z}.
@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
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
@}
@end example
-If you declare your own GiNaC functions, then they will conjugate themselves
-by conjugating their arguments. This is the default strategy. If you want to
-change this behavior, you have to supply a specialized conjugation method
-for your function (see @ref{Symbolic functions} and the GiNaC source-code
-for @code{abs} as an example). Also, specialized methods can be provided
-to take real and imaginary parts of user-defined functions.
+If you declare your own GiNaC functions and you want to conjugate them, you
+will have to supply a specialized conjugation method for them (see
+@ref{Symbolic functions} and the GiNaC source-code for @code{abs} as an
+example). GiNaC does not automatically conjugate user-supplied functions
+by conjugating their arguments because this would be incorrect on branch
+cuts. Also, specialized methods can be provided to take real and imaginary
+parts of user-defined functions.
@node Solving linear systems of equations, Input/output, Complex expressions, Methods and functions
@c node-name, next, previous, up
@cindex Monte Carlo integration
@code{FUNCP_2P} allows for two variables in the expression. @code{FUNCP_CUBA} is
the correct type to be used with the CUBA library
-(@uref{http://www.feynarts/cuba}) for numerical integrations. The details for the
+(@uref{http://www.feynarts.de/cuba}) for numerical integrations. The details for the
parameters of @code{FUNCP_CUBA} are explained in the CUBA manual.
@cindex compile_ex
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<matrix>();
+@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<typename T> 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)
@subsection Upgrading extension classes from older version of GiNaC
-GiNaC used to use custom run time type information system (RTTI). It was
-removed from GiNaC. Thus, one need to rewrite constructors which set
+GiNaC used to use a custom run time type information system (RTTI). It was
+removed from GiNaC. Thus, one needs to rewrite constructors which set
@code{tinfo_key} (which does not exist any more). For example,
@example
myclass::myclass() : inherited(&myclass::tinfo_static) @{@}
@end example
-need to be rewritten as
+needs to be rewritten as
@example
myclass::myclass() @{@}
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).