]> www.ginac.de Git - ginac.git/blobdiff - ginac/pseries.cpp
Synced to HEAD
[ginac.git] / ginac / pseries.cpp
index 1efbb65d98640db836b2ca5d5a40969d5370e8c4..993eacf119f7583903747f2a92577f59fa508841 100644 (file)
@@ -785,13 +785,20 @@ ex mul::series(const relational & r, int order, unsigned options) const
        const epvector::const_iterator itend = seq.end();
        for (epvector::const_iterator it=itbeg; it!=itend; ++it) {
 
-               ex buf = recombine_pair_to_ex(*it);
+               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) {}
+               } catch (std::runtime_error) {}
 
                if (real_ldegree == 0) {
                        int orderloop = 0;
@@ -801,12 +808,12 @@ 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) {
+       if (degsum >= order) {
                epvector epv;
                epv.push_back(expair(Order(_ex1), order));
                return (new pseries(r, epv))->setflag(status_flags::dynallocated);
@@ -820,7 +827,7 @@ ex mul::series(const relational & r, int order, unsigned options) const
                ex op = recombine_pair_to_ex(*it).series(r, order-degsum+(*itd), options);
 
                // Series multiplication
-               if (it==itbeg)
+               if (it == itbeg)
                        acc = ex_to<pseries>(op);
                else
                        acc = ex_to<pseries>(acc.mul_series(ex_to<pseries>(op)));
@@ -873,7 +880,7 @@ ex pseries::power_const(const numeric &p, int deg) const
                throw std::runtime_error("pseries::power_const(): trying to assemble a Puiseux series");
 
        // adjust number of coefficients
-       deg = deg - p.to_int()*ldeg;
+       deg = deg - (p*ldeg).to_int();
        
        // O(x^n)^(-m) is undefined
        if (seq.size() == 1 && is_order_function(seq[0].rest) && p.real().is_negative())
@@ -945,11 +952,11 @@ 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?
-       if (!must_expand_basis && !basis.subs(r, subs_options::no_pattern).is_zero())
+       if (!must_expand_basis && !basis.subs(r, subs_options::no_pattern).is_zero() && !is_a<add>(basis))
                return basic::series(r, order, options);
 
        // Singularity encountered, is the basis equal to (var - point)?
@@ -964,7 +971,12 @@ ex power::series(const relational & r, int order, unsigned options) const
 
        // No, expand basis into series
 
-       int intexp = ex_to<numeric>(exponent).to_int();
+       numeric numexp;
+       if (is_a<numeric>(exponent)) {
+               numexp = ex_to<numeric>(exponent);
+       } else {
+               numexp = 0;
+       }
        const ex& sym = r.lhs();
        // find existing minimal degree
        int real_ldegree = basis.expand().ldegree(sym-r.rhs());
@@ -976,13 +988,14 @@ ex power::series(const relational & r, int order, unsigned options) const
                } while (real_ldegree == orderloop);
        }
 
-       ex e = basis.series(r, order + real_ldegree*(1-intexp), options);
+       if (!(real_ldegree*numexp).is_integer())
+               throw std::runtime_error("pseries::power_const(): trying to assemble a Puiseux series");
+       ex e = basis.series(r, (order + real_ldegree*(1-numexp)).to_int(), options);
        
        ex result;
        try {
-               result = ex_to<pseries>(e).power_const(intexp, order);
-       }
-       catch (pole_error) {
+               result = ex_to<pseries>(e).power_const(numexp, order);
+       } catch (pole_error) {
                epvector ser;
                ser.push_back(expair(Order(_ex1), order));
                result = pseries(r, ser);