From: Chris Dams Date: Tue, 16 May 2006 19:27:20 +0000 (+0000) Subject: Patches by Vladimir. X-Git-Tag: release_1-4-0~89 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=commitdiff_plain;h=92203097b593322eda950cf8c831177a0c204129;p=ginac.git Patches by Vladimir. --- diff --git a/debian/changelog b/debian/changelog index 8eeeccf0..ca6b24f7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,7 +3,7 @@ ginac (1.4.0-1) unstable; urgency=low * New upstream release; binary incompatible, so it's libginac1.4 now. * debian/*: Streamlining by Peter Eisentraut . - -- Richard Kreckel + -- Richard Kreckel Mon, 17 Apr 2006 22:25:48 +0200 ginac (1.3.4-1) unstable; urgency=low diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 8c7f993e..76c20742 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -2053,6 +2053,12 @@ Here are a couple of examples for constructing matrices: @} @end example +@cindex @code{is_zero_matrix()} +The method @code{matrix::is_zero_matrix()} returns @code{true} only if +all entries of the matrix are zeros. There is also method +@code{ex::is_zero_matrix()} which returns @code{true} only if the +expression is zero or a zero matrix. + @cindex @code{transpose()} There are three ways to do arithmetic with matrices. The first (and most direct one) is to use the methods provided by the @code{matrix} class: @@ -3545,9 +3551,10 @@ linear-fractional) transformation @samp{v -> (av+b)/(cv+d)} defined by the matrix @samp{M = [[a, b], [c, d]]}. The parameter @code{G} defines the metric of the surrounding (pseudo-)Euclidean space. This can be an indexed object, tensormetric, matrix or a Clifford unit, in the later -case the optional parameters @code{rl} and @code{anticommuting} are ignored -even if supplied. The returned value of this function is a list of -components of the resulting vector. +case the optional parameters @code{rl} and @code{anticommuting} are +ignored even if supplied. Depending from the type of @code{v} the +returned value of this function is either a vector or a list holding vector's +components. @cindex @code{clifford_max_label()} Finally the function @@ -4097,7 +4104,8 @@ bool ex::is_zero(); @end example for checking whether one expression is equal to another, or equal to zero, -respectively. +respectively. See also the method @code{ex::is_zero_matrix()}, +@pxref{Matrices}. @subsection Ordering expressions diff --git a/ginac/clifford.cpp b/ginac/clifford.cpp index 65cdefb2..e306be8e 100644 --- a/ginac/clifford.cpp +++ b/ginac/clifford.cpp @@ -1053,7 +1053,7 @@ ex canonicalize_clifford(const ex & e_) pointer_to_map_function fcn(canonicalize_clifford); if (is_a(e_) // || is_a(e) || is_a(e) - || is_a(e_)) { + || e_.info(info_flags::list)) { return e_.map(fcn); } else { ex e=simplify_indexed(e_); @@ -1120,7 +1120,7 @@ ex clifford_prime(const ex & e) if (is_a(e) && is_a(e.op(0))) { return -e; } else if (is_a(e) || is_a(e) || is_a(e) //|| is_a(e) || is_a(e) - || is_a(e) || is_a(e)) { + || is_a(e) || e.info(info_flags::list)) { return e.map(fcn); } else if (is_a(e)) { return pow(clifford_prime(e.op(0)), e.op(1)); @@ -1145,7 +1145,7 @@ ex remove_dirac_ONE(const ex & e, unsigned char rl, unsigned options) else throw(std::invalid_argument("remove_dirac_ONE(): expression is a non-scalar Clifford number!")); } else if (is_a(e1) || is_a(e1) || is_a(e1) - || is_a(e1) || is_a(e1)) { + || is_a(e1) || e1.info(info_flags::list)) { if (options & 3) // is a child or was already expanded return e1.map(fcn); else @@ -1227,8 +1227,8 @@ ex lst_to_clifford(const ex & v, const ex & e) { else throw(std::invalid_argument("lst_to_clifford(): dimensions of vector and clifford unit mismatch")); } else - throw(std::invalid_argument("lst_to_clifford(): first argument should be a vector vector")); - } else if (is_a(v)) { + throw(std::invalid_argument("lst_to_clifford(): first argument should be a vector (nx1 or 1xn matrix)")); + } else if (v.info(info_flags::list)) { if (dim == ex_to(v).nops()) return indexed(matrix(dim, 1, ex_to(v)), ex_to(mu).toggle_variance()) * e; else @@ -1246,7 +1246,7 @@ static ex get_clifford_comp(const ex & e, const ex & c) pointer_to_map_function_1arg fcn(get_clifford_comp, c); int ival = ex_to(ex_to(c.op(1)).get_value()).to_int(); - if (is_a(e) || is_a(e) // || is_a(e) || is_a(e) + if (is_a(e) || e.info(info_flags::list) // || is_a(e) || is_a(e) || is_a(e)) return e.map(fcn); else if (is_a(e) || is_a(e)) { @@ -1335,7 +1335,7 @@ ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, { ex x, D, cu; - if (! is_a(v) && ! is_a(v)) + if (! is_a(v) && ! v.info(info_flags::list)) throw(std::invalid_argument("clifford_moebius_map(): parameter v should be either vector or list")); if (is_a(G)) { @@ -1352,8 +1352,8 @@ ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, } x = lst_to_clifford(v, cu); - ex e = simplify_indexed(canonicalize_clifford((a * x + b) * clifford_inverse(c * x + d))); - return clifford_to_lst(e, cu, false); + ex e = clifford_to_lst(simplify_indexed(canonicalize_clifford((a * x + b) * clifford_inverse(c * x + d))), cu, false); + return (is_a(v) ? matrix(ex_to(v).rows(), ex_to(v).cols(), ex_to(e)) : e); } ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl, bool anticommuting) diff --git a/ginac/ex.cpp b/ginac/ex.cpp index f1835377..d0645eef 100644 --- a/ginac/ex.cpp +++ b/ginac/ex.cpp @@ -28,6 +28,7 @@ #include "mul.h" #include "ncmul.h" #include "numeric.h" +#include "matrix.h" #include "power.h" #include "lst.h" #include "relational.h" @@ -254,6 +255,17 @@ bool ex::is_polynomial(const ex & vars) const return bp->is_polynomial(vars); } +/** Check whether expression is zero or zero matrix. */ +bool ex::is_zero_matrix() const +{ + if (is_zero()) + return true; + else { + ex e = evalm(); + return is_a(e) && ex_to(e).is_zero_matrix(); + } +} + // private /** Make this ex writable (if more than one ex handle the same basic) by diff --git a/ginac/ex.h b/ginac/ex.h index d0892362..1e56e823 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -205,6 +205,7 @@ public: int compare(const ex & other) const; bool is_equal(const ex & other) const; bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); } + bool is_zero_matrix() const; // symmetry ex symmetrize() const; diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 3f3b2e6f..bc58245f 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -1527,6 +1527,16 @@ int matrix::pivot(unsigned ro, unsigned co, bool symbolic) return k; } +/** Function to check that all elements of the matrix are zero. + */ +bool matrix::is_zero_matrix() const +{ + for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i) + if(!(i->is_zero())) + return false; + return true; +} + ex lst_to_matrix(const lst & l) { lst::const_iterator itr, itc; diff --git a/ginac/matrix.h b/ginac/matrix.h index 08c9fe88..ab8d7997 100644 --- a/ginac/matrix.h +++ b/ginac/matrix.h @@ -151,6 +151,7 @@ public: matrix solve(const matrix & vars, const matrix & rhs, unsigned algo = solve_algo::automatic) const; unsigned rank() const; + bool is_zero_matrix() const; protected: ex determinant_minor() const; int gauss_elimination(const bool det = false);