]> www.ginac.de Git - ginac.git/commitdiff
- subs_no_pattern -> no_pattern, subs_algebraic -> algebraic
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 21 Jul 2003 17:43:52 +0000 (17:43 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 21 Jul 2003 17:43:52 +0000 (17:43 +0000)
- backported the expariseq::subschildren() optimization from 1.2

ginac/basic.cpp
ginac/expairseq.cpp
ginac/mul.cpp
ginac/power.cpp

index bd19ab59d218ca94af5be69694147275d0d7ac79..d5654e21739c7fd8e55e2f83208690ed66ff4f6a 100644 (file)
@@ -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<basic>(*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<basic>(*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<mul>(s) || is_exactly_a<power>(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);
 }
 
index d4dd3df14613555b53917a5724b17f075d004c93..df270bdc3c4dc883eb63b297b4a2eaa1b44e9448 100644 (file)
@@ -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<basic>(thisexpairseq(vp, overall_coeff));
-       else if ((options & subs_options::subs_algebraic) && is_exactly_a<mul>(*this))
+       else if ((options & subs_options::algebraic) && is_exactly_a<mul>(*this))
                return static_cast<const mul *>(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<mul>(*it) || is_exactly_a<power>(*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<mul>(*it) || is_exactly_a<power>(*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();
index 244a5f8c5690ea343a3f87a971bc3397e0ba4816..2352729c1adbf74159a29d88b400ef4231b61ade 100644 (file)
@@ -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; j<this->nops(); 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<nops(); i++) {
index 2cae8a88f4a2e4c867a25c4775bbfc677e5dfbf6..fb67a504de19f3d4ac162b3935cf1a4246f45105 100644 (file)
@@ -536,7 +536,7 @@ ex power::subs(const lst & ls, const lst & lr, unsigned options) const
         || !are_ex_trivially_equal(exponent, subsed_exponent)) 
                return power(subsed_basis, subsed_exponent).basic::subs(ls, lr, options);
 
-       if(!(options & subs_options::subs_algebraic))
+       if(!(options & subs_options::algebraic))
                return basic::subs(ls, lr, options);
 
        lst::const_iterator its, itr;
@@ -544,7 +544,7 @@ ex power::subs(const lst & ls, const lst & lr, unsigned options) const
                int nummatches = std::numeric_limits<int>::max();
                lst repls;
                if (tryfactsubs(*this, *its, nummatches, repls))
-                       return (ex_to<basic>((*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<basic>((*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);