1 | initial version |
A shortcut for the first line is:
sage: x = polygen(QQ)
Then it's a matter of taste which is more elegant: your code, or
sage: p = x^6 - 3*x^4 + 5*x^2 - 9
sage: assert not any(p.list()[1::2])
sage: p.parent(p.list()[::2])
x^3 - 3*x^2 + 5*x - 9
This code is shorter, but yours iterates instead of constructing a list.
Sadly, p[1::2]
and p[::2]
don't give the expected result,
the final :2
is silently ignored. The code for that is in the
__getitem__
method of the class Polynomial_rational_flint
,
which is the class of p
. Inspecting this method:
sage: from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
sage: Polynomial_rational_flint.__getitem__??
gives
def __getitem__(self, n):
"""
Returns coefficient of the monomial of degree `n` if `n` is an integer,
returns the monomials of self of degree in slice `n` if `n` is a slice.
INPUT:
- ``n`` - Degree of the monomial whose coefficient is to be returned
or a slice.
EXAMPLES::
sage: R.<t> = QQ[]
sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
sage: f[-1], f[0], f[3], f[5] # indirect doctest
(0, 1, 1/3, 0)
sage: f[1:3] # indirect doctest
1/2*t^2 + t
"""
cdef Rational z = PY_NEW(Rational)
cdef Polynomial_rational_flint res = self._new()
cdef bint do_sig = _do_sig(self.__poly)
if isinstance(n, slice):
start, stop, step = n.indices(self.degree() + 1)
if do_sig: sig_on()
fmpq_poly_get_slice(res.__poly, self.__poly, start, stop)
if do_sig: sig_off()
return res
else:
if 0 <= n and n < fmpq_poly_length(self.__poly):
fmpq_poly_get_coeff_mpq(z.value, self.__poly, n)
return z
in which we see that in the case where n
is an instance of the type slice
,
it is split into start, stop, step
, and then step
is silently dropped
when calling fmpq_poly_get_slice(res.__poly, self.__poly, start, stop)
.
Fixing this is not immediate since the flint function fmpq_poly_get_slice
only takes start and stop arguments, not a step, see
flint source code.
Maybe this could be a feature request for Flint, and then we could make
the __get_item__
method above work!
In the meantime, I wonder if a warning, or a "not implemented" error
should be raised when calling __get_item__
with a step other than 1,
since the result is likely to be wrong with respect to the user's expectation.
Going beyond this exploration of your simple example: of course if you wanted to deal with very general polynomials, including sparse polynomials or multivariate polynomials, you would need to deal differently with different flavours of polynomials, since they have different implementations.