]> www.ginac.de Git - ginac.git/blobdiff - ginac/power.cpp
lst now provides (read-only) iterator types, the use of which makes iterating
[ginac.git] / ginac / power.cpp
index 718a26f745508a64eb97f82daf861aa0822210eb..2cae8a88f4a2e4c867a25c4775bbfc677e5dfbf6 100644 (file)
@@ -73,7 +73,7 @@ DEFAULT_DESTROY(power)
 // archiving
 //////////
 
-power::power(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
+power::power(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
 {
        n.find_ex("basis", basis, sym_lst);
        n.find_ex("exponent", exponent, sym_lst);
@@ -228,14 +228,13 @@ bool power::info(unsigned inf) const
        return inherited::info(inf);
 }
 
-unsigned power::nops() const
+size_t power::nops() const
 {
        return 2;
 }
 
-ex power::op(int i) const
+ex power::op(size_t i) const
 {
-       GINAC_ASSERT(i>=0);
        GINAC_ASSERT(i<2);
 
        return i==0 ? basis : exponent;
@@ -525,28 +524,31 @@ ex power::evalm(void) const
        return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated);
 }
 
-extern bool tryfactsubs(const ex &, const ex &, unsigned &, lst &);
+// from mul.cpp
+extern bool tryfactsubs(const ex &, const ex &, int &, lst &);
 
 ex power::subs(const lst & ls, const lst & lr, unsigned options) const
-{
-       if (options & subs_options::subs_algebraic) {
-               for (int i=0; i<ls.nops(); i++) {
-                       unsigned nummatches = std::numeric_limits<unsigned>::max();
-                       lst repls;
-                       if (tryfactsubs(*this, ls.op(i), nummatches, repls))
-                               return (ex_to<basic>((*this) * power(lr.op(i).subs(ex(repls), subs_options::subs_no_pattern) / ls.op(i).subs(ex(repls), subs_options::subs_no_pattern), nummatches))).basic::subs(ls, lr, options);
-               }
-               return basic::subs(ls, lr, options);
-       }
-
+{      
        const ex &subsed_basis = basis.subs(ls, lr, options);
        const ex &subsed_exponent = exponent.subs(ls, lr, options);
 
-       if (are_ex_trivially_equal(basis, subsed_basis)
-        && are_ex_trivially_equal(exponent, subsed_exponent))
-               return basic::subs(ls, lr, options);
-       else
+       if (!are_ex_trivially_equal(basis, subsed_basis)
+        || !are_ex_trivially_equal(exponent, subsed_exponent)) 
                return power(subsed_basis, subsed_exponent).basic::subs(ls, lr, options);
+
+       if(!(options & subs_options::subs_algebraic))
+               return basic::subs(ls, lr, options);
+
+       lst::const_iterator its, itr;
+       for (its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) {
+               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);
+       }
+
+       ex result=basic::subs(ls, lr, options);
+       return result;
 }
 
 ex power::eval_ncmul(const exvector & v) const
@@ -678,7 +680,7 @@ ex power::expand_add(const add & a, int n) const
        if (n==2)
                return expand_add_2(a);
 
-       const int m = a.nops();
+       const size_t m = a.nops();
        exvector result;
        // The number of terms will be the number of combinatorial compositions,
        // i.e. the number of unordered arrangement of m nonnegative integers
@@ -690,7 +692,7 @@ ex power::expand_add(const add & a, int n) const
        intvector upper_limit(m-1);
        int l;
 
-       for (int l=0; l<m-1; ++l) {
+       for (size_t l=0; l<m-1; ++l) {
                k[l] = 0;
                k_cum[l] = 0;
                upper_limit[l] = n;
@@ -746,10 +748,10 @@ ex power::expand_add(const add & a, int n) const
                // recalc k_cum[] and upper_limit[]
                k_cum[l] = (l==0 ? k[0] : k_cum[l-1]+k[l]);
 
-               for (int i=l+1; i<m-1; ++i)
+               for (size_t i=l+1; i<m-1; ++i)
                        k_cum[i] = k_cum[i-1]+k[i];
 
-               for (int i=l+1; i<m-1; ++i)
+               for (size_t i=l+1; i<m-1; ++i)
                        upper_limit[i] = n-k_cum[i-1];
        }
 
@@ -763,7 +765,7 @@ ex power::expand_add(const add & a, int n) const
 ex power::expand_add_2(const add & a) const
 {
        epvector sum;
-       unsigned a_nops = a.nops();
+       size_t a_nops = a.nops();
        sum.reserve((a_nops*(a_nops+1))/2);
        epvector::const_iterator last = a.seq.end();