GINAC_ASSERT(self->nops() == 4);
GINAC_ASSERT(is_ex_of_type(self->op(0), su3d));
- if (is_ex_exactly_of_type(other->op(0), su3d) || is_ex_exactly_of_type(other->op(0), su3f)) {
+ if (is_ex_exactly_of_type(other->op(0), su3d)) {
// Find the dummy indices of the contraction
exvector dummy_indices;
dummy_indices = ex_to_indexed(*self).get_dummy_indices(ex_to_indexed(*other));
- if (is_ex_exactly_of_type(other->op(0), su3d)) {
-
- // d.abc*d.abc=40/3
- if (dummy_indices.size() == 3) {
- *self = numeric(40, 3);
- *other = _ex1();
- return true;
-
- // d.akl*d.bkl=5/3*delta.ab
- } else if (dummy_indices.size() == 2) {
- exvector a = index_set_difference(ex_to_indexed(*self).get_indices(), dummy_indices);
- exvector b = index_set_difference(ex_to_indexed(*other).get_indices(), dummy_indices);
- GINAC_ASSERT(a.size() > 0);
- GINAC_ASSERT(b.size() > 0);
- *self = numeric(5, 3) * delta_tensor(a[0], b[0]);
- *other = _ex1();
- return true;
- }
-
- } else {
-
- // d.akl*f.bkl=0 (includes the case a=b)
- if (dummy_indices.size() >= 2) {
- *self = _ex0();
- *other = _ex0();
- return true;
- }
+ // d.abc*d.abc=40/3
+ if (dummy_indices.size() == 3) {
+ *self = numeric(40, 3);
+ *other = _ex1();
+ return true;
+
+ // d.akl*d.bkl=5/3*delta.ab
+ } else if (dummy_indices.size() == 2) {
+ exvector a = index_set_difference(ex_to_indexed(*self).get_indices(), dummy_indices);
+ exvector b = index_set_difference(ex_to_indexed(*other).get_indices(), dummy_indices);
+ GINAC_ASSERT(a.size() > 0);
+ GINAC_ASSERT(b.size() > 0);
+ *self = numeric(5, 3) * delta_tensor(a[0], b[0]);
+ *other = _ex1();
+ return true;
}
}
if (!is_ex_of_type(*it1, indexed))
continue;
- // Indexed factor found, look for contraction candidates
+ // Indexed factor found, get free indices and look for contraction
+ // candidates
+ exvector free1, dummy1;
+ find_free_and_dummy(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end(), free1, dummy1);
+
exvector::iterator it2;
for (it2 = it1 + 1; it2 != itend; it2++) {
if (!is_ex_of_type(*it2, indexed))
continue;
+ // Find free indices of second factor and merge them with free
+ // indices of first factor
+ exvector un;
+ find_free_and_dummy(ex_to_indexed(*it2).seq.begin() + 1, ex_to_indexed(*it2).seq.end(), un, dummy1);
+ un.insert(un.end(), free1.begin(), free1.end());
+
// Check whether the two factors share dummy indices
- exvector un(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end());
- un.insert(un.end(), ex_to_indexed(*it2).seq.begin() + 1, ex_to_indexed(*it2).seq.end());
exvector free, dummy;
find_free_and_dummy(un, free, dummy);
if (dummy.size() == 0)
// If contracting with the delta tensor, let the delta do it
// (don't raise/lower delta indices)
- if (is_ex_exactly_of_type(other->op(0), tensdelta))
+ if (is_ex_of_type(other->op(0), tensdelta))
return false;
// Try to contract first index