Solving polynomial equations

Question:

Up to now I have always Mathematica for solving analytical equations. Now however I need to solve a few hundred equations of this type (characteristic polynomials)

a_20*x^20+a_19*x^19+...+a_1*x+a_0=0 (constant floats a_0,...a_20)

at once which yields awfully long calculation times in Mathematica.

Is there like a ready to use command in numpy or any other package to solve an equation of this type? (up to now I have used Python only for simulations so I don’t know much about analytical tools and I couldn’t find anything useful in the numpy tutorials).

Asked By: alice

||

Answers:

You use numpy (apparently), but I’ve never tried it myself though: http://docs.scipy.org/doc/numpy/reference/generated/numpy.roots.html#numpy.roots.

Numpy also provides a polynomial class… numpy.poly1d.

This finds the roots numerically — if you want the analytical roots, I don’t think numpy can do that for you.

Answered By: mgilson

You may want to look at SAGE which is a complete python distribution designed for mathematical processing. Beyond that, I have used Sympy for somewhat similar matters, as Marcin highlighted.

Answered By: TimothyAWiseman

Here is an example from simpy docs:

>>> from sympy import *
>>> x = symbols('x')
>>> from sympy import roots, solve_poly_system

>>> solve(x**3 + 2*x + 3, x)
           ____          ____
     1   / 11 *I  1   / 11 *I
[-1, - - --------, - + --------]
     2      2      2      2

>>> p = Symbol('p')
>>> q = Symbol('q')

>>> sorted(solve(x**2 + p*x + q, x))
          __________           __________
         /  2                 /  2
   p   /  p  - 4*q     p   /  p  - 4*q
[- - + -------------, - - - -------------]
   2         2          2         2

>>> solve_poly_system([y - x, x - 5], x, y)
[(5, 5)]

>>> solve_poly_system([y**2 - x**3 + 1, y*x], x, y)
                                   ___                 ___
                             1   / 3 *I         1   / 3 *I
[(0, I), (0, -I), (1, 0), (- - + -------, 0), (- - - -------, 0)]
                             2      2            2      2

(a link to the docs with this example)

Answered By: akaRem
import decimal as dd
degree = int(input('What is the highest co-efficient of x? '))
coeffs = [0]* (degree + 1)
coeffs1 = {}
dd.getcontext().prec = 10
for ii in range(degree,-1,-1):
    if ii != 0:
        res=dd.Decimal(input('what is the coefficient of x^ %s ? '%ii))
        coeffs[ii] = res
        coeffs1.setdefault('x^ %s ' % ii, res)
    else:
        res=dd.Decimal(input('what is the constant term ? '))
        coeffs[ii] = res
        coeffs1.setdefault('CT', res)
coeffs = coeffs[::-1]
def contextmg(start,stop,step):
    r = start
    while r < stop:
        yield r
        r += step
def ell(a,b,c):
    vals=contextmg(a,b,c)
    context = ['%.10f' % it for it in vals]
    return context
labels = [0]*degree
for ll in range(degree):
    labels[ll] = 'x%s'%(ll+1)
roots = {}
context = ell(-20,20,0.0001)
for x in context:
    for xx in range(degree):
        if xx == 0:
            calculatoR = (coeffs[xx]* dd.Decimal(x)) + coeffs[xx+1]
        else:
            calculatoR = calculatoR * dd.Decimal(x) + coeffs[xx+1]

    func =round(float(calculatoR),2)
    xp = round(float(x),3)
    if func==0 and roots=={} :
        roots[labels[0]] = xp
        labels = labels[1:]
        p = xp
    elif func == 0 and xp >(0.25 + p):
        roots[labels[0]] = xp
        labels = labels[1:]
        p = xp

print(roots)
Answered By: Christopher_Okoro

Way faster approach is to use SageMath. Here’s an example from docs:

x = var('x')
solve(x^2 + 3*x + 2, x)
# [x == -2, x == -1]

You can run this in sage terminal or create file.sage and run it with sage file.sage. It’s all based on Python.

Installation: https://doc.sagemath.org/html/en/installation/index.html

You can also use brew or apt:

brew install sage --cask
# or
sudo apt install sagemath
Answered By: blazej
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.