]> www.ginac.de Git - ginac.git/blobdiff - ginac/pseries.cpp
- added find() (like has(), but returns list of all occurrences)
[ginac.git] / ginac / pseries.cpp
index d7f784760be6f2b43f2ccc1f0da325e1fcd55dde..0602ddd74f26df5a1e00bbe70aa249b9439ef6f3 100644 (file)
@@ -132,7 +132,8 @@ void pseries::print(const print_context & c, unsigned level) const
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
                unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
-               for (unsigned i=0; i<seq.size(); ++i) {
+               unsigned num = seq.size();
+               for (unsigned i=0; i<num; ++i) {
                        seq[i].rest.print(c, level + delta_indent);
                        seq[i].coeff.print(c, level + delta_indent);
                        c.s << std::string(level + delta_indent, ' ') << "-----" << std::endl;
@@ -150,9 +151,10 @@ void pseries::print(const print_context & c, unsigned level) const
                
                // objects of type pseries must not have any zero entries, so the
                // trivial (zero) pseries needs a special treatment here:
-               if (seq.size() == 0)
+               if (seq.empty())
                        c.s << '0';
-               for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+               epvector::const_iterator i = seq.begin(), end = seq.end();
+               while (i != end) {
                        // print a sign, if needed
                        if (i != seq.begin())
                                c.s << '+';
@@ -196,6 +198,7 @@ void pseries::print(const print_context & c, unsigned level) const
                                }
                        } else
                                Order(power(var-point,i->coeff)).print(c);
+                       ++i;
                }
 
                if (precedence() <= level)
