- The dimension of indices is now treated as a kind of "effective" dimension
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 18 Jul 2002 19:24:33 +0000 (19:24 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 18 Jul 2002 19:24:33 +0000 (19:24 +0000)
  with respect to contractions; this allows for a limited support of subspaces,
  e.g. delta.i[2].j[2] * a.i[3] -> a.j[2] by simplify_indexed(), and
  delta.i[2].i[3] -> 2. Likewise, eta~mu[3]~nu[3] * eta.mu[4].nu[4] -> 3 etc.
  (The numbers in brackets are the index dimensions which are not visible
  in the output.)
  Symbolic ("N", "D", ...) dimensions are always assumed to be higher than
  numeric ones.
- eps0123 is gone, dirac_trace() generates ordinary epsilon tensors with
  4-dimensional indices.

check/exam_clifford.cpp
ginac/clifford.cpp
ginac/idx.cpp
ginac/tensor.cpp
ginac/tensor.h

index 2dae18f..73aa132 100644 (file)
@@ -156,7 +156,7 @@ static unsigned clifford_check3(void)
          + dim * dirac_gamma5() * dirac_gamma(nu) * dirac_gamma(rho) * dirac_gamma(sig) * dirac_gamma(kap);
        e = dirac_trace(e).simplify_indexed();
        e = (e / (dim - 4)).normal();
-       result += check_equal(e, 8 * I * eps0123(nu, rho, sig, kap));
+       result += check_equal(e, 8 * I * lorentz_eps(nu.replace_dim(4), rho.replace_dim(4), sig.replace_dim(4), kap.replace_dim(4)));
 
        // one-loop vacuum polarization in QED
        e = dirac_gamma(mu) *
index 86678ec..1b3d034 100644 (file)
@@ -501,17 +501,19 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                                return _ex0;
 
                        // Tr gamma5 gamma.mu gamma.nu gamma.rho gamma.sigma = 4I * epsilon(mu, nu, rho, sigma)
+                       // (the epsilon is always 4-dimensional)
                        if (num == 5) {
                                ex b1, i1, b2, i2, b3, i3, b4, i4;
                                base_and_index(e.op(1), b1, i1);
                                base_and_index(e.op(2), b2, i2);
                                base_and_index(e.op(3), b3, i3);
                                base_and_index(e.op(4), b4, i4);
-                               return trONE * I * (eps0123(i1, i2, i3, i4) * b1 * b2 * b3 * b4).simplify_indexed();
+                               return trONE * I * (lorentz_eps(ex_to<idx>(i1).replace_dim(_ex4), ex_to<idx>(i2).replace_dim(_ex4), ex_to<idx>(i3).replace_dim(_ex4), ex_to<idx>(i4).replace_dim(_ex4)) * b1 * b2 * b3 * b4).simplify_indexed();
                        }
 
                        // Tr gamma5 S_2k =
                        //   I/4! * epsilon0123.mu1.mu2.mu3.mu4 * Tr gamma.mu1 gamma.mu2 gamma.mu3 gamma.mu4 S_2k
+                       // (the epsilon is always 4-dimensional)
                        exvector ix(num-1), bv(num-1);
                        for (unsigned i=1; i<num; i++)
                                base_and_index(e.op(i), bv[i-1], ix[i-1]);
@@ -536,7 +538,7 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                                                                v.push_back(ix[n]);
                                                        }
                                                        int sign = permutation_sign(iv, iv + num);
-                                                       result += sign * eps0123(idx1, idx2, idx3, idx4)
+                                                       result += sign * lorentz_eps(ex_to<idx>(idx1).replace_dim(_ex4), ex_to<idx>(idx2).replace_dim(_ex4), ex_to<idx>(idx3).replace_dim(_ex4), ex_to<idx>(idx4).replace_dim(_ex4))
                                                                * trace_string(v.begin(), num - 4);
                                                }
                                        }
index 6a9ac8a..63d2997 100644 (file)
@@ -409,7 +409,7 @@ bool idx::is_dummy_pair_same_type(const basic & other) const
        if (dim.is_equal(o.dim))
                return true;
 
-       return (dim < o.dim || dim > o.dim);
+       return (dim < o.dim || dim > o.dim || (is_a<numeric>(dim) && is_a<symbol>(o.dim)) || (is_a<symbol>(dim) && is_a<numeric>(o.dim)));
 }
 
 bool varidx::is_dummy_pair_same_type(const basic & other) const
@@ -449,9 +449,9 @@ ex idx::replace_dim(const ex & new_dim) const
 
 ex idx::minimal_dim(const idx & other) const
 {
-       if (dim.is_equal(other.dim) || dim < other.dim)
+       if (dim.is_equal(other.dim) || dim < other.dim || (is_a<numeric>(dim) && is_a<symbol>(other.dim)))
                return dim;
-       else if (dim > other.dim)
+       else if (dim > other.dim || (is_a<symbol>(dim) && is_a<numeric>(other.dim)))
                return other.dim;
        else
                throw (std::runtime_error("idx::minimal_dim: index dimensions cannot be ordered"));
index 48835ed..08c2ecc 100644 (file)
@@ -179,9 +179,14 @@ ex tensdelta::eval_indexed(const basic & i) const
        const idx & i1 = ex_to<idx>(i.op(1));
        const idx & i2 = ex_to<idx>(i.op(2));
 
-       // Trace of delta tensor is the dimension of the space
-       if (is_dummy_pair(i1, i2))
-               return i1.get_dim();
+       // Trace of delta tensor is the (effective) dimension of the space
+       if (is_dummy_pair(i1, i2)) {
+               try {
+                       return i1.minimal_dim(i2);
+               } catch (std::exception &e) {
+                       return i.hold();
+               }
+       }
 
        // Numeric evaluation
        if (static_cast<const indexed &>(i).all_index_values_are(info_flags::integer)) {
@@ -333,9 +338,15 @@ again:
 
                                // Contraction found, remove this tensor and substitute the
                                // index in the second object
-                               *self = _ex1;
-                               *other = other->subs(other_idx == *free_idx);
-                               return true;
+                               try {
+                                       // minimal_dim() throws an exception when index dimensions are not comparable
+                                       ex min_dim = self_idx->minimal_dim(other_idx);
+                                       *self = _ex1;
+                                       *other = other->subs(other_idx == free_idx->replace_dim(min_dim));
+                                       return true;
+                               } catch (std::exception &e) {
+                                       return false;
+                               }
                        }
                }
        }
@@ -578,16 +589,4 @@ ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool
        return indexed(tensepsilon(true, pos_sig), sy_anti(), i1, i2, i3, i4);
 }
 
-ex eps0123(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig)
-{
-       if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
-               throw(std::invalid_argument("indices of epsilon tensor must be of type varidx"));
-
-       ex dim = ex_to<idx>(i1).get_dim();
-       if (dim.is_equal(4))
-               return lorentz_eps(i1, i2, i3, i4, pos_sig);
-       else
-               return indexed(tensepsilon(true, pos_sig), sy_anti(), i1, i2, i3, i4);
-}
-
 } // namespace GiNaC
index 9b19dc1..3fae6b4 100644 (file)
@@ -213,18 +213,6 @@ ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3);
  *  @return newly constructed epsilon tensor */
 ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig = false);
 
-/** Create an epsilon tensor in a 4-dimensional projection of a D-dimensional
- *  Minkowski space. It vanishes whenever one of the indices is not in the
- *  set {0, 1, 2, 3}.
- *
- *  @param i1 First index
- *  @param i2 Second index
- *  @param i3 Third index
- *  @param i4 Fourth index
- *  @param pos_sig Whether the signature of the metric is positive
- *  @return newly constructed epsilon tensor */
-ex eps0123(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig = false);
-
 } // namespace GiNaC
 
 #endif // ndef __GINAC_TENSOR_H__