From: Christian Bauer Date: Mon, 21 Jul 2003 17:43:52 +0000 (+0000) Subject: - subs_no_pattern -> no_pattern, subs_algebraic -> algebraic X-Git-Tag: release_1-1-2~5 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=4da59ebf068ecfc6be232d6ce360ce6c02b5e393 - subs_no_pattern -> no_pattern, subs_algebraic -> algebraic - backported the expariseq::subschildren() optimization from 1.2 --- diff --git a/ginac/basic.cpp b/ginac/basic.cpp index bd19ab59..d5654e21 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -29,6 +29,7 @@ #include "basic.h" #include "ex.h" #include "numeric.h" +#include "mul.h" #include "power.h" #include "symbol.h" #include "lst.h" @@ -528,7 +529,7 @@ ex basic::subs(const lst & ls, const lst & lr, unsigned options) const lst::const_iterator its, itr; - if (options & subs_options::subs_no_pattern) { + if (options & subs_options::no_pattern) { for (its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) { if (is_equal(ex_to(*its))) return *itr; @@ -537,7 +538,7 @@ ex basic::subs(const lst & ls, const lst & lr, unsigned options) const for (its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) { lst repl_lst; if (match(ex_to(*its), repl_lst)) - return itr->subs(repl_lst, options | subs_options::subs_no_pattern); // avoid infinite recursion when re-substituting the wildcards + return itr->subs(repl_lst, options | subs_options::no_pattern); // avoid infinite recursion when re-substituting the wildcards } } @@ -723,9 +724,18 @@ ex basic::subs(const ex & e, unsigned options) const if (!r.info(info_flags::relation_equal)) { throw(std::invalid_argument("basic::subs(ex): argument must be a list of equations")); } - ls.append(r.op(0)); + const ex & s = r.op(0); + ls.append(s); lr.append(r.op(1)); + + // Search for products and powers in the expressions to be substituted + // (for an optimization in expairseq::subs()) + if (is_exactly_a(s) || is_exactly_a(s)) + options |= subs_options::pattern_is_product; } + if (!(options & subs_options::pattern_is_product)) + options |= subs_options::pattern_is_not_product; + return subs(ls, lr, options); } diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index d4dd3df1..df270bdc 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -405,7 +405,7 @@ ex expairseq::subs(const lst &ls, const lst &lr, unsigned options) const epvector *vp = subschildren(ls, lr, options); if (vp) return ex_to(thisexpairseq(vp, overall_coeff)); - else if ((options & subs_options::subs_algebraic) && is_exactly_a(*this)) + else if ((options & subs_options::algebraic) && is_exactly_a(*this)) return static_cast(this)->algebraic_subs_mul(ls, lr, options); else return basic::subs(ls, lr, options); @@ -1564,18 +1564,23 @@ epvector * expairseq::subschildren(const lst &ls, const lst &lr, unsigned option { GINAC_ASSERT(ls.nops()==lr.nops()); - // The substitution is "complex" when any of the objects to be substituted - // is a product or power. In this case we have to recombine the pairs - // because the numeric coefficients may be part of the search pattern. - bool complex_subs = false; - for (lst::const_iterator it = ls.begin(); it != ls.end(); ++it) { - if (is_exactly_a(*it) || is_exactly_a(*it)) { - complex_subs = true; - break; + // When any of the objects to be substituted is a product or power + // we have to recombine the pairs because the numeric coefficients may + // be part of the search pattern. + if (!(options & (subs_options::pattern_is_product | subs_options::pattern_is_not_product))) { + + // Search the list of substitutions and cache our findings + for (lst::const_iterator it = ls.begin(); it != ls.end(); ++it) { + if (is_exactly_a(*it) || is_exactly_a(*it)) { + options |= subs_options::pattern_is_product; + break; + } } + if (!(options & subs_options::pattern_is_product)) + options |= subs_options::pattern_is_not_product; } - if (complex_subs) { + if (options & subs_options::pattern_is_product) { // Substitute in the recombined pairs epvector::const_iterator cit = seq.begin(), last = seq.end(); diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 244a5f8c..2352729c 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -602,7 +602,7 @@ ex mul::algebraic_subs_mul(const lst & ls, const lst & lr, unsigned options) con subsresult[j] = op(j); else { foundfirstsubsedfactor = true; - subsresult[j] = op(j) * power(itr->subs(ex(repls), subs_options::subs_no_pattern) / its->subs(ex(repls), subs_options::subs_no_pattern), nummatches); + subsresult[j] = op(j) * power(itr->subs(ex(repls), subs_options::no_pattern) / its->subs(ex(repls), subs_options::no_pattern), nummatches); } subsed[j] = true; } @@ -616,7 +616,7 @@ ex mul::algebraic_subs_mul(const lst & ls, const lst & lr, unsigned options) con for (size_t j=0; jnops(); j++) { if (!subsed[j] && tryfactsubs(op(j), *its, nummatches, repls)) { subsed[j] = true; - subsresult[j] = op(j) * power(itr->subs(ex(repls), subs_options::subs_no_pattern) / its->subs(ex(repls), subs_options::subs_no_pattern), nummatches); + subsresult[j] = op(j) * power(itr->subs(ex(repls), subs_options::no_pattern) / its->subs(ex(repls), subs_options::no_pattern), nummatches); } } } @@ -630,7 +630,7 @@ ex mul::algebraic_subs_mul(const lst & ls, const lst & lr, unsigned options) con } } if (!subsfound) - return basic::subs(ls, lr, options | subs_options::subs_algebraic); + return basic::subs(ls, lr, options | subs_options::algebraic); exvector ev; ev.reserve(nops()); for (size_t i=0; i::max(); lst repls; if (tryfactsubs(*this, *its, nummatches, repls)) - return (ex_to((*this) * power(itr->subs(ex(repls), subs_options::subs_no_pattern) / its->subs(ex(repls), subs_options::subs_no_pattern), nummatches))).basic::subs(ls, lr, options); + return (ex_to((*this) * power(itr->subs(ex(repls), subs_options::no_pattern) / its->subs(ex(repls), subs_options::no_pattern), nummatches))).basic::subs(ls, lr, options); } ex result=basic::subs(ls, lr, options);