X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fexpairseq.cpp;h=3ed9e2892a23040c8bbb8e2ce4bf3ebfed36705f;hp=8e9594b6e312b640775ad59fd8d0cb8e66b8592a;hb=581244b7b8fc9b5f81291e1a3f5731939e3f3d8e;hpb=4cf53676d7823ec3c55a90df7723f7f1492a95b2 diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 8e9594b6..3ed9e289 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -3,7 +3,7 @@ * Implementation of sequences of expression pairs. */ /* - * GiNaC Copyright (C) 1999-2006 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2008 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 @@ -24,6 +24,7 @@ #include #include #include +#include #include "expairseq.h" #include "lst.h" @@ -145,13 +146,17 @@ expairseq::expairseq(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst , hashtabsize(0) #endif { - for (unsigned int i=0; true; i++) { + archive_node::archive_node_cit first = n.find_first("rest"); + archive_node::archive_node_cit last = n.find_last("coeff"); + ++last; + seq.reserve((last-first)/2); + + for (archive_node::archive_node_cit loc = first; loc < last;) { ex rest; ex coeff; - if (n.find_ex("rest", rest, sym_lst, i) && n.find_ex("coeff", coeff, sym_lst, i)) - seq.push_back(expair(rest, coeff)); - else - break; + n.find_ex_by_loc(loc++, rest, sym_lst); + n.find_ex_by_loc(loc++, coeff, sym_lst); + seq.push_back(expair(rest, coeff)); } n.find_ex("overall_coeff", overall_coeff, sym_lst); @@ -263,6 +268,26 @@ void expairseq::do_print_tree(const print_tree & c, unsigned level) const bool expairseq::info(unsigned inf) const { + switch(inf) { + case info_flags::expanded: + return (flags & status_flags::expanded); + case info_flags::has_indices: { + if (flags & status_flags::has_indices) + return true; + else if (flags & status_flags::has_no_indices) + return false; + for (epvector::const_iterator i = seq.begin(); i != seq.end(); ++i) { + if (i->rest.info(info_flags::has_indices)) { + this->setflag(status_flags::has_indices); + this->clearflag(status_flags::has_no_indices); + return true; + } + } + this->clearflag(status_flags::has_indices); + this->setflag(status_flags::has_no_indices); + return false; + } + } return inherited::info(inf); } @@ -285,7 +310,7 @@ ex expairseq::op(size_t i) const ex expairseq::map(map_function &f) const { std::auto_ptr v(new epvector); - v->reserve(seq.size()); + v->reserve(seq.size()+1); epvector::const_iterator cit = seq.begin(), last = seq.end(); while (cit != last) { @@ -295,8 +320,15 @@ ex expairseq::map(map_function &f) const if (overall_coeff.is_equal(default_overall_coeff())) return thisexpairseq(v, default_overall_coeff(), true); - else - return thisexpairseq(v, f(overall_coeff), true); + else { + ex newcoeff = f(overall_coeff); + if(is_a(newcoeff)) + return thisexpairseq(v, newcoeff, true); + else { + v->push_back(split_ex_to_pair(newcoeff)); + return thisexpairseq(v, default_overall_coeff(), true); + } + } } /** Perform coefficient-wise automatic term rewriting rules in this class. */ @@ -780,8 +812,8 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh) construct_from_2_ex_via_exvector(lh,rh); } else { #endif // EXPAIRSEQ_USE_HASHTAB - if(is_a(lh)) - { + if (is_a(lh) && lh.info(info_flags::has_indices) && + rh.info(info_flags::has_indices)) { ex newrh=rename_dummy_indices_uniquely(lh, rh); construct_from_2_expairseq(ex_to(lh), ex_to(newrh)); @@ -1015,61 +1047,6 @@ void expairseq::construct_from_epvector(const epvector &v, bool do_index_renamin #endif // EXPAIRSEQ_USE_HASHTAB } -// Class to handle the renaming of dummy indices. It holds a vector of -// indices that are being used in the expression so-far. If the same -// index occurs again as a dummy index in a factor, it is to be renamed. -// Unless dummy index renaming was swichted of, of course ;-) . -class make_flat_inserter -{ - public: - make_flat_inserter(const epvector &epv, bool b): do_renaming(b) - { - if (!do_renaming) - return; - for (epvector::const_iterator i=epv.begin(); i!=epv.end(); ++i) - if(are_ex_trivially_equal(i->coeff, _ex1)) - combine_indices(i->rest.get_free_indices()); - } - make_flat_inserter(const exvector &v, bool b): do_renaming(b) - { - if (!do_renaming) - return; - for (exvector::const_iterator i=v.begin(); i!=v.end(); ++i) - combine_indices(i->get_free_indices()); - } - ex handle_factor(const ex &x, const ex &coeff) - { - if (!do_renaming) - return x; - exvector dummies_of_factor; - if (coeff == _ex1) - dummies_of_factor = get_all_dummy_indices_safely(x); - else if (coeff == _ex2) - dummies_of_factor = x.get_free_indices(); - else - return x; - if (dummies_of_factor.size() == 0) - return x; - sort(dummies_of_factor.begin(), dummies_of_factor.end(), ex_is_less()); - ex new_factor = rename_dummy_indices_uniquely(used_indices, - dummies_of_factor, x); - combine_indices(dummies_of_factor); - return new_factor; - } - private: - void combine_indices(const exvector &dummies_of_factor) - { - exvector new_dummy_indices; - set_union(used_indices.begin(), used_indices.end(), - dummies_of_factor.begin(), dummies_of_factor.end(), - std::back_insert_iterator(new_dummy_indices), ex_is_less()); - used_indices.swap(new_dummy_indices); - } - bool do_renaming; - exvector used_indices; -}; - - /** Combine this expairseq with argument exvector. * It cares for associativity as well as for special handling of numerics. */ void expairseq::make_flat(const exvector &v) @@ -1080,6 +1057,7 @@ void expairseq::make_flat(const exvector &v) // and their cumulative number of operands int nexpairseqs = 0; int noperands = 0; + bool do_idx_rename = false; cit = v.begin(); while (cit!=v.end()) { @@ -1087,6 +1065,9 @@ void expairseq::make_flat(const exvector &v) ++nexpairseqs; noperands += ex_to(*cit).seq.size(); } + if (is_a(*this) && (!do_idx_rename) && + cit->info(info_flags::has_indices)) + do_idx_rename = true; ++cit; } @@ -1094,7 +1075,7 @@ void expairseq::make_flat(const exvector &v) seq.reserve(v.size()+noperands-nexpairseqs); // copy elements and split off numerical part - make_flat_inserter mf(v, this->tinfo()==&mul::tinfo_static); + make_flat_inserter mf(v, do_idx_rename); cit = v.begin(); while (cit!=v.end()) { if (ex_to(*cit).tinfo()==this->tinfo()) { @@ -1128,6 +1109,7 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) // and their cumulative number of operands int nexpairseqs = 0; int noperands = 0; + bool really_need_rename_inds = false; cit = v.begin(); while (cit!=v.end()) { @@ -1135,8 +1117,12 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) ++nexpairseqs; noperands += ex_to(cit->rest).seq.size(); } + if ((!really_need_rename_inds) && is_a(*this) && + cit->rest.info(info_flags::has_indices)) + really_need_rename_inds = true; ++cit; } + do_index_renaming = do_index_renaming && really_need_rename_inds; // reserve seq and coeffseq which will hold all operands seq.reserve(v.size()+noperands-nexpairseqs);