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)) {
const varidx & i1 = ex_to<varidx>(i.op(1));
const varidx & i2 = ex_to<varidx>(i.op(2));
+ // The dimension of the indices must be equal, otherwise we use the minimal
+ // dimension
+ if (!i1.get_dim().is_equal(i2.get_dim())) {
+ ex min_dim = i1.minimal_dim(i2);
+ return i.subs(lst(i1 == i1.replace_dim(min_dim), i2 == i2.replace_dim(min_dim)));
+ }
+
// A metric tensor with one covariant and one contravariant index gets
// replaced by a delta tensor
if (i1.is_covariant() != i2.is_covariant())
// 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;
+ }
}
}
}
{
if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx))
throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
- ex dim = ex_to<idx>(i1).get_dim();
- if (!dim.is_equal(ex_to<idx>(i2).get_dim()))
- throw(std::invalid_argument("all indices of metric tensor must have the same dimension"));
return indexed(tensmetric(), sy_symm(), i1, i2);
}
{
if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx))
throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
- ex dim = ex_to<idx>(i1).get_dim();
- if (!dim.is_equal(ex_to<idx>(i2).get_dim()))
- throw(std::invalid_argument("all indices of metric tensor must have the same dimension"));
return indexed(minkmetric(pos_sig), sy_symm(), i1, i2);
}
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