]> www.ginac.de Git - ginac.git/blobdiff - ginac/clifford.cpp
Improved dummy index renaming.
[ginac.git] / ginac / clifford.cpp
index 65cdefb210fc353b7e0dfbf63fe6966ed20d65f9..97b503b851eb46a29bd5905b0207a772efe49108 100644 (file)
@@ -158,29 +158,39 @@ ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const
        if (is_a<indexed>(metric)) {
                if (symmetrised && !(ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()).has_symmetry())) {
                        if (is_a<matrix>(metric.op(0))) {
-                               return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(metric.op(0)).transpose())).mul(numeric(1,2)),
+                               return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(metric.op(0)).transpose())).mul(numeric(1, 2)),
                                               symmetric2(), i, j);
                        } else {
                                return simplify_indexed(indexed(metric.op(0)*_ex1_2, i, j) + indexed(metric.op(0)*_ex1_2, j, i));
                        }
                } else {
-                       //return indexed(metric.op(0), ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()), i, j);
                        return metric.subs(lst(metric.op(1) == i, metric.op(2) == j), subs_options::no_pattern);
                }
        } else {
-               // should not really happen since all constructors but clifford() make the metric an indexed object
-               return indexed(metric, i, j);
+               exvector indices = metric.get_free_indices();
+               if (symmetrised)
+                       return _ex1_2*simplify_indexed(metric.subs(lst(indices[0] == i, indices[1] == j), subs_options::no_pattern)
+                                                                       + metric.subs(lst(indices[0] == j, indices[1] == i), subs_options::no_pattern));
+               else
+                       return metric.subs(lst(indices[0] == i, indices[1] == j), subs_options::no_pattern);
        }
 }
 
 bool clifford::same_metric(const ex & other) const
 {
-       if (is_a<clifford>(other)) {
-               return same_metric(ex_to<clifford>(other).get_metric());
-       } else if (is_a<indexed>(other)) {
-               return get_metric(other.op(1), other.op(2)).is_equal(other);
-       } else
-               return false;
+       ex metr;
+       if (is_a<clifford>(other)) 
+               metr = ex_to<clifford>(other).get_metric();
+       else 
+               metr = other;
+
+       if (is_a<indexed>(metr))
+               return metr.op(0).is_equal(get_metric().op(0));
+       else {
+               exvector indices = metr.get_free_indices();
+               return  (indices.size() == 2) 
+                       && simplify_indexed(get_metric(indices[0], indices[1])-metr).is_zero();
+       }
 }
 
 //////////
@@ -436,7 +446,7 @@ static int find_same_metric(exvector & v, ex & c)
                    && ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[1])
                    || (ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0]
                    && ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[1]))) {
-                       return i; // the index of the found
+                       return i; // the index of the found term
                }
        }
        return -1; //nothing found
@@ -758,17 +768,10 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticomm
        if (ex_to<idx>(mu).is_symbolic() && !is_a<varidx>(mu))
                throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)"));
 
-       if (is_a<indexed>(metr)) {
-               exvector indices = ex_to<indexed>(metr).get_indices();
-               if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(indices[1])) {
-                       return clifford(unit, mu, metr, rl, anticommuting);
-               } else {
-                       throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be indexed exactly by two indices of same type as the given index"));
-               }
-       } else if (is_a<tensor>(metr)) {
-               static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
-                       chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
-               return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
+       exvector indices = metr.get_free_indices();
+
+       if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(indices[1])) {
+               return clifford(unit, mu, metr, rl, anticommuting);
        } else if (is_a<matrix>(metr)) {
                matrix M = ex_to<matrix>(metr);
                unsigned n = M.rows();
@@ -792,9 +795,12 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticomm
                } else {
                        throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be a square matrix with the same dimensions as index"));
                }
-       } else {
-               throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type indexed, tensor or matrix"));
-       }
+       } else if (indices.size() == 0) { // a tensor or other expression without indices
+               static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
+                       chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
+               return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
+       }  else 
+               throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type tensor, matrix or an expression with two free indices"));
 }
 
 ex dirac_gamma(const ex & mu, unsigned char rl)
@@ -1053,7 +1059,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 +1126,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 +1151,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 +1233,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 +1252,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 +1341,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 +1358,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)