X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;ds=sidebyside;f=ginac%2Findexed.cpp;h=873a9ad0b9661d721f14d09439ab8256661b7260;hb=e0a84a395ab1bf84813eea95fde9c8a361dae9bc;hp=01fc985bb60805bb4cc1f961ae8faff42d4f3965;hpb=d327f3f00c66a79d42855939866047b3e8caa630;p=ginac.git diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index 01fc985b..873a9ad0 100644 --- a/ginac/indexed.cpp +++ b/ginac/indexed.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's indexed expressions. */ /* - * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,11 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include -#include - #include "indexed.h" #include "idx.h" #include "add.h" @@ -42,6 +37,11 @@ #include "matrix.h" #include "inifcns.h" +#include +#include +#include +#include + namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(indexed, exprseq, @@ -648,7 +648,7 @@ bool reposition_dummy_indices(ex & e, exvector & variant_dummy_indices, exvector } // In the case where a dummy symbol occurs twice in the same indexed object - // we try all posibilities of raising/lowering and keep the least one in + // we try all possibilities of raising/lowering and keep the least one in // the sense of ex_is_less. ex optimal_e = e; size_t numpossibs = 1 << local_var_dummies.size(); @@ -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 @@ -872,8 +874,16 @@ contraction_done: // Non-commutative products are always re-expanded to give // eval_ncmul() the chance to re-order and canonicalize // the product + bool is_a_product = (is_exactly_a(*it1) || is_exactly_a(*it1)) && + (is_exactly_a(*it2) || is_exactly_a(*it2)); ex r = (non_commutative ? ex(ncmul(v, true)) : ex(mul(v))); - return simplify_indexed(r, free_indices, dummy_indices, sp); + + // If new expression is a product we can call this function again, + // otherwise we need to pass argument to simplify_indexed() to be expanded + if (is_a_product) + return simplify_indexed_product(r, free_indices, dummy_indices, sp); + else + return simplify_indexed(r, free_indices, dummy_indices, sp); } // Both objects may have new indices now or they might @@ -882,6 +892,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 +950,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 @@ -971,7 +988,7 @@ public: terminfo(const ex & orig_, const ex & symm_) : orig(orig_), symm(symm_) {} ex orig; /**< original term */ - ex symm; /**< symmtrized term */ + ex symm; /**< symmetrized term */ }; class terminfo_is_less {