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

Commit

Permalink
Merge branch 'u/rws/coefficients_of_symbolic_expressions_revamp' of t…
Browse files Browse the repository at this point in the history
…rac.sagemath.org:sage into t/17399/fix_coefficients_for_symbolic_series

* 'u/rws/coefficients_of_symbolic_expressions_revamp' of trac.sagemath.org:sage:
  17438: implement ex.list()
  17438: deprecate ex.coeff/coeffs()
  17438: implement coeff list
  • Loading branch information
rwst committed Dec 4, 2014
2 parents 99820cf + 0fec129 commit 168b659
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/sage/calculus/calculus.py
Expand Up @@ -379,7 +379,7 @@
+ 4*euler_gamma*(sqrt(3)*pi + 9*log(3)) + 27*log(3)^2 + 12*psi(1,
1/3))*x^2*gamma(1/3) - 1/6*(6*euler_gamma + sqrt(3)*pi +
9*log(3))*x*gamma(1/3) + gamma(1/3)
sage: map(lambda f:f[0].n(), _.coeffs()) # numerical coefficients to make comparison easier; Maple 12 gives same answer
sage: map(lambda f:f[0].n(), _.coefficients()) # numerical coefficients to make comparison easier; Maple 12 gives same answer
[2.6789385347..., -8.3905259853..., 26.662447494..., -80.683148377...]
Ensure that ticket #8582 is fixed::
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/tutorial.py
Expand Up @@ -319,7 +319,7 @@
or calculate, more or less instantaneously, the 100-th coefficient::
sage: C.series(z, 101).coeff(z,100)
sage: C.series(z, 101).coefficient(z,100)
227508830794229349661819540395688853956041682601541047340
It is unfortunate to have to recalculate everything if at some point we
Expand Down
2 changes: 1 addition & 1 deletion src/sage/databases/oeis.py
Expand Up @@ -95,7 +95,7 @@
::
sage: x = var('x') ; f(x) = e^(e^x - 1)
sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coeffs()] ; L
sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coefficients()] ; L
[1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597,
27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159,
5832742205057, 51724158235372]
Expand Down
2 changes: 1 addition & 1 deletion src/sage/matrix/constructor.py
Expand Up @@ -2906,7 +2906,7 @@ def companion_matrix(poly, format='right'):
...
TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not y^3 - 2*y + 1
sage: coeff_list = [q(y=0)] + [q.coeff(y^k) for k in range(1, q.degree(y)+1)]
sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) for k in range(1, q.degree(y)+1)]
sage: coeff_list
[1, -2, 0, 1]
sage: companion_matrix(coeff_list)
Expand Down
2 changes: 1 addition & 1 deletion src/sage/modules/vector_space_morphism.py
Expand Up @@ -748,7 +748,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'):
raise ValueError('symbolic function has the wrong number of inputs for domain')
if n != C.degree():
raise ValueError('symbolic function has the wrong number of outputs for codomain')
arg2 = [[e.coeff(a) for e in exprs] for a in args]
arg2 = [[e.coefficient(a) for e in exprs] for a in args]
try:
arg2 = matrix(D.base_ring(), m, n, arg2)
except TypeError as e:
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/padics/factory.py
Expand Up @@ -2277,7 +2277,7 @@ def create_key_and_extra_args(self, base, premodulus, prec = None, print_mode =
# the information needed to shift right with full precision from the premodulus.
if is_Expression(premodulus):
# Here we assume that the output of coeffs is sorted in increasing order by exponent:
coeffs = premodulus.coeffs()
coeffs = premodulus.coefficients()
preseed = premodulus / coeffs[-1][0]
preseed -= preseed.variables()[0]**coeffs[-1][1]
preseed /= base.prime() # here we assume that the base is unramified over Qp
Expand Down
124 changes: 102 additions & 22 deletions src/sage/symbolic/expression.pyx
Expand Up @@ -832,21 +832,21 @@ cdef class Expression(CommutativeRingElement):
EXAMPLES::
sage: f = x^3 + 17*x -3
sage: ZZ(f.coeff(x^3))
sage: ZZ(f.coefficient(x^3))
1
sage: ZZ(f.coeff(x))
sage: ZZ(f.coefficient(x))
17
sage: ZZ(f.coeff(x,0))
sage: ZZ(f.coefficient(x,0))
-3
sage: type(ZZ(f.coeff(x,0)))
sage: type(ZZ(f.coefficient(x,0)))
<type 'sage.rings.integer.Integer'>
Coercion is done if necessary::
sage: f = x^3 + 17/1*x
sage: ZZ(f.coeff(x))
sage: ZZ(f.coefficient(x))
17
sage: type(ZZ(f.coeff(x)))
sage: type(ZZ(f.coefficient(x)))
<type 'sage.rings.integer.Integer'>
If the symbolic expression is just a wrapper around an integer,
Expand Down Expand Up @@ -914,15 +914,15 @@ cdef class Expression(CommutativeRingElement):
EXAMPLES::
sage: f = x^3 + 17/1*x - 3/8
sage: QQ(f.coeff(x^2))
sage: QQ(f.coefficient(x^2))
0
sage: QQ(f.coeff(x^3))
sage: QQ(f.coefficient(x^3))
1
sage: a = QQ(f.coeff(x)); a
sage: a = QQ(f.coefficient(x)); a
17
sage: type(a)
<type 'sage.rings.rational.Rational'>
sage: QQ(f.coeff(x,0))
sage: QQ(f.coefficient(x,0))
-3/8
If the symbolic expression is just a wrapper around a rational,
Expand Down Expand Up @@ -4093,9 +4093,9 @@ cdef class Expression(CommutativeRingElement):
False
sage: (4*x^2 + x + 3).has(x)
True
sage: (4*x^2 - x + 3).coeff(x,1)
sage: (4*x^2 - x + 3).coefficient(x,1)
-1
sage: (4*x^2 + x + 3).coeff(x,1)
sage: (4*x^2 + x + 3).coefficient(x,1)
1
"""
cdef Expression p = self.coerce_in(pattern)
Expand Down Expand Up @@ -5103,12 +5103,19 @@ cdef class Expression(CommutativeRingElement):
sage: var('x,y,z')
(x, y, z)
sage: f = x*y*z^2
sage: f.coeff(x*y)
sage: f.coefficient(x*y)
z^2
sage: f.coeff(x*y, 2)
sage: f.coefficient(x*y, 2)
Traceback (most recent call last):
...
TypeError: n != 1 only allowed for s being a variable
Using ``coeff()`` is now deprecated (:trac:`17438`)::
sage: x.coeff(x)
doctest:...: DeprecationWarning: coeff is deprecated. Please use coefficient instead.
See http://trac.sagemath.org/17438 for details.
1
"""
cdef Expression ss = self.coerce_in(s)
if n != 1 and not is_a_symbol(ss._gobj):
Expand All @@ -5118,13 +5125,13 @@ cdef class Expression(CommutativeRingElement):
if is_a_mul(ss._gobj): # necessarily n=1 here
res = self
for i from 0 <= i < ss._gobj.nops():
res = res.coeff(new_Expression_from_GEx(self._parent, ss._gobj.op(i)))
res = res.coefficient(new_Expression_from_GEx(self._parent, ss._gobj.op(i)))
return res
return new_Expression_from_GEx(self._parent, self._gobj.coeff(ss._gobj, n))

coeff = coefficient
coeff = deprecated_function_alias(17438, coefficient)

def coefficients(self, x=None):
def coefficients(self, x=None, sparse=True):
r"""
Return the coefficients of this symbolic expression as a polynomial in x.
Expand All @@ -5133,9 +5140,14 @@ cdef class Expression(CommutativeRingElement):
- ``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.
- 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::
Expand All @@ -5144,18 +5156,40 @@ cdef class Expression(CommutativeRingElement):
sage: p = x^3 - (x-3)*(x^2+x) + 1
sage: p.coefficients()
[[1, 0], [3, 1], [2, 2]]
sage: p.coefficients(sparse=False)
[1, 3, 2]
sage: p = x - x^3 + 5/7*x^5
sage: p.coefficients()
[[1, 1], [-1, 3], [5/7, 5]]
sage: p.coefficients(sparse=False)
[0, 1, 0, -1, 0, 5/7]
sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
sage: p.coefficients(a)
[[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]]
sage: p.coefficients(a, sparse=False)
[x^2 + x + 1, -2*sqrt(2)*x, 2]
sage: p.coefficients(x)
[[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]]
sage: p.coefficients(x, sparse=False)
[2*a^2 + 1, -2*sqrt(2)*a + 1, 1]
A polynomial with wacky exponents::
The behaviour is undefined with noninteger or negative exponents::
sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x
sage: p.coefficients(x)
[[1, -1], [x^x, 0], [y, 1], [17/3*a, 3/2]]
sage: p.coefficients(x, sparse=False)
Traceback (most recent call last):
...
ValueError: Cannot return dense coefficient list with noninteger exponents.
Using ``coeffs()`` is now deprecated (:trac:`17438`)::
sage: x.coeffs()
doctest:...: DeprecationWarning: coeffs is deprecated. Please use coefficients instead.
See http://trac.sagemath.org/17438 for details.
[[1, 1]]
"""
f = self._maxima_()
maxima = f.parent()
Expand All @@ -5166,9 +5200,55 @@ cdef class Expression(CommutativeRingElement):
G = f.coeffs(x)
from sage.calculus.calculus import symbolic_expression_from_maxima_string
S = symbolic_expression_from_maxima_string(repr(G))
return S[1:]
l = S[1:]
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

coeffs = deprecated_function_alias(17438, coefficients)

def list(self, x=None):
r"""
Return the coefficients of this symbolic expression as a polynomial in x.
INPUT:
- ``x`` -- optional variable.
coeffs = coefficients
OUTPUT:
A list of expressions where the ``n``-th element is the coefficient of
``x^n`` when self is seen as polynomial in ``x``.
EXAMPLES::
sage: var('x, y, a')
(x, y, a)
sage: (x^5).list()
[0, 0, 0, 0, 0, 1]
sage: p = x^3 - (x-3)*(x^2+x) + 1
sage: p.list()
[1, 3, 2]
sage: p = x - x^3 + 5/7*x^5
sage: p.list()
[0, 1, 0, -1, 0, 5/7]
sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
sage: p.list(a)
[x^2 + x + 1, -2*sqrt(2)*x, 2]
"""
return self.coefficients(x=x, sparse=False)

def leading_coefficient(self, s):
"""
Expand Down
4 changes: 2 additions & 2 deletions src/sage/symbolic/function_factory.py
Expand Up @@ -217,9 +217,9 @@ def function(s, *args, **kwds):
(r^2*D[0, 0](psi)(r) + 2*r*D[0](psi)(r))/r^2
sage: g.expand()
2*D[0](psi)(r)/r + D[0, 0](psi)(r)
sage: g.coeff(psi.derivative(r,2))
sage: g.coefficient(psi.derivative(r,2))
1
sage: g.coeff(psi.derivative(r,1))
sage: g.coefficient(psi.derivative(r,1))
2/r
Defining custom methods for automatic or numeric evaluation, derivation,
Expand Down
2 changes: 1 addition & 1 deletion src/sage/tests/french_book/nonlinear_doctest.py
Expand Up @@ -73,7 +73,7 @@
sage: x, a, b, c, d = var('x, a, b, c, d')
sage: P = a * x^3 + b * x^2 + c * x + d
sage: alpha = var('alpha')
sage: P.subs(x=x + alpha).expand().coeff(x, 2)
sage: P.subs(x=x + alpha).expand().coefficient(x, 2)
3*a*alpha + b
sage: P.subs(x = x - b / (3 * a)).expand().collect(x)
a*x^3 - 1/3*(b^2/a - 3*c)*x + 2/27*b^3/a^2 - 1/3*b*c/a + d
Expand Down

0 comments on commit 168b659

Please sign in to comment.