pythonsympysimplify

Making solveset solutions rational in sympy


I'm trying to solve a cubic with a parameter r, for x. The cubic is the awful expression

poly = b*(-(10 + x)*b - 10*b) - ((8/3) + x)*((10+x)*(1+x) - 10)

where

b = sp.sqrt((8/3)*(1 - a))

which factors out to x^3 + (41/3)x^2 + (8/3)(a + 10)x + (160/3)(a - 1).

SymPy's solveset() gives a solution, but it is really long mostly due to the large mass of repeated fractions in the answer. I'd like to do something like Rational(solution) to make the solution nicer, but it doesn't work.

Here's my code and the error:

import sympy as sp
from sympy import Eq, solveset, Rational
from sympy.abc import x, a, b

poly = b*(-(10 + x)*b - 10*b) - ((8/3) + x)*((10+x)*(1+x) - 10)
polysub = poly.subs(b,sp.sqrt((8/3)*(1 - a)))
polyeq = Eq(polysub,0)
solutionset = solveset(polyeq,x)
Rational(solutionset)
TypeError: invalid input: {ridiculously long solution}

Solution

  • If you import S and use S(8)/3 instead of 8/3 you will get fractions instead of floats...but it will still be complicated. You can also use cse to give a symbolically simpler substituted expression:

    ...your code
    >>> from sympy import cse
    >>> cse(solve(polyeq,x))
    [(x0, 8*a + 817/9), (x1, (-556*a + sqrt(-4*x0**3 + (70450/27 - 1112*a)**2)/2 + 35225/27)**(1/3)), (x2, x1/3), (x3, x0/(3*x1)), (x4, sqrt(3)*I/2), (x5, -x4 - 1/2), (x6, x4 - 1/2)], [-x2 - x3 - 41/9, -x2*x5 - x3/x5 - 41/9, -x2*x6 - x3/x6 - 41/9])
    >>> _[-1]
    [-x2 - x3 - 41/9, -x2*x5 - x3/x5 - 41/9, -x2*x6 - x3/x6 - 41/9]