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

Commit

Permalink
16203: implement ex.series_variable; disallow ex.series conversion in…
Browse files Browse the repository at this point in the history
…to mismatched PowerSeries ring element
  • Loading branch information
rwst committed Dec 5, 2014
1 parent 53b2ca4 commit e1a9039
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
26 changes: 14 additions & 12 deletions src/sage/rings/power_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,17 +698,16 @@ def _element_constructor_(self, f, prec=infinity, check=True):
Conversion from symbolic series::
sage: x,y = var('x,y')
sage: s=(1/(1-x)).series(x,3); s
1 + 1*x + 1*x^2 + Order(x^3)
sage: R.<x> = PowerSeriesRing(QQ)
sage: y=var('y')
sage: ex=(1/(1-y)).series(y,6); R(ex)
1 + x + x^2 + x^3 + x^4 + x^5 + O(x^6)
sage: ex=(sin(y)).series(y,6); R(ex)
x - 1/6*x^3 + 1/120*x^5 + O(x^6)
sage: R.<x> = PowerSeriesRing(SR)
sage: ex=(log(2-y)).series(y,4); R(ex)
log(2) - 1/2*x - 1/8*x^2 - 1/24*x^3 + O(x^4)
sage: ex=(gamma(1-y)).series(y,3); R(ex)
1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + O(x^3)
sage: R(s)
1 + x + x^2 + O(x^3)
sage: ex=(gamma(1-y)).series(y,3)
sage: R.<y> = PowerSeriesRing(SR)
sage: R(ex)
1 + euler_gamma*y + (1/2*euler_gamma^2 + 1/12*pi^2)*y^2 + O(y^3)
Laurent series with non-negative valuation are accepted (see
:trac:`6431`)::
Expand Down Expand Up @@ -740,8 +739,11 @@ def _element_constructor_(self, f, prec=infinity, check=True):
den = self.element_class(self, f.denominator(), prec, check=check)
return self.coerce(num/den)
elif isinstance(f, Expression) and f.is_series():
return self.element_class(self, f.list(),
f.degree(f.default_variable()), check=check)
if str(f.series_variable()) is self.variable_name():
return self.element_class(self, f.list(),
f.degree(f.series_variable()), check=check)
else:
raise TypeError("Can only convert series into ring with same variable name.")
return self.element_class(self, f, prec, check=check)

def construction(self):
Expand Down
23 changes: 22 additions & 1 deletion src/sage/symbolic/expression.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3560,7 +3560,28 @@ cdef class Expression(CommutativeRingElement):
finally:
sig_off()
return new_Expression_from_GEx(self._parent, x)


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
sage: x.series_variable()
Traceback (most recent call last):
...
TypeError: Not a series.
"""
cdef GEx x = g_series_var(self._gobj)
cdef Expression ex = new_Expression_from_GEx(self._parent, x)
if ex.is_zero():
raise TypeError("Not a series.")
return ex

def residue(self, symbol):
"""
Calculate the residue of ``self`` with respect to ``symbol``.
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

0 comments on commit e1a9039

Please sign in to comment.