X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Findexed.cpp;h=b62e5d4dd917527556985d6c3bdc8e4773d6ebda;hb=c814fb2991fc9d44c7466da5bbf20e58c0f4238f;hp=8c5256aff33a1b88560c53ea9ab2a6fa0126bd5d;hpb=def26469ff96228c66e877bb5594e7d9a24b638f;p=ginac.git diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index 8c5256af..b62e5d4d 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, @@ -129,8 +129,9 @@ indexed::indexed(const symmetry & symm, std::auto_ptr vp) : inherited( // archiving ////////// -indexed::indexed(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) +void indexed::read_archive(const archive_node &n, lst &sym_lst) { + inherited::read_archive(n, sym_lst); if (!n.find_ex("symmetry", symtree, sym_lst)) { // GiNaC versions <= 0.9.0 had an unsigned "symmetry" property unsigned symm = 0; @@ -149,6 +150,7 @@ indexed::indexed(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) const_cast(ex_to(symtree)).validate(seq.size() - 1); } } +GINAC_BIND_UNARCHIVER(indexed); void indexed::archive(archive_node &n) const { @@ -156,8 +158,6 @@ void indexed::archive(archive_node &n) const n.add_ex("symmetry", symtree); } -DEFAULT_UNARCHIVE(indexed) - ////////// // functions overriding virtual functions from base classes ////////// @@ -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