X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fexpairseq.cpp;h=7dc55824e52f4252377d27386d70877f7ca927d8;hb=9ada7a7f5c47e512b7bf6057d4c013612be9a33b;hp=72848364ae17de1b69f14393bd3ddd45584b5b63;hpb=1602530f716ba1d425a0667b897182b99c374823;p=ginac.git diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 72848364..7dc55824 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -3,7 +3,7 @@ * Implementation of sequences of expression pairs. */ /* - * GiNaC Copyright (C) 1999-2009 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2011 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 @@ -30,6 +30,7 @@ #include "archive.h" #include "operators.h" #include "utils.h" +#include "hash_seed.h" #include "indexed.h" #include @@ -370,23 +371,10 @@ ex expairseq::conjugate() const return *this; } ex result = thisexpairseq(newepv ? *newepv : seq, x); - if (newepv) { - delete newepv; - } + delete newepv; return result; } -bool expairseq::is_polynomial(const ex & var) const -{ - if (!is_exactly_a(*this) && !is_exactly_a(*this)) - return basic::is_polynomial(var); - for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { - if (!(i->rest).is_polynomial(var)) - return false; - } - return true; -} - bool expairseq::match(const ex & pattern, exmap & repl_lst) const { // This differs from basic::match() because we want "a+b+c+d" to @@ -406,6 +394,12 @@ bool expairseq::match(const ex & pattern, exmap & repl_lst) const } } + // Even if the expression does not match the pattern, some of + // its subexpressions could match it. For example, x^5*y^(-1) + // does not match the pattern $0^5, but its subexpression x^5 + // does. So, save repl_lst in order to not add bogus entries. + exmap tmp_repl = repl_lst; + // Unfortunately, this is an O(N^2) operation because we can't // sort the pattern in a useful way... @@ -423,7 +417,7 @@ bool expairseq::match(const ex & pattern, exmap & repl_lst) const continue; exvector::iterator it = ops.begin(), itend = ops.end(); while (it != itend) { - if (it->match(p, repl_lst)) { + if (it->match(p, tmp_repl)) { ops.erase(it); goto found; } @@ -444,10 +438,16 @@ found: ; for (size_t i=0; ipush_back(split_ex_to_pair(ops[i])); ex rest = thisexpairseq(vp, default_overall_coeff()); - for (exmap::const_iterator it = repl_lst.begin(); it != repl_lst.end(); ++it) { - if (it->first.is_equal(global_wildcard)) - return rest.is_equal(it->second); + for (exmap::const_iterator it = tmp_repl.begin(); it != tmp_repl.end(); ++it) { + if (it->first.is_equal(global_wildcard)) { + if (rest.is_equal(it->second)) { + repl_lst = tmp_repl; + return true; + } + return false; + } } + repl_lst = tmp_repl; repl_lst[global_wildcard] = rest; return true; @@ -455,7 +455,11 @@ found: ; // No global wildcard, then the match fails if there are any // unmatched terms left - return ops.empty(); + if (ops.empty()) { + repl_lst = tmp_repl; + return true; + } + return false; } } return inherited::match(pattern, repl_lst); @@ -465,7 +469,7 @@ ex expairseq::subs(const exmap & m, unsigned options) const { std::auto_ptr vp = subschildren(m, options); if (vp.get()) - return ex_to(thisexpairseq(vp, overall_coeff, true)); + return ex_to(thisexpairseq(vp, overall_coeff, (options & subs_options::no_index_renaming) == 0)); else if ((options & subs_options::algebraic) && is_exactly_a(*this)) return static_cast(this)->algebraic_subs_mul(m, options); else @@ -611,8 +615,7 @@ unsigned expairseq::return_type() const unsigned expairseq::calchash() const { - const void* this_tinfo = (const void*)typeid(*this).name(); - unsigned v = golden_ratio_hash((p_int)this_tinfo); + unsigned v = make_hash_seed(typeid(*this)); epvector::const_iterator i = seq.begin(); const epvector::const_iterator end = seq.end(); while (i != end) { @@ -886,7 +889,7 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh) } void expairseq::construct_from_2_expairseq(const expairseq &s1, - const expairseq &s2) + const expairseq &s2) { combine_overall_coeff(s1.overall_coeff); combine_overall_coeff(s2.overall_coeff); @@ -941,7 +944,7 @@ void expairseq::construct_from_2_expairseq(const expairseq &s1, } void expairseq::construct_from_expairseq_ex(const expairseq &s, - const ex &e) + const ex &e) { combine_overall_coeff(s.overall_coeff); if (is_exactly_a(e)) { @@ -1006,7 +1009,7 @@ void expairseq::construct_from_exvector(const exvector &v) { // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity) // +(d,b,c,a) -> +(a,b,c,d) (canonicalization) - // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric()) + // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric) // (same for (+,*) -> (*,^) make_flat(v); @@ -1022,8 +1025,8 @@ void expairseq::construct_from_epvector(const epvector &v, bool do_index_renamin { // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity) // +(d,b,c,a) -> +(a,b,c,d) (canonicalization) - // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric()) - // (same for (+,*) -> (*,^) + // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric) + // same for (+,*) -> (*,^) make_flat(v, do_index_renaming); #if EXPAIRSEQ_USE_HASHTAB @@ -1445,7 +1448,7 @@ bool expairseq::has_coeff_0() const } void expairseq::add_numerics_to_hashtab(epvector::iterator first_numeric, - epvector::const_iterator last_non_zero) + epvector::const_iterator last_non_zero) { if (first_numeric == seq.end()) return; // no numerics