Limiting the costly symmetrization tests inside simplify_indexed() to
authorJens Vollinga <jensv@nikhef.nl>
Fri, 20 May 2011 23:30:08 +0000 (01:30 +0200)
committerJens Vollinga <jensv@nikhef.nl>
Fri, 20 May 2011 23:30:08 +0000 (01:30 +0200)
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
ginac/symmetry.cpp
ginac/symmetry.h

index b59240e..b85c386 100644 (file)
@@ -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<symmetry>(ex_to<indexed>(*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<symmetry>(ex_to<indexed>(*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<idx>(r, local_dummy_indices);
-       if (q.is_zero()) {
-               free_indices.clear();
-               return _ex0;
-       }
-       q = idx_symmetrization<varidx>(q, local_dummy_indices);
-       if (q.is_zero()) {
-               free_indices.clear();
-               return _ex0;
-       }
-       q = idx_symmetrization<spinidx>(q, local_dummy_indices);
-       if (q.is_zero()) {
-               free_indices.clear();
-               return _ex0;
+       if (has_nonsymmetric) {
+               ex q = idx_symmetrization<idx>(r, local_dummy_indices);
+               if (q.is_zero()) {
+                       free_indices.clear();
+                       return _ex0;
+               }
+               q = idx_symmetrization<varidx>(q, local_dummy_indices);
+               if (q.is_zero()) {
+                       free_indices.clear();
+                       return _ex0;
+               }
+               q = idx_symmetrization<spinidx>(q, local_dummy_indices);
+               if (q.is_zero()) {
+                       free_indices.clear();
+                       return _ex0;
+               }
        }
 
        // Dummy index renaming
index d93e34c..a44cfcc 100644 (file)
@@ -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<symmetry>(*i).has_nonsymmetric())
+                       return true;
+
+       return false;
+}
+
 bool symmetry::has_cyclic() const
 {
        if (type == cyclic)
index 54a2cb8..fa897be 100644 (file)
@@ -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;