]> www.ginac.de Git - ginac.git/blobdiff - ginac/pseries.cpp
synced to 1.2 (memory conservation)
[ginac.git] / ginac / pseries.cpp
index 607360e757d451cc04981100f4978327932838b1..a8b820d46d073c28b81777de987a6cdf7cc4eb2e 100644 (file)
@@ -529,9 +529,10 @@ bool pseries::is_terminating() const
 ex basic::series(const relational & r, int order, unsigned options) const
 {
        epvector seq;
+       const symbol &s = ex_to<symbol>(r.lhs());
 
        // default for order-values that make no sense for Taylor expansion
-       if (order <= 0) {
+       if ((order <= 0) && this->has(s)) {
                seq.push_back(expair(Order(_ex1), order));
                return pseries(r, seq);
        }
@@ -540,8 +541,7 @@ ex basic::series(const relational & r, int order, unsigned options) const
        numeric fac = 1;
        ex deriv = *this;
        ex coeff = deriv.subs(r, subs_options::no_pattern);
-       const symbol &s = ex_to<symbol>(r.lhs());
-       
+
        if (!coeff.is_zero()) {
                seq.push_back(expair(coeff, _ex0));
        }
@@ -784,10 +784,23 @@ ex mul::series(const relational & r, int order, unsigned options) const
        const epvector::const_iterator itbeg = seq.begin();
        const epvector::const_iterator itend = seq.end();
        for (epvector::const_iterator it=itbeg; it!=itend; ++it) {
-               
-               ex buf = recombine_pair_to_ex(*it);
-               
-               int real_ldegree = buf.expand().ldegree(sym-r.rhs());
+
+               ex expon = it->coeff;
+               int factor = 1;
+               ex buf;
+               if (expon.info(info_flags::integer)) {
+                       buf = it->rest;
+                       factor = ex_to<numeric>(expon).to_int();
+               } else {
+                       buf = recombine_pair_to_ex(*it);
+               }
+
+               int real_ldegree = 0;
+               try {
+                       real_ldegree = buf.expand().ldegree(sym-r.rhs());
+               }
+               catch (std::runtime_error) {}
+
                if (real_ldegree == 0) {
                        int orderloop = 0;
                        do {
@@ -796,11 +809,17 @@ ex mul::series(const relational & r, int order, unsigned options) const
                        } while (real_ldegree == orderloop);
                }
 
-               ldegrees.push_back(real_ldegree);
+               ldegrees.push_back(factor * real_ldegree);
        }
 
        int degsum = std::accumulate(ldegrees.begin(), ldegrees.end(), 0);
-               
+
+       if (degsum>order) {
+               epvector epv;
+               epv.push_back(expair(Order(_ex1), order));
+               return (new pseries(r, epv))->setflag(status_flags::dynallocated);
+       }
+
        // Multiply with remaining terms
        std::vector<int>::const_iterator itd = ldegrees.begin();
        for (epvector::const_iterator it=itbeg; it!=itend; ++it, ++itd) {
@@ -934,7 +953,7 @@ ex power::series(const relational & r, int order, unsigned options) const
        }
 
        // Is the expression of type something^(-int)?
-       if (!must_expand_basis && !exponent.info(info_flags::negint))
+       if (!must_expand_basis && !exponent.info(info_flags::negint) && !is_a<add>(basis))
                return basic::series(r, order, options);
 
        // Is the expression of type 0^something?