#include "ncmul.h"
#include "power.h"
#include "lst.h"
+#include "inifcns.h"
#include "print.h"
#include "archive.h"
#include "utils.h"
return dummy_indices;
}
+bool indexed::has_dummy_index_for(const ex & i) const
+{
+ exvector::const_iterator it = seq.begin() + 1, itend = seq.end();
+ while (it != itend) {
+ if (is_dummy_pair(*it, i))
+ return true;
+ it++;
+ }
+ return false;
+}
+
exvector indexed::get_free_indices(void) const
{
exvector free_indices, dummy_indices;
if (!is_ex_of_type(*it1, indexed))
continue;
+ bool first_noncommutative = (it1->return_type() != return_types::commutative);
+
// Indexed factor found, get free indices and look for contraction
// candidates
exvector free1, dummy1;
if (!is_ex_of_type(*it2, indexed))
continue;
+ bool second_noncommutative = (it2->return_type() != return_types::commutative);
+
// Find free indices of second factor and merge them with free
// indices of first factor
exvector un;
}
if (contracted) {
contraction_done:
- if (non_commutative
+ if (first_noncommutative || second_noncommutative
|| is_ex_exactly_of_type(*it1, add) || is_ex_exactly_of_type(*it2, add)
|| is_ex_exactly_of_type(*it1, mul) || is_ex_exactly_of_type(*it2, mul)
|| is_ex_exactly_of_type(*it1, ncmul) || is_ex_exactly_of_type(*it2, ncmul)) {
// Non-commutative products are always re-expanded to give
// simplify_ncmul() the chance to re-order and canonicalize
// the product
- ex r = (non_commutative ? ex(ncmul(v)) : ex(mul(v)));
+ ex r = (non_commutative ? ex(ncmul(v, true)) : ex(mul(v)));
return simplify_indexed(r, free_indices, dummy_indices, sp);
}
ex r;
if (something_changed)
- r = non_commutative ? ex(ncmul(v)) : ex(mul(v));
+ r = non_commutative ? ex(ncmul(v, true)) : ex(mul(v));
else
r = e;
return simplify_indexed(e, free_indices, dummy_indices, sp);
}
+ex symmetrize(const ex & e)
+{
+ return symmetrize(e, e.get_free_indices());
+}
+
+ex antisymmetrize(const ex & e)
+{
+ return antisymmetrize(e, e.get_free_indices());
+}
+
//////////
// helper classes
//////////