Ask Your Question

checking whether the polynomial has a rational root

asked 2023-01-02 12:09:14 +0200

the1diot gravatar image

updated 2023-01-02 12:09:44 +0200

Hello there,

I have a polynomial $f$ which has all its roots purely imaginary, that is, if $f(z)=0$, then $z=ix$ for some real number $x$. I'm using the following command to check all the roots.


Now I define $g(x) = f(ix)$. Then, all the roots of $g(x)$ are real. I want to print only the rational roots of $g$. So I tried:


But I'm getting the following error:

Unable to coerce I to a rational

How to fix this?

edit retag flag offensive close merge delete




[x[0] for x in g.roots() if x[0] in QQ]
achrzesz gravatar imageachrzesz ( 2023-01-02 12:45:26 +0200 )edit

@the 1diot : do not use CC, which is a(pseudo-)ring of numerical approximations to complexes (and therefore "inexact"), but QQbar, representation of agorithms allowing to compute an algebraic number to arbitrary precision, and therefore considered as an "exact" representation of algebraics. Contemplate :

sage: CC
Complex Field with 53 bits of precision
sage: CC.is_exact()
sage: QQbar
Algebraic Field
sage: QQbar.is_exact()
Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2023-01-02 18:28:12 +0200 )edit

@achresz : you should transform your comment in an answer, that the Idiot can accept, in order to mark this question as answered for the benefit of future

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2023-01-02 18:30:29 +0200 )edit

Since in the question f(x) and g(x) are not defined I can't check if my "answer" is correct.

achrzesz gravatar imageachrzesz ( 2023-01-02 20:59:12 +0200 )edit

@achrzesz : you can illustrate your answer with an example, without attempting to solve the 1diot's problem :

sage: f(x) = ((x-I)^2*(x-sqrt(2)*I)*(x-3/2*I)^3).expand() ; f(x)
x^6 - I*sqrt(2)*x^5 - 13/2*I*x^5 - 13/2*sqrt(2)*x^4 - 67/4*x^4 + 67/4*I*sqrt(2)*x^3 + 171/8*I*x^3 + 171/8*sqrt(2)*x^2 + 27/2*x^2 - 27/2*I*sqrt(2)*x - 27/8*I*x - 27/8*sqrt(2)
sage: g(x)=f(I*x) ; g
x |--> -x^6 + sqrt(2)*x^5 + 13/2*x^5 - 13/2*sqrt(2)*x^4 - 67/4*x^4 + 67/4*sqrt(2)*x^3 + 171/8*x^3 - 171/8*sqrt(2)*x^2 - 27/2*x^2 + 27/2*sqrt(2)*x + 27/8*x - 27/8*sqrt(2 ...
Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2023-01-03 00:09:21 +0200 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2023-01-05 22:47:21 +0200

dan_fulea gravatar image

updated 2023-01-05 22:48:32 +0200

Here is the "same" answer, using a ring of polynomials. So the pythonic variable x below is representing the indeterminate of a polynomial ring $R$. We have to introduce this polynomial, in my case the ring of coefficients is $\Bbb Q$, the ring of rational numbers, but also other (exact) rings may be used. So $R=\Bbb Q[x]$. We ask sage to give us all roots of a sample polynomial $f$, these live in $\bar{\Bbb Q}$, check which ones are in $i\Bbb Q$ among them, and print them. (If $f$ has all roots in $i\Bbb Q$, we show them all.)

Our sample polynomial is: $$ \begin{aligned} f &= 4 \, x^{12} + 4 \, x^{11} + 33 \, x^{10} + 49 \, x^{9} + 138 \, x^{8} + 254 \, x^{7} \\ &+ 473 \, x^{6} + 689 \, x^{5} + 971 \, x^{4} + 912 \, x^{3} + 859 \, x^{2} + 432 \, x + 252 \ . \end{aligned} $$ The code declares $R=\Bbb Q[x]$, and $f$ first,

R.<x> = PolynomialRing(QQ)    # or simply QQ[]
f = ( 4*x^12 + 4*x^11 + 33*x^10 + 49*x^9 + 138*x^8 + 254*x^7
             + 473*x^6 + 689*x^5 + 971*x^4 + 912*x^3 + 859*x^2 + 432*x + 252 )

and asks for the roots with real part zero, and imaginary part in QQ$=\Bbb Q$:

for r in f.roots(ring=QQbar, multiplicities=False):
    if r.real() == 0 and r.imag() in QQ:
        print(f'Found root r = {r} with rational imaginary part {QQ(r/i)}')


Found root r = -2*I with rational imaginary part -2
Found root r = -1.5000000000000000?*I with rational imaginary part -3/2
Found root r = -1*I with rational imaginary part -1
Found root r = 1*I with rational imaginary part 1
Found root r = 1.5000000000000000?*I with rational imaginary part 3/2
Found root r = 2*I with rational imaginary part 2

In this approach, the step of passing from $f$ to $g$ is no longer needed. But can be done. We could introduce $\Bbb Q(j)$, $j=\sqrt{-1}$, instead of $\Bbb Q$ as the base field for the coefficients. And while computing the roots we can ask directly for the roots in this ring. For instance:

K.<j> = QuadraticField(-1)    # so j is sqrt(-1)
RK.<X> = PolynomialRing(K)    # or simply K[]
g = f(j*X)


sage: [ r for r in g.roots(multiplicities=False) if r in QQ ]
[2, 3/2, 1, -1, -3/2, -2]
sage: [ r for r in f.roots(ring=K, multiplicities=False) if r*j in QQ ]
[2*j, 3/2*j, j, -j, -3/2*j, -2*j]
edit flag offensive delete link more

answered 2023-01-03 01:11:14 +0200

achrzesz gravatar image

Here is a full example to my advice from comments:

[x[0] for x in g.roots() if x[0] in QQ]


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: 2023-01-02 12:09:14 +0200

Seen: 125 times

Last updated: Jan 05