@@ -263,7 +266,7 @@ int pseries::degree(const ex &s) const
        if (var.is_equal(s)) {
                // Return last exponent
                if (seq.size())
-                       return ex_to_numeric((*(seq.end() - 1)).coeff).to_int();
+                       return ex_to<numeric>((*(seq.end() - 1)).coeff).to_int();
                else
                        return 0;
        } else {
@@ -291,7 +294,7 @@ int pseries::ldegree(const ex &s) const
        if (var.is_equal(s)) {
                // Return first exponent
                if (seq.size())
-                       return ex_to_numeric((*(seq.begin())).coeff).to_int();
+                       return ex_to<numeric>((*(seq.begin())).coeff).to_int();
                else
                        return 0;
        } else {
@@ -319,7 +322,7 @@ int pseries::ldegree(const ex &s) const
 ex pseries::coeff(const ex &s, int n) const
 {
        if (var.is_equal(s)) {
-               if (seq.size() == 0)
+               if (seq.empty())
                        return _ex0();
                
                // Binary search in sequence for given power
@@ -328,7 +331,7 @@ ex pseries::coeff(const ex &s, int n) const
                while (lo <= hi) {
                        int mid = (lo + hi) / 2;
                        GINAC_ASSERT(is_ex_exactly_of_type(seq[mid].coeff, numeric));
-                       int cmp = ex_to_numeric(seq[mid].coeff).compare(looking_for);
+                       int cmp = ex_to<numeric>(seq[mid].coeff).compare(looking_for);
                        switch (cmp) {
                                case -1:
                                        lo = mid + 1;
@@ -418,13 +421,15 @@ ex pseries::subs(const lst & ls, const lst & lr, bool no_pattern) const
 ex pseries::expand(unsigned options) const
 {
        epvector newseq;
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+       epvector::const_iterator i = seq.begin(), end = seq.end();
+       while (i != end) {
                ex restexp = i->rest.expand();
                if (!restexp.is_zero())
                        newseq.push_back(expair(restexp, i->coeff));
+               ++i;
        }
        return (new pseries(relational(var,point), newseq))
-               ->setflag(status_flags::dynallocated | status_flags::expanded);
+               ->setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
 }
 
 /** Implementation of ex::diff() for a power series.  It treats the series as a
@@ -471,7 +476,7 @@ ex pseries::convert_to_poly(bool no_order) const
 
 bool pseries::is_terminating(void) const
 {
-       return seq.size() == 0 || !is_order_function((seq.end()-1)->rest);
+       return seq.empty() || !is_order_function((seq.end()-1)->rest);
 }
 
 
@@ -566,7 +571,7 @@ ex pseries::add_series(const pseries &other) const
                        }
                        break;
                } else
-                       pow_a = ex_to_numeric((*a).coeff).to_int();
+                       pow_a = ex_to<numeric>((*a).coeff).to_int();
                
                // If b is empty, fill up with elements from a and stop
                if (b == b_end) {
@@ -576,7 +581,7 @@ ex pseries::add_series(const pseries &other) const
                        }
                        break;
                } else
-                       pow_b = ex_to_numeric((*b).coeff).to_int();
+                       pow_b = ex_to<numeric>((*b).coeff).to_int();
                
                // a and b are non-empty, compare powers
                if (pow_a < pow_b) {
@@ -629,10 +634,10 @@ ex add::series(const relational & r, int order, unsigned options) const
                else
                        op = it->rest.series(r, order, options);
                if (!it->coeff.is_equal(_ex1()))
-                       op = ex_to_pseries(op).mul_const(ex_to_numeric(it->coeff));
+                       op = ex_to<pseries>(op).mul_const(ex_to<numeric>(it->coeff));
                
                // Series addition
-               acc = ex_to_pseries(acc).add_series(ex_to_pseries(op));
+               acc = ex_to<pseries>(acc).add_series(ex_to<pseries>(op));
        }
        return acc;
 }
@@ -731,15 +736,15 @@ ex mul::series(const relational & r, int order, unsigned options) const
                if (op.info(info_flags::numeric)) {
                        // series * const (special case, faster)
                        ex f = power(op, it->coeff);
-                       acc = ex_to_pseries(acc).mul_const(ex_to_numeric(f));
+                       acc = ex_to<pseries>(acc).mul_const(ex_to<numeric>(f));
                        continue;
                } else if (!is_ex_exactly_of_type(op, pseries))
                        op = op.series(r, order, options);
                if (!it->coeff.is_equal(_ex1()))
-                       op = ex_to_pseries(op).power_const(ex_to_numeric(it->coeff), order);
+                       op = ex_to<pseries>(op).power_const(ex_to<numeric>(it->coeff), order);
 
                // Series multiplication
-               acc = ex_to_pseries(acc).mul_series(ex_to_pseries(op));
+               acc = ex_to<pseries>(acc).mul_series(ex_to<pseries>(op));
        }
        return acc;
 }
@@ -771,7 +776,7 @@ ex pseries::power_const(const numeric &p, int deg) const
        // repeat the above derivation.  The leading power of C2(x) = A2(x)^2 is
        // then of course x^(p*m) but the recurrence formula still holds.
        
-       if (seq.size()==0) {
+       if (seq.empty()) {
                // as a spacial case, handle the empty (zero) series honoring the
                // usual power laws such as implemented in power::eval()
                if (p.real().is_zero())
@@ -824,9 +829,12 @@ ex pseries::power_const(const numeric &p, int deg) const
 /** Return a new pseries object with the powers shifted by deg. */
 pseries pseries::shift_exponents(int deg) const
 {
-       epvector newseq(seq);
-       for (epvector::iterator i=newseq.begin(); i!=newseq.end(); ++i)
-               i->coeff = i->coeff + deg;
+       epvector newseq = seq;
+       epvector::iterator i = newseq.begin(), end  = newseq.end();
+       while (i != end) {
+               i->coeff += deg;
+               ++i;
+       }
        return pseries(relational(var, point), newseq);
 }
 
@@ -862,7 +870,7 @@ ex power::series(const relational & r, int order, unsigned options) const
        }
        
        // Power e
-       return ex_to_pseries(e).power_const(ex_to_numeric(exponent), order);
+       return ex_to<pseries>(e).power_const(ex_to<numeric>(exponent), order);
 }
 
 
@@ -880,7 +888,7 @@ ex pseries::series(const relational & r, int order, unsigned options) const
                        epvector new_seq;
                        epvector::const_iterator it = seq.begin(), itend = seq.end();
                        while (it != itend) {
-                               int o = ex_to_numeric(it->coeff).to_int();
+                               int o = ex_to<numeric>(it->coeff).to_int();
                                if (o >= order) {
                                        new_seq.push_back(expair(Order(_ex1()), o));
                                        break;
@@ -911,7 +919,7 @@ ex ex::series(const ex & r, int order, unsigned options) const
        relational rel_;
        
        if (is_ex_exactly_of_type(r,relational))
-               rel_ = ex_to_relational(r);
+               rel_ = ex_to<relational>(r);
        else if (is_ex_exactly_of_type(r,symbol))
                rel_ = relational(r,_ex0());
        else