sympy/sympy — pull request #2926 by smichr (2014-02-18 08:11:59+00:00)
Title: relax constraint on quartic solutions

The "general solution" given at

https://en.wikipedia.org/wiki/File:Quartic_Formula.svg for
x**4 + a*x**3 + b*x**2 + c*x + d == 0

TH = Rational(1, 3)
g = b**2 - 3*a*c + 12*d
al = 2*b**3 - 9*a*b*c + 27*c**2 + 27*a**2*d - 72*b*d
be = sqrt(-4*g**3 + al**2)
a4 = 2**TH*g/(3*(al + be)**TH)
a5 = ((al + be)/54)**TH
a3 = a**2/4 - 2*b/3
a1 = a3 + a4 + a5
a2 = 2*a3 - a4 - a5 - (-a**3 + 4*a*b - 8*c)/(4*sqrt(a1))
r1 = -a/4 - (sqrt(a1) + sqrt(a2))/2
r2 = -a/4 + (-sqrt(a1) + sqrt(a2))/2
r3 = -a/4 + (sqrt(a1) - sqrt(a2))/2
r4 = -a/4 + (sqrt(a1) + sqrt(a2))/2

is not generally valid.

Consider this equation

>>> eq=(x**4+a*x**3+b*x**2+c*x+d)
>>> eq.subs(dict(a=2,b=3,c=z + 11,d=5))
x**4 + 2*x**3 + 3*x**2 + x*(z + 11) + 5

There is no real value of z that will give this more than
2 real roots and yet all 4 roots given by the above formula
for z=0, for example, are real:

>>> zans=solve(_,x)
>>> [w.subs(z,0).n(2) for w in zans]
[-2.3, -0.51, -0.49, 1.3]

Again, consider

>>> eq = x**4 - 8*x**3 + 24*x**2 - x*(z + 32) + 16
>>> zans=solve(eq, x, check=0)
>>> [w.subs(z,0).n(2) for w in zans]
[nan, nan, nan, nan]

versus

>>> [w.n(2) for w in solve(eq.subs(z,0))]
[2.0]

>>> [w.subs(z,1).n(2) for w in zans] # 4 imaginary
[1.8 - 1.2*I, 1.8 + 1.2*I, 2.2 - 1.2*I, 2.2 + 1.2*I]

versus

>>> [w.n(2) for w in solve(eq.subs(z,1))] # two imaginary
[1.0, 1.8 - 1.2*I, 1.8 + 1.2*I, 3.4]