def test_roots_quartic(): assert roots_quartic(Poly(x**4, x)) == [0, 0, 0, 0] assert roots_quartic(Poly(x**4 + x**3, x)) in [[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1]] assert roots_quartic(Poly(x**4 - x**3, x)) in [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] lhs = roots_quartic(Poly(x**4 + x, x)) rhs = [ Rational(1, 2) + I * sqrt(3) / 2, Rational(1, 2) - I * sqrt(3) / 2, 0, -1 ] assert sorted(lhs, key=hash) == sorted(rhs, key=hash) # test of all branches of roots quartic for i, (a, b, c, d) in enumerate([(1, 2, 3, 0), (3, -7, -9, 9), (1, 2, 3, 4), (1, 2, 3, 4), (-7, -3, 3, -6), (-3, 5, -6, -4), (6, -5, -10, -3)]): if i == 2: c = -a * (a**2 / Integer(8) - b / Integer(2)) elif i == 3: d = a * (a * (3 * a**2 / Integer(256) - b / Integer(16)) + c / Integer(4)) eq = x**4 + a * x**3 + b * x**2 + c * x + d ans = roots_quartic(Poly(eq, x)) assert all(eq.subs({x: ai}).evalf(chop=True) == 0 for ai in ans) # not all symbolic quartics are unresolvable eq = Poly(q * x + q / 4 + x**4 + x**3 + 2 * x**2 - Rational(1, 3), x) sol = roots_quartic(eq) assert all(verify_numerically(eq.subs({x: i}), 0) for i in sol) z = symbols('z', negative=True) eq = x**4 + 2 * x**3 + 3 * x**2 + x * (z + 11) + 5 zans = roots_quartic(Poly(eq, x)) assert all(verify_numerically(eq.subs({x: i, z: -1}), 0) for i in zans) # but some are (see also issue sympy/sympy#4989) # it's ok if the solution is not Piecewise, but the tests below should pass eq = Poly(y * x**4 + x**3 - x + z, x) ans = roots_quartic(eq) assert all(type(i) == Piecewise for i in ans) reps = ( { y: -Rational(1, 3), z: -Rational(1, 4) }, # 4 real { y: -Rational(1, 3), z: -Rational(1, 2) }, # 2 real { y: -Rational(1, 3), z: -2 }) # 0 real for rep in reps: sol = roots_quartic(Poly(eq.subs(rep), x)) assert all( verify_numerically(w.subs(rep) - s, 0) for w, s in zip(ans, sol))
def test_roots_quartic(): assert roots_quartic(Poly(x**4, x)) == [0, 0, 0, 0] assert roots_quartic(Poly(x**4 + x**3, x)) in [ [-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1] ] assert roots_quartic(Poly(x**4 - x**3, x)) in [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ] lhs = roots_quartic(Poly(x**4 + x, x)) rhs = [Rational(1, 2) + I*sqrt(3)/2, Rational(1, 2) - I*sqrt(3)/2, 0, -1] assert sorted(lhs, key=hash) == sorted(rhs, key=hash) # test of all branches of roots quartic for i, (a, b, c, d) in enumerate([(1, 2, 3, 0), (3, -7, -9, 9), (1, 2, 3, 4), (1, 2, 3, 4), (-7, -3, 3, -6), (-3, 5, -6, -4), (6, -5, -10, -3)]): if i == 2: c = -a*(a**2/Integer(8) - b/Integer(2)) elif i == 3: d = a*(a*(3*a**2/Integer(256) - b/Integer(16)) + c/Integer(4)) eq = x**4 + a*x**3 + b*x**2 + c*x + d ans = roots_quartic(Poly(eq, x)) assert all(eq.subs({x: ai}).evalf(chop=True) == 0 for ai in ans) # not all symbolic quartics are unresolvable eq = Poly(q*x + q/4 + x**4 + x**3 + 2*x**2 - Rational(1, 3), x) sol = roots_quartic(eq) assert all(verify_numerically(eq.subs({x: i}), 0) for i in sol) z = symbols('z', negative=True) eq = x**4 + 2*x**3 + 3*x**2 + x*(z + 11) + 5 zans = roots_quartic(Poly(eq, x)) assert all(verify_numerically(eq.subs({x: i, z: -1}), 0) for i in zans) # but some are (see also issue sympy/sympy#4989) # it's ok if the solution is not Piecewise, but the tests below should pass eq = Poly(y*x**4 + x**3 - x + z, x) ans = roots_quartic(eq) assert all(type(i) == Piecewise for i in ans) reps = ({y: -Rational(1, 3), z: -Rational(1, 4)}, # 4 real {y: -Rational(1, 3), z: -Rational(1, 2)}, # 2 real {y: -Rational(1, 3), z: -2}) # 0 real for rep in reps: sol = roots_quartic(Poly(eq.subs(rep), x)) assert all(verify_numerically(w.subs(rep) - s, 0) for w, s in zip(ans, sol))