coproc
coproc

Reputation: 6257

How to make sympy simplify a radical expression equaling zero

The three (real) roots of the polynomial x^3 - 3x + 1 sum up to 0. But sympy does not seem to be able to simplify this sum of roots:

>>> from sympy import *
>>> from sympy.abc import x
>>> rr = real_roots(x**3 -3*x + 1)
>>> sum(rr)
CRootOf(x**3 - 3*x + 1, 0) + CRootOf(x**3 - 3*x + 1, 1) + CRootOf(x**3 - 3*x + 1, 2)

The functions simplify and radsimp cannot simplify this expression. The minimal polynomial, however, is computed correctly:

>>> minimal_polymial(sum(rr))
_x

From this we can conclude that the sum is 0. Is there a direct way of making sympy simplify this sum of roots?

Upvotes: 0

Views: 262

Answers (1)

coproc
coproc

Reputation: 6257

The following function computes the rational number equal to an algebraic term if possible:

import sympy as sp

# try to simplify an algebraic term to a rational number
def try_simplify_to_rational(expr):
  try:
    float(expr) # does the expression evaluate to a real number?
    minPoly = sp.poly(sp.minimal_polynomial(expr))
    print('minimal polynomial:', minPoly)
    if len(minPoly.monoms()) == 1: # minPoly == x
      return 0
    if minPoly.degree() == 1: # minPoly == a*x + b
      a,b = minPoly.coeffs()
      return sp.Rational(-b, a)
  except TypeError:
    pass # expression does not evaluate to a real number
  except sp.polys.polyerrors.NotAlgebraic:
    pass # expression does not evaluate to an algebraic number
  except Exception as exc:
    print("unexpected exception:", str(exc))
  print('simplification to rational number not successful')
  return expr # simplification not successful

See the working example:

x = sp.symbols('x')
rr = sp.real_roots(x**3 - 3*x + 1)
# sum of roots equals (-1)*coefficient of x^2, here 0
print(sp.simplify(sum(rr)))
print(try_simplify_to_rational(sum(rr))) # -> 0

A more elaborate function computing also simple radical expressions is proposed in sympy issue #19726.

Upvotes: 1

Related Questions