Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
17400: implement series.simplify_full()
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Jan 23, 2015
1 parent 2e74911 commit 2660235
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 25 deletions.
33 changes: 8 additions & 25 deletions src/sage/symbolic/expression.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5200,34 +5200,17 @@ cdef class Expression(CommutativeRingElement):
doctest:...: DeprecationWarning: coeffs is deprecated. Please use coefficients instead.
See http://trac.sagemath.org/17438 for details.
[[1, 1]]
Series coefficients are now handled correctly (:trac:`17399`)::
sage: s=(1/(1-x)).series(x,6); s
1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6)
sage: s.coefficients()
[[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]]
sage: s.coefficients(x, sparse=False)
[1, 1, 1, 1, 1, 1]
sage: x,y = var("x,y")
sage: s=(1/(1-y*x-x)).series(x,3); s
1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3)
sage: s.coefficients(x, sparse=False)
[1, y + 1, (y + 1)^2]
"""
f = self._maxima_()
maxima = f.parent()
maxima._eval_line('load(coeflist)')
if x is None:
x = self.default_variable()
if is_a_series(self._gobj):
l = [[self.coefficient(x, d), d] for d in xrange(self.degree(x))]
else:
f = self._maxima_()
maxima = f.parent()
maxima._eval_line('load(coeflist)')
G = f.coeffs(x)
from sage.calculus.calculus import symbolic_expression_from_maxima_string
S = symbolic_expression_from_maxima_string(repr(G))
l = S[1:]

x = self.parent().var(repr(x))
G = f.coeffs(x)
from sage.calculus.calculus import symbolic_expression_from_maxima_string
S = symbolic_expression_from_maxima_string(repr(G))
l = S[1:]
if sparse is True:
return l
else:
Expand Down
1 change: 1 addition & 0 deletions src/sage/symbolic/ginac.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ cdef extern from "ginac_wrap.h":
bint is_a_series "is_a<pseries>" (GEx e)
# you must ensure that is_a_series(e) is true before calling this:
bint g_is_a_terminating_series(GEx e) except +
GEx g_series_var(GEx e) except +

# Relations
ctypedef enum operators "relational::operators":
Expand Down
7 changes: 7 additions & 0 deletions src/sage/symbolic/ginac_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ bool g_is_a_terminating_series(const ex& e) {
return false;
}

ex g_series_var(const ex& e) {
if (is_a<pseries>(e)) {
return (ex_to<pseries>(e)).get_var();
}
return NULL;
}

relational::operators relational_operator(const ex& e) {
// unsafe cast -- be damn sure the input is a relational.
return (ex_to<relational>(e)).the_operator();
Expand Down
87 changes: 87 additions & 0 deletions src/sage/symbolic/series.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ from sage.symbolic.expression cimport Expression, new_Expression_from_GEx
cdef class SymbolicSeries(Expression):
def __init__(self, SR):
Expression.__init__(self, SR, 0)
self._parent = SR

def is_series(self):
"""
Expand Down Expand Up @@ -142,3 +143,89 @@ cdef class SymbolicSeries(Expression):
"""
return new_Expression_from_GEx(self._parent, series_to_poly(self._gobj))

def series_variable(self):
"""
Return the expansion variable of this symbolic series.
EXAMPLES::
sage: s=(1/(1-x)).series(x,3); s
1 + 1*x + 1*x^2 + Order(x^3)
sage: s.series_variable()
x
"""
cdef GEx x = g_series_var(self._gobj)
cdef Expression ex = new_Expression_from_GEx(self._parent, x)
return ex

def coefficients(self, x=None, sparse=True):
r"""
Return the coefficients of this symbolic series as a polynomial in x.
INPUT:
- ``x`` -- optional variable.
OUTPUT:
Depending on the value of ``sparse``,
- A list of pairs ``(expr, n)``, where ``expr`` is a symbolic
expression and ``n`` is a power (``sparse=True``, default)
- A list of expressions where the ``n``-th element is the coefficient of
``x^n`` when self is seen as polynomial in ``x`` (``sparse=False``).
EXAMPLES::
sage: s=(1/(1-x)).series(x,6); s
1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6)
sage: s.coefficients()
[[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]]
sage: s.coefficients(x, sparse=False)
[1, 1, 1, 1, 1, 1]
sage: x,y = var("x,y")
sage: s=(1/(1-y*x-x)).series(x,3); s
1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3)
sage: s.coefficients(x, sparse=False)
[1, y + 1, (y + 1)^2]
"""
if x is None:
x = self.default_variable()
l = [[self.coefficient(x, d), d] for d in xrange(self.degree(x))]
if sparse is True:
return l
else:
from sage.rings.integer_ring import ZZ
if any(not c[1] in ZZ for c in l):
raise ValueError("Cannot return dense coefficient list with noninteger exponents.")
val = l[0][1]
if val < 0:
raise ValueError("Cannot return dense coefficient list with negative valuation.")
deg = l[-1][1]
ret = [ZZ(0)] * int(deg+1)
for c in l:
ret[c[1]] = c[0]
return ret

def simplify_full(self):
"""
Return a simplified version of this symbolic series.
This calls `simplify_full()` for every coefficient of the series.
EXAMPLES::
sage: x,y = var('x,y')
sage: s = (1/(1-x*y-x^2)).series(x,5); s
1 + (y)*x + (y^2 + 1)*x^2 + ((y^2 + 1)*y + y)*x^3 + (((y^2 + 1)*y + y)*y + y^2 + 1)*x^4 + Order(x^5)
sage: s.simplify_full()
1 + (y)*x + (y^2 + 1)*x^2 + (y^3 + 2*y)*x^3 + (y^4 + 3*y^2 + 1)*x^4 + Order(x^5)
"""
l = self.coefficients(sparse=True)
var = self.default_variable()
poly = sum(co.simplify_full()*var**ex for (co,ex) in l)
if not self.is_terminating_series():
poly += var**(self.degree(var)+1)
return poly.series(var, self.degree(var))

0 comments on commit 2660235

Please sign in to comment.