Ask Your Question

Substitute square in polynomial

asked 2015-01-09 14:58:34 +0200

MvG gravatar image

updated 2015-01-14 14:15:51 +0200

FrédéricC gravatar image

Suppose I have a univariate polynomial, say from QQ['x'], and for some reason I know that the odd coefficients will all be zero. So in fact this is a polynomial in x^2. What's the most elegant syntax to substitute some other value for x^2?

The best I could come up with so far is something like this:

sage: x = QQ['x'].0
sage: p = x^6 - 3*x^4 + 5*x^2 - 9
sage: assert not any(p[i] for i in range(1,,2))
sage: p.parent([p[i] for i in range(0,,2)])
x^3 - 3*x^2 + 5*x - 9
sage: _(7)

Of course, if the value I want to plug in comes from some field where I can compute square roots, I could simply plug one of those in, like p(sqrt(7)) in the example above, but I'm more interested in substituting a multivariate polynomial or something like this.

edit retag flag offensive close merge delete



Note that in the symbolic ring you can use substitute_expression, for example after sage: x = var('x') and sage: f = x^2 + 1 then f.subs_expr(x^2 == x) gives x+1. Not sure going to the symbolic ring and back could be called elegant, though.

slelievre gravatar imageslelievre ( 2015-01-10 17:52:22 +0200 )edit

1 Answer

Sort by » oldest newest most voted

answered 2015-01-09 18:51:33 +0200

slelievre gravatar image

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__??


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.


    - ``n`` - Degree of the monomial whose coefficient is to be returned
              or a slice.


        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( + 1)
        if do_sig: sig_on()
        fmpq_poly_get_slice(res.__poly, self.__poly, start, stop)
        if do_sig: sig_off()
        return res
        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.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2015-01-09 14:58:34 +0200

Seen: 639 times

Last updated: Jan 09 '15