X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fexpairseq.cpp;h=fe8b86e803099a7add5b7b970a068834caf578f5;hb=67111f007a38497508b72603408b8f59a8e110a5;hp=67099f5796395e7d012fb1d4a13484278675e800;hpb=1b8bcb068171ce9d5c8202ae3c76647b65c9a06d;p=ginac.git diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 67099f57..fe8b86e8 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -3,7 +3,7 @@ * Implementation of sequences of expression pairs. */ /* - * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2020 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 @@ -32,10 +32,12 @@ #include "utils.h" #include "hash_seed.h" #include "indexed.h" +#include "compiler.h" #include #include #include +#include #include #include @@ -110,17 +112,15 @@ expairseq::expairseq(epvector && vp, const ex &oc, bool do_index_renaming) void expairseq::read_archive(const archive_node &n, lst &sym_lst) { inherited::read_archive(n, sym_lst); - auto first = n.find_first("rest"); - auto last = n.find_last("coeff"); - ++last; - seq.reserve((last-first)/2); + auto range = n.find_property_range("rest", "coeff"); + seq.reserve((range.end-range.begin)/2); - for (auto loc = first; loc < last;) { + for (auto loc = range.begin; loc < range.end;) { ex rest; ex coeff; n.find_ex_by_loc(loc++, rest, sym_lst); n.find_ex_by_loc(loc++, coeff, sym_lst); - seq.push_back(expair(rest, coeff)); + seq.emplace_back(expair(rest, coeff)); } n.find_ex("overall_coeff", overall_coeff, sym_lst); @@ -237,14 +237,14 @@ ex expairseq::map(map_function &f) const } /** Perform coefficient-wise automatic term rewriting rules in this class. */ -ex expairseq::eval(int level) const +ex expairseq::eval() const { - if ((level==1) && (flags &status_flags::evaluated)) + if (flags &status_flags::evaluated) return *this; - epvector evaled = evalchildren(level); + const epvector evaled = evalchildren(); if (!evaled.empty()) - return (new expairseq(std::move(evaled), overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated); + return dynallocate(std::move(evaled), overall_coeff).setflag(status_flags::evaluated); else return this->hold(); } @@ -263,7 +263,7 @@ epvector* conjugateepvector(const epvector&epv) } newepv = new epvector; newepv->reserve(epv.size()); - for (epvector::const_iterator j=epv.begin(); j!=i; ++j) { + for (auto j=epv.begin(); j!=i; ++j) { newepv->push_back(*j); } newepv->push_back(x); @@ -558,11 +558,16 @@ expair expairseq::combine_pair_with_coeff_to_pair(const expair &p, * @see expairseq::split_ex_to_pair() */ ex expairseq::recombine_pair_to_ex(const expair &p) const { - return lst(p.rest,p.coeff); + return lst{p.rest, p.coeff}; } bool expairseq::expair_needs_further_processing(epp it) { + if (is_exactly_a(it->rest) && + it->coeff.is_equal(_ex1)) { + // the pair {, 1} has yet to be absorbed into overall_coeff + return true; + } return false; } @@ -597,19 +602,11 @@ bool expairseq::can_make_flat(const expair &p) const // non-virtual functions in this class ////////// -void expairseq::construct_from_2_ex_via_exvector(const ex &lh, const ex &rh) -{ - exvector v; - v.reserve(2); - v.push_back(lh); - v.push_back(rh); - construct_from_exvector(v); -} - void expairseq::construct_from_2_ex(const ex &lh, const ex &rh) { - if (typeid(ex_to(lh)) == typeid(*this)) { - if (typeid(ex_to(rh)) == typeid(*this)) { + const std::type_info& typeid_this = typeid(*this); + if (typeid(ex_to(lh)) == typeid_this) { + if (typeid(ex_to(rh)) == typeid_this) { if (is_a(lh) && lh.info(info_flags::has_indices) && rh.info(info_flags::has_indices)) { ex newrh=rename_dummy_indices_uniquely(lh, rh); @@ -624,7 +621,7 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh) construct_from_expairseq_ex(ex_to(lh), rh); return; } - } else if (typeid(ex_to(rh)) == typeid(*this)) { + } else if (typeid(ex_to(rh)) == typeid_this) { construct_from_expairseq_ex(ex_to(rh),lh); return; } @@ -714,8 +711,8 @@ void expairseq::construct_from_2_expairseq(const expairseq &s1, } if (needs_further_processing) { - epvector v = seq; - seq.clear(); + // Clear seq and start over. + epvector v = std::move(seq); construct_from_epvector(std::move(v)); } } @@ -775,8 +772,8 @@ void expairseq::construct_from_expairseq_ex(const expairseq &s, } if (needs_further_processing) { - epvector v = seq; - seq.clear(); + // Clear seq and start over. + epvector v = std::move(seq); construct_from_epvector(std::move(v)); } } @@ -826,9 +823,10 @@ void expairseq::make_flat(const exvector &v) int nexpairseqs = 0; int noperands = 0; bool do_idx_rename = false; - + + const std::type_info& typeid_this = typeid(*this); for (auto & cit : v) { - if (typeid(ex_to(cit)) == typeid(*this)) { + if (typeid(ex_to(cit)) == typeid_this) { ++nexpairseqs; noperands += ex_to(cit).seq.size(); } @@ -843,7 +841,7 @@ void expairseq::make_flat(const exvector &v) // copy elements and split off numerical part make_flat_inserter mf(v, do_idx_rename); for (auto & cit : v) { - if (typeid(ex_to(cit)) == typeid(*this)) { + if (typeid(ex_to(cit)) == typeid_this) { ex newfactor = mf.handle_factor(cit, _ex1); const expairseq &subseqref = ex_to(newfactor); combine_overall_coeff(subseqref.overall_coeff); @@ -870,9 +868,10 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) int nexpairseqs = 0; int noperands = 0; bool really_need_rename_inds = false; - + + const std::type_info& typeid_this = typeid(*this); for (auto & cit : v) { - if (typeid(ex_to(cit.rest)) == typeid(*this)) { + if (typeid(ex_to(cit.rest)) == typeid_this) { ++nexpairseqs; noperands += ex_to(cit.rest).seq.size(); } @@ -888,12 +887,11 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) // copy elements and split off numerical part for (auto & cit : v) { - if (typeid(ex_to(cit.rest)) == typeid(*this) && + if (typeid(ex_to(cit.rest)) == typeid_this && this->can_make_flat(cit)) { ex newrest = mf.handle_factor(cit.rest, cit.coeff); const expairseq &subseqref = ex_to(newrest); - combine_overall_coeff(ex_to(subseqref.overall_coeff), - ex_to(cit.coeff)); + combine_overall_coeff(subseqref.overall_coeff, cit.coeff); for (auto & cit_s : subseqref.seq) { seq.push_back(expair(cit_s.rest, ex_to(cit_s.coeff).mul_dyn(ex_to(cit.coeff)))); @@ -963,8 +961,8 @@ void expairseq::combine_same_terms_sorted_seq() seq.erase(itout,last); if (needs_further_processing) { - epvector v = seq; - seq.clear(); + // Clear seq and start over. + epvector v = std::move(seq); construct_from_epvector(std::move(v)); } } @@ -1012,7 +1010,7 @@ epvector expairseq::expandchildren(unsigned options) const { auto cit = seq.begin(), last = seq.end(); while (cit!=last) { - const ex &expanded_ex = cit->rest.expand(options); + const ex expanded_ex = cit->rest.expand(options); if (!are_ex_trivially_equal(cit->rest,expanded_ex)) { // something changed, copy seq, eval and return it @@ -1020,25 +1018,20 @@ epvector expairseq::expandchildren(unsigned options) const s.reserve(seq.size()); // copy parts of seq which are known not to have changed - auto cit2 = seq.begin(); - while (cit2!=cit) { - s.push_back(*cit2); - ++cit2; - } + s.insert(s.begin(), seq.begin(), cit); // copy first changed element - s.push_back(combine_ex_with_coeff_to_pair(expanded_ex, - cit2->coeff)); - ++cit2; + s.push_back(expair(expanded_ex, cit->coeff)); + ++cit; // copy rest - while (cit2!=last) { - s.push_back(combine_ex_with_coeff_to_pair(cit2->rest.expand(options), - cit2->coeff)); - ++cit2; + while (cit != last) { + s.push_back(expair(cit->rest.expand(options), cit->coeff)); + ++cit; } return s; } + ++cit; } @@ -1051,44 +1044,32 @@ epvector expairseq::expandchildren(unsigned options) const * @see expairseq::eval() * @return epvector containing evaluated pairs, empty if no members * had to be changed. */ -epvector expairseq::evalchildren(int level) const +epvector expairseq::evalchildren() const { - if (level==1) - return epvector(); // nothing had to be evaluated - - if (level == -max_recursion_level) - throw(std::runtime_error("max recursion level reached")); - - --level; auto cit = seq.begin(), last = seq.end(); while (cit!=last) { - const ex evaled_ex = cit->rest.eval(level); - if (!are_ex_trivially_equal(cit->rest,evaled_ex)) { - - // something changed, copy seq, eval and return it + const expair evaled_pair = combine_ex_with_coeff_to_pair(cit->rest, cit->coeff); + if (unlikely(!evaled_pair.is_equal(*cit))) { + + // something changed: copy seq, eval and return it epvector s; s.reserve(seq.size()); - + // copy parts of seq which are known not to have changed - auto cit2 = seq.begin(); - while (cit2!=cit) { - s.push_back(*cit2); - ++cit2; - } + s.insert(s.begin(), seq.begin(), cit); // copy first changed element - s.push_back(combine_ex_with_coeff_to_pair(evaled_ex, - cit2->coeff)); - ++cit2; + s.push_back(evaled_pair); + ++cit; // copy rest - while (cit2!=last) { - s.push_back(combine_ex_with_coeff_to_pair(cit2->rest.eval(level), - cit2->coeff)); - ++cit2; + while (cit != last) { + s.push_back(combine_ex_with_coeff_to_pair(cit->rest, cit->coeff)); + ++cit; } - return std::move(s); + return s; } + ++cit; } @@ -1128,7 +1109,7 @@ epvector expairseq::subschildren(const exmap & m, unsigned options) const const ex &subsed_ex = orig_ex.subs(m, options); if (!are_ex_trivially_equal(orig_ex, subsed_ex)) { - // Something changed, copy seq, subs and return it + // Something changed: copy seq, subs and return it epvector s; s.reserve(seq.size()); @@ -1156,10 +1137,11 @@ epvector expairseq::subschildren(const exmap & m, unsigned options) const auto cit = seq.begin(), last = seq.end(); while (cit != last) { - const ex &subsed_ex = cit->rest.subs(m, options); - if (!are_ex_trivially_equal(cit->rest, subsed_ex)) { + const ex subsed_rest = cit->rest.subs(m, options); + const expair subsed_pair = combine_ex_with_coeff_to_pair(subsed_rest, cit->coeff); + if (!subsed_pair.is_equal(*cit)) { - // Something changed, copy seq, subs and return it + // Something changed: copy seq, subs and return it epvector s; s.reserve(seq.size()); @@ -1167,7 +1149,7 @@ epvector expairseq::subschildren(const exmap & m, unsigned options) const s.insert(s.begin(), seq.begin(), cit); // Copy first changed element - s.push_back(combine_ex_with_coeff_to_pair(subsed_ex, cit->coeff)); + s.push_back(subsed_pair); ++cit; // Copy rest