index 48835ed5b0161b3f88b9d6a21776fc6c96c90817..0c36a68002423d712f4d8afa5ec903716ffba7e7 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)) {
@@ -208,6 +213,13 @@ ex tensmetric::eval_indexed(const basic & i) const
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())
@@ -333,9 +345,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;
+                               }
}
}
}
@@ -508,9 +526,6 @@ ex metric_tensor(const ex & i1, const ex & 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(tensmetric(), sy_symm(), i1, i2);
}
@@ -519,9 +534,6 @@ ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig)
{
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);
}
@@ -578,16 +590,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