Allow for more general expressions for clifford metrics. Patch by Vladimir.
authorChris Dams <Chris.Dams@mi.infn.it>
Wed, 24 May 2006 19:04:18 +0000 (19:04 +0000)
committerChris Dams <Chris.Dams@mi.infn.it>
Wed, 24 May 2006 19:04:18 +0000 (19:04 +0000)
check/exam_clifford.cpp
doc/tutorial/ginac.texi
ginac/clifford.cpp

index 53b5790..5a365d3 100644 (file)
@@ -457,13 +457,10 @@ static unsigned clifford_check7(const ex & G, const symbol & dim)
        varidx mu(symbol("mu"), dim), nu(symbol("nu"), dim), rho(symbol("rho"), dim),
               psi(symbol("psi"),dim), lam(symbol("lambda"), dim), xi(symbol("xi"), dim);
 
-       ex e, G_base;
-
-       if (is_a<indexed>(G))
-               G_base = G.op(0);
-       else
-               G_base = G;
-
+       ex e;
+       clifford unit = ex_to<clifford>(clifford_unit(mu, G));
+       ex scalar = unit.get_metric(varidx(0, dim), varidx(0, dim));
+       
        e = dirac_ONE() * dirac_ONE();
        result += check_equal(e, dirac_ONE());
 
@@ -472,25 +469,25 @@ static unsigned clifford_check7(const ex & G, const symbol & dim)
 
        e = clifford_unit(varidx(2, dim), G) * clifford_unit(varidx(1, dim), G)
          * clifford_unit(varidx(1, dim), G) * clifford_unit(varidx(2, dim), G);
-       result += check_equal(e, dirac_ONE());
+       result += check_equal(e, dirac_ONE()*pow(scalar, 2));
 
        e = clifford_unit(mu, G) * clifford_unit(nu, G)
          * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu.toggle_variance(), G);
-       result += check_equal_simplify(e, pow(dim, 2) * dirac_ONE());
+       result += check_equal_simplify(e, pow(dim*scalar, 2) * dirac_ONE());
 
        e = clifford_unit(mu, G) * clifford_unit(nu, G)
          * clifford_unit(mu.toggle_variance(), G) * clifford_unit(nu.toggle_variance(), G);
-       result += check_equal_simplify(e, 2*dim*dirac_ONE() - pow(dim, 2)*dirac_ONE());
+       result += check_equal_simplify(e, (2*dim - pow(dim, 2))*pow(scalar,2)*dirac_ONE());
 
        e = clifford_unit(nu.toggle_variance(), G) * clifford_unit(rho.toggle_variance(), G)
          * clifford_unit(mu, G) * clifford_unit(rho, G) * clifford_unit(nu, G);
        e = e.simplify_indexed().collect(clifford_unit(mu, G));
-       result += check_equal(e, pow(2 - dim, 2).expand() * clifford_unit(mu, G));
+       result += check_equal(e, pow(scalar*(dim-2), 2).expand() * clifford_unit(mu, G));
 
        // canonicalize_clifford() checks, only for symmetric metrics
        if (ex_to<symmetry>(ex_to<indexed>(ex_to<clifford>(clifford_unit(mu, G)).get_metric()).get_symmetry()).has_symmetry()) {
                e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
-               result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G_base, sy_symm(), nu, mu));
+               result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*unit.get_metric(nu, mu));
                
                e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
                         + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
@@ -498,14 +495,14 @@ static unsigned clifford_check7(const ex & G, const symbol & dim)
                         - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
                         - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
                         - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
-                       + indexed(G_base, sy_symm(), mu, nu) * clifford_unit(lam, G)
-                       - indexed(G_base, sy_symm(), mu, lam) * clifford_unit(nu, G)
-                       + indexed(G_base, sy_symm(), nu, lam) * clifford_unit(mu, G)
+                       + unit.get_metric(mu, nu) * clifford_unit(lam, G)
+                       - unit.get_metric(mu, lam) * clifford_unit(nu, G)
+                       + unit.get_metric(nu, lam) * clifford_unit(mu, G)
                        - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
                result += check_equal(canonicalize_clifford(e), 0);
        } else {
                e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
-               result += check_equal(canonicalize_clifford(e), dirac_ONE()*(indexed(G_base, mu, nu) + indexed(G_base, nu, mu)));
+               result += check_equal(canonicalize_clifford(e), dirac_ONE()*(unit.get_metric(mu, nu) + unit.get_metric(nu, mu)));
                
                e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
                         + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
@@ -513,9 +510,9 @@ static unsigned clifford_check7(const ex & G, const symbol & dim)
                         - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
                         - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
                         - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
-                       + half * (indexed(G_base,  mu, nu) + indexed(G_base,  nu, mu)) * clifford_unit(lam, G)
-                       - half * (indexed(G_base, mu, lam) + indexed(G_base, lam, mu)) * clifford_unit(nu, G)
-                       + half * (indexed(G_base, nu, lam) + indexed(G_base, lam, nu)) * clifford_unit(mu, G)
+                       + half * (unit.get_metric(mu, nu) + unit.get_metric(nu, mu)) * clifford_unit(lam, G)
+                       - half * (unit.get_metric(mu, lam) + unit.get_metric(lam, mu)) * clifford_unit(nu, G)
+                       + half * (unit.get_metric(nu, lam) + unit.get_metric(lam, nu)) * clifford_unit(mu, G)
                        - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
                result += check_equal(canonicalize_clifford(e), 0);
        }
@@ -580,8 +577,13 @@ unsigned exam_clifford()
        result += clifford_check7(minkmetric(), dim); cout << '.' << flush;
 
        varidx chi(symbol("chi"), dim), xi(symbol("xi"), dim);
+       result += clifford_check7(delta_tensor(xi, chi), dim); cout << '.' << flush;
+
        result += clifford_check7(lorentz_g(xi, chi), dim); cout << '.' << flush;
 
+       result += clifford_check7(indexed(-2*minkmetric(), sy_symm(), xi, chi), dim); cout << '.' << flush;
+       result += clifford_check7(-2*delta_tensor(xi, chi), dim); cout << '.' << flush;
+
        if (!result) {
                cout << " passed " << endl;
                clog << "(no output)" << endl;
index 76c2074..26f004e 100644 (file)
@@ -3307,7 +3307,11 @@ generators, an index @code{mu} with a numeric value may be of type
 @code{idx} as well.
 Parameter @code{metr} defines the metric @math{M(i, j)} and can be
 represented by a square @code{matrix}, @code{tensormetric} or @code{indexed} class
-object. Optional parameter @code{rl} allows to distinguish different
+object. In fact, any expression either with two free indices or without
+indices at all is admitted as @code{metr}. In the later case an @code{indexed}
+object with two newly created indices with @code{metr} as its
+@code{op(0)} will be used.
+Optional parameter @code{rl} allows to distinguish different
 Clifford algebras, which will commute with each other. The last
 optional parameter @code{anticommuting} defines if the anticommuting
 assumption (i.e.
index e306be8..97b503b 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)