Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
24942: move roots solving of univariate SR polynomial ring
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Mar 10, 2018
1 parent 3750eaa commit fcd9773
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 49 deletions.
49 changes: 0 additions & 49 deletions src/sage/rings/polynomial/polynomial_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -7318,12 +7318,6 @@ cdef class Polynomial(CommutativeAlgebraElement):
If L is SR, then the roots will be radical expressions,
computed as the solutions of a symbolic polynomial expression.
At the moment this delegates to
:meth:`sage.symbolic.expression.Expression.solve`
which in turn uses Maxima to find radical solutions.
Some solutions may be lost in this approach.
Once :trac:`17516` gets implemented, all possible radical
solutions should become available.
If L is AA or RIF, and K is ZZ, QQ, or AA, then the root isolation
algorithm sage.rings.polynomial.real_roots.real_roots() is used.
Expand Down Expand Up @@ -7404,19 +7398,6 @@ cdef class Polynomial(CommutativeAlgebraElement):
sage: [abs(p(rt)) < eps for rt in rts] == [True]*50
True
This shows that the issue at :trac:`10901` is fixed::
sage: a = var('a'); R.<x> = SR[]
sage: f = x - a
sage: f.roots(RR)
Traceback (most recent call last):
...
TypeError: Cannot evaluate symbolic expression to a numeric value.
sage: f.roots(CC)
Traceback (most recent call last):
...
TypeError: Cannot evaluate symbolic expression to a numeric value.
We can find roots of polynomials defined over `\ZZ` or `\QQ`
over the `p`-adics, see :trac:`15422`::
Expand Down Expand Up @@ -7557,36 +7538,6 @@ cdef class Polynomial(CommutativeAlgebraElement):
else:
return [rt for (rt, mult) in rts_mult]

from sage.symbolic.ring import SR
if L is SR:
if self.degree() == 2:
from sage.functions.other import sqrt
from sage.libs.pynac.pynac import I
coeffs = self.list()
D = coeffs[1]*coeffs[1] - 4*coeffs[0]*coeffs[2]
if D > 0:
l = [((-coeffs[1]-sqrt(D))/2/coeffs[2], 1),
((-coeffs[1]+sqrt(D))/2/coeffs[2], 1)]
elif D < 0:
l = [((-coeffs[1]-I*sqrt(-D))/2/coeffs[2], 1),
((-coeffs[1]+I*sqrt(-D))/2/coeffs[2], 1)]
else:
l = [(-coeffs[1]/2/coeffs[2]), 2]
if multiplicities:
return l
else:
return [val for val,m in l]
vname = 'do_not_use_this_name_in_a_polynomial_coefficient'
var = SR(vname)
expr = self(var)
rts = expr.solve(var,
explicit_solutions=True,
multiplicities=multiplicities)
if multiplicities:
return [(rt.rhs(), mult) for rt, mult in zip(*rts)]
else:
return [rt.rhs() for rt in rts]

if L != K or is_AlgebraicField_common(L):
# So far, the only "special" implementations are for real
# and complex root isolation and for p-adic factorization
Expand Down
62 changes: 62 additions & 0 deletions src/sage/symbolic/ring.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,68 @@ cdef class SymbolicRing(CommutativeRing):

return _the_element.subs(d, **kwds)

def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True,
algorithm=None):
r"""
At the moment this delegates to
:meth:`sage.symbolic.expression.Expression.solve`
which in turn uses Maxima to find radical solutions.
Some solutions may be lost in this approach.
Once :trac:`17516` gets implemented, all possible radical
solutions should become available.
EXAMPLES::
sage: R.<x> = SR[]
sage: (x^2 + x + 1).roots(SR)
[(-1/2*I*sqrt(3) - 1/2, 1), (1/2*I*sqrt(3) - 1/2, 1)]
sage: (x^3 + x^2 + x + 1).roots(SR)
[(-I, 1), (I, 1), (-1, 1)]
TESTS:
This shows that the issue at :trac:`10901` is fixed::
sage: a = var('a'); R.<x> = SR[]
sage: f = x - a
sage: f.roots(RR)
Traceback (most recent call last):
...
TypeError: unable to convert 'do_not_use_this_name_in_a_polynomial_coefficient' to a real number
sage: f.roots(CC)
Traceback (most recent call last):
...
NameError: name 'do_not_use_this_name_in_a_polynomial_coefficient' is not defined
"""
if p.degree() == 2:
from sage.functions.other import sqrt
from sage.libs.pynac.pynac import I
coeffs = p.list()
D = coeffs[1]*coeffs[1] - 4*coeffs[0]*coeffs[2]
if D > 0:
l = [((-coeffs[1]-sqrt(D))/2/coeffs[2], 1),
((-coeffs[1]+sqrt(D))/2/coeffs[2], 1)]
elif D < 0:
l = [((-coeffs[1]-I*sqrt(-D))/2/coeffs[2], 1),
((-coeffs[1]+I*sqrt(-D))/2/coeffs[2], 1)]
else:
l = [(-coeffs[1]/2/coeffs[2]), 2]
if multiplicities:
return l
else:
return [val for val,m in l]
L = self if ring is None else ring
vname = 'do_not_use_this_name_in_a_polynomial_coefficient'
var = L(vname)
expr = p(var)
rts = expr.solve(var,
explicit_solutions=True,
multiplicities=multiplicities)
if multiplicities:
return [(rt.rhs(), mult) for rt, mult in zip(*rts)]
else:
return [rt.rhs() for rt in rts]

def subring(self, *args, **kwds):
r"""
Create a subring of this symbolic ring.
Expand Down

0 comments on commit fcd9773

Please sign in to comment.