Patches by Vladimir.
authorChris Dams <Chris.Dams@mi.infn.it>
Tue, 16 May 2006 19:27:20 +0000 (19:27 +0000)
committerChris Dams <Chris.Dams@mi.infn.it>
Tue, 16 May 2006 19:27:20 +0000 (19:27 +0000)
debian/changelog
doc/tutorial/ginac.texi
ginac/clifford.cpp
ginac/ex.cpp
ginac/ex.h
ginac/matrix.cpp
ginac/matrix.h

index 8eeeccf..ca6b24f 100644 (file)
@@ -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 <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 8c7f993..76c2074 100644 (file)
@@ -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
index 65cdefb..e306be8 100644 (file)
@@ -1053,7 +1053,7 @@ ex canonicalize_clifford(const ex & e_)
        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 @@ ex clifford_prime(const ex & e)
        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 @@ 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<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 @@ 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<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 @@ static ex get_clifford_comp(const ex & e, const ex & c)
        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 clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d,
 {
        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 @@ 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<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 f183537..d0645ee 100644 (file)
@@ -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<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 d089236..1e56e82 100644 (file)
@@ -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;
index 3f3b2e6..bc58245 100644 (file)
@@ -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;
index 08c9fe8..ab8d799 100644 (file)
@@ -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);