Dear All, I propose to change all test for an argument type lst as follows: is_a<lst>(e) --> e.info(info_flags::list) The former tests fail with lst created by boostPython (e.g. pyGiNaC) and the later are passed. I did the change in clifford.cpp and wondering if it should be applied everywhere. The included patch is cumulative from my previous two messages. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ /home/amsta/kisilv/GiNaC Index: debian/changelog =================================================================== RCS file: /home/cvs/GiNaC/debian/changelog,v retrieving revision 1.36 diff -u -r1.36 changelog --- debian/changelog 20 Apr 2006 22:59:39 -0000 1.36 +++ debian/changelog 10 May 2006 12:16:15 -0000 @@ -3,7 +3,7 @@ * New upstream release; binary incompatible, so it's libginac1.4 now. * debian/*: Streamlining by Peter Eisentraut <petere@debian.org>. - -- Richard Kreckel <kreckel@ginac.de> <DATE> + -- Richard Kreckel <kreckel@ginac.de> Mon, 17 Apr 2006 22:25:48 +0200 ginac (1.3.4-1) unstable; urgency=low Index: doc/tutorial/ginac.texi =================================================================== RCS file: /home/cvs/GiNaC/doc/tutorial/ginac.texi,v retrieving revision 1.185 diff -u -r1.185 ginac.texi --- doc/tutorial/ginac.texi 22 Apr 2006 15:42:57 -0000 1.185 +++ doc/tutorial/ginac.texi 10 May 2006 12:16:15 -0000 @@ -2053,6 +2053,12 @@ @} @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 @@ 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 @@ @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 Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.95 diff -u -r1.95 clifford.cpp --- ginac/clifford.cpp 22 Feb 2006 14:52:07 -0000 1.95 +++ ginac/clifford.cpp 10 May 2006 12:16:15 -0000 @@ -1053,7 +1053,7 @@ pointer_to_map_function fcn(canonicalize_clifford); if (is_a<matrix>(e_) // || is_a<pseries>(e) || is_a<integral>(e) - || is_a<lst>(e_)) { + || e_.info(info_flags::list)) { return e_.map(fcn); } else { ex e=simplify_indexed(e_); @@ -1120,7 +1120,7 @@ if (is_a<clifford>(e) && is_a<cliffordunit>(e.op(0))) { return -e; } else if (is_a<add>(e) || is_a<ncmul>(e) || is_a<mul>(e) //|| is_a<pseries>(e) || is_a<integral>(e) - || is_a<matrix>(e) || is_a<lst>(e)) { + || is_a<matrix>(e) || e.info(info_flags::list)) { return e.map(fcn); } else if (is_a<power>(e)) { return pow(clifford_prime(e.op(0)), e.op(1)); @@ -1145,7 +1145,7 @@ else throw(std::invalid_argument("remove_dirac_ONE(): expression is a non-scalar Clifford number!")); } else if (is_a<add>(e1) || is_a<ncmul>(e1) || is_a<mul>(e1) - || is_a<matrix>(e1) || is_a<lst>(e1)) { + || is_a<matrix>(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 @@ 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<lst>(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<lst>(v).nops()) return indexed(matrix(dim, 1, ex_to<lst>(v)), ex_to<varidx>(mu).toggle_variance()) * e; else @@ -1246,7 +1246,7 @@ pointer_to_map_function_1arg<const ex &> fcn(get_clifford_comp, c); int ival = ex_to<numeric>(ex_to<varidx>(c.op(1)).get_value()).to_int(); - if (is_a<add>(e) || is_a<lst>(e) // || is_a<pseries>(e) || is_a<integral>(e) + if (is_a<add>(e) || e.info(info_flags::list) // || is_a<pseries>(e) || is_a<integral>(e) || is_a<matrix>(e)) return e.map(fcn); else if (is_a<ncmul>(e) || is_a<mul>(e)) { @@ -1335,7 +1335,7 @@ { ex x, D, cu; - if (! is_a<matrix>(v) && ! is_a<lst>(v)) + if (! is_a<matrix>(v) && ! v.info(info_flags::list)) throw(std::invalid_argument("clifford_moebius_map(): parameter v should be either vector or list")); if (is_a<clifford>(G)) { @@ -1352,8 +1352,8 @@ } 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<matrix>(v) ? matrix(ex_to<matrix>(v).rows(), ex_to<matrix>(v).cols(), ex_to<lst>(e)) : e); } ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl, bool anticommuting) Index: ginac/ex.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/ex.h,v retrieving revision 1.87 diff -u -r1.87 ex.h --- ginac/ex.h 21 Apr 2006 12:16:01 -0000 1.87 +++ ginac/ex.h 10 May 2006 12:16:15 -0000 @@ -205,6 +205,7 @@ 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; Index: ginac/ex.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/ex.cpp,v retrieving revision 1.60 diff -u -r1.60 ex.cpp --- ginac/ex.cpp 27 Mar 2006 15:13:22 -0000 1.60 +++ ginac/ex.cpp 10 May 2006 12:16:16 -0000 @@ -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 @@ 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<matrix>(e) && ex_to<matrix>(e).is_zero_matrix(); + } +} + // private /** Make this ex writable (if more than one ex handle the same basic) by Index: ginac/matrix.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/matrix.h,v retrieving revision 1.71 diff -u -r1.71 matrix.h --- ginac/matrix.h 21 Apr 2006 12:16:01 -0000 1.71 +++ ginac/matrix.h 10 May 2006 12:16:16 -0000 @@ -151,6 +151,7 @@ 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); Index: ginac/matrix.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/matrix.cpp,v retrieving revision 1.108 diff -u -r1.108 matrix.cpp --- ginac/matrix.cpp 21 Apr 2006 12:16:01 -0000 1.108 +++ ginac/matrix.cpp 10 May 2006 12:16:16 -0000 @@ -1527,6 +1527,16 @@ return k; } +/** Function to check that all elements of the matrix are zero. + */ +bool matrix::is_zero_matrix() const +{ + bool result = true; + for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i) + result = result && (*i).is_zero(); + return result; +} + ex lst_to_matrix(const lst & l) { lst::const_iterator itr, itc;