From 56bbb99adc43dad22ee615380d4446a87b713cb8 Mon Sep 17 00:00:00 2001 From: Jens Vollinga Date: Sat, 21 May 2011 01:30:08 +0200 Subject: [PATCH] Limiting the costly symmetrization tests inside simplify_indexed() to cases where at least one antisymmetric or cyclic non-free index is involved. Thanks to P.G.Clark for reporting the problem. --- ginac/indexed.cpp | 37 +++++++++++++++++++++++-------------- ginac/symmetry.cpp | 12 ++++++++++++ ginac/symmetry.h | 2 ++ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index b59240e0..b85c3869 100644 --- a/ginac/indexed.cpp +++ b/ginac/indexed.cpp @@ -797,6 +797,7 @@ ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & du // Perform contractions bool something_changed = false; + bool has_nonsymmetric = false; GINAC_ASSERT(v.size() > 1); exvector::iterator it1, itend = v.end(), next_to_last = itend - 1; for (it1 = v.begin(); it1 != next_to_last; it1++) { @@ -806,6 +807,7 @@ try_again: continue; bool first_noncommutative = (it1->return_type() != return_types::commutative); + bool first_nonsymmetric = ex_to(ex_to(*it1).get_symmetry()).has_nonsymmetric(); // Indexed factor found, get free indices and look for contraction // candidates @@ -882,6 +884,11 @@ contraction_done: something_changed = true; goto try_again; } + else if (!has_nonsymmetric && + (first_nonsymmetric || + ex_to(ex_to(*it2).get_symmetry()).has_nonsymmetric())) { + has_nonsymmetric = true; + } } } @@ -935,20 +942,22 @@ contraction_done: // The result should be symmetric with respect to exchange of dummy // indices, so if the symmetrization vanishes, the whole expression is // zero. This detects things like eps.i.j.k * p.j * p.k = 0. - ex q = idx_symmetrization(r, local_dummy_indices); - if (q.is_zero()) { - free_indices.clear(); - return _ex0; - } - q = idx_symmetrization(q, local_dummy_indices); - if (q.is_zero()) { - free_indices.clear(); - return _ex0; - } - q = idx_symmetrization(q, local_dummy_indices); - if (q.is_zero()) { - free_indices.clear(); - return _ex0; + if (has_nonsymmetric) { + ex q = idx_symmetrization(r, local_dummy_indices); + if (q.is_zero()) { + free_indices.clear(); + return _ex0; + } + q = idx_symmetrization(q, local_dummy_indices); + if (q.is_zero()) { + free_indices.clear(); + return _ex0; + } + q = idx_symmetrization(q, local_dummy_indices); + if (q.is_zero()) { + free_indices.clear(); + return _ex0; + } } // Dummy index renaming diff --git a/ginac/symmetry.cpp b/ginac/symmetry.cpp index d93e34cb..a44cfcc5 100644 --- a/ginac/symmetry.cpp +++ b/ginac/symmetry.cpp @@ -270,6 +270,18 @@ void symmetry::do_print_tree(const print_tree & c, unsigned level) const // non-virtual functions in this class ////////// +bool symmetry::has_nonsymmetric() const +{ + if (type == antisymmetric || type == cyclic) + return true; + + for (exvector::const_iterator i=children.begin(); i!=children.end(); ++i) + if (ex_to(*i).has_nonsymmetric()) + return true; + + return false; +} + bool symmetry::has_cyclic() const { if (type == cyclic) diff --git a/ginac/symmetry.h b/ginac/symmetry.h index 54a2cb82..fa897be9 100644 --- a/ginac/symmetry.h +++ b/ginac/symmetry.h @@ -80,6 +80,8 @@ public: /** Check whether this node actually represents any kind of symmetry. */ bool has_symmetry() const {return type != none || !children.empty(); } + /** Check whether this node involves anything non symmetric. */ + bool has_nonsymmetric() const; /** Check whether this node involves a cyclic symmetry. */ bool has_cyclic() const; -- 2.44.0