Sympy Polynomail Issues

76 views
Skip to first unread message

k

unread,
Feb 26, 2018, 8:42:55 AM2/26/18
to sympy
Hi
I am trying to understand how to simplify a Polynomial in Sympy without any 1/x or 1/x^n terms.

Because solving for roots, the domain won't work with nroots.

The error I get.

MultivariatePolynomialError: can't compute numerical roots of Poly(-2.61468835142518e-12*I*x**3 - '
1.77367468147515e-13*x**2 + 2.01551297295763e-14*I*x + 6.13636683162216e-92*1/x**2 - 1.320867768074e-41*I*1/x + 7.79634921616583e-16, x, 1/x, domain='EX')

Any help would be of great assistance.

Leonid Kovalev

unread,
Feb 26, 2018, 11:25:37 AM2/26/18
to sympy
Let's start with the expression 

expr = -2.61468835142518e-12*I*x**3 - 1.77367468147515e-13*x**2 + 2.01551297295763e-14*I*x + 6.13636683162216e-92*1/x**2 - 1.320867768074e-41*I*1/x + 7.79634921616583e-16

It is not a polynomial in x, because it contains negative powers of x. If you force it to be a polynomial with poly(expr), it becomes a polynomial with respect to x and 1/x. And that is a multivariate polynomial (x and 1/x are like two variables). Hence the error: nroots does not work with multivariate polynomials.

Instead, get rid of the negative powers of x first. For example, 

numer, denom = factor(expr).as_numer_denom()

which returns numerator and denominator as a tuple,

(-2.61468835142518e-12*I*x**5 - 1.77367468147515e-13*x**4 + 2.01551297295763e-14*I*x**3 + 7.79634921616583e-16*x**2 - 1.320867768074e-41*I*x + 6.13636683162216e-92,
 x
**2)

(The factoring is optional, but helpful in order to get a simpler numerator-denominator split). Now, the roots of the original expression are the roots of the numerator, except any that are shared with the denominator. 

Now we can convert the numerator to a polynomial and use nroots:

p = poly(numer, x)  
p
.nroots()

Output: 

[0, 0, -0.0808688047608342 + 0.0115783613847529*I, 0.0446783092911365*I, 0.0808688047608342 + 0.0115783613847529*I]

which is disappointing because 0 is obviously not a root of the numerator. The tiny size of constant term is a problem, it creates some roots that are too close to 0 for double-precision computations to discern. We need more precision (parameter n), which in turn requires more iterative steps (parameter maxsteps). 

p.nroots(n=50, maxsteps=200)

This looks better:

[-0.080868804760834166180018845175030947090976577924994 + 0.011578361384752871275300055197605686713645998543873*I, -4.6457086620940071146527033337243530690040397643132e-51*I, 1.6942131906240984280655485817471796195769008732488e-26*I, 0.044678309291136464439409743198239609092604642312342*I, 0.080868804760834166180018845175030947090976577924994 + 0.011578361384752871275300055197605686713645998543873*I]



Reply all
Reply to author
Forward
0 new messages