+ 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) *
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]);
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);
}
}
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
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"));
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)) {
// 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;
+ }
}
}
}
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
* @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__