Skip to content

Commit

Permalink
Trac #20064: Bug in sqrt in QQbar
Browse files Browse the repository at this point in the history
See #18836.  This bug is holding up that (and also #20028).  The
following code creates an elemnt d of QQbar and tries to do d.sqrt().
It fails unless you call d.imag().is_zero() first.
{{{
K.<i> = QuadraticField(-1)

# define a low-precision embedding from K to CC:

emb = K.embeddings(CC)[1]

# extend this to the closest embedding into QQbar:

old_gen = emb(K.gen())
rr = K.defining_polynomial().roots(QQbar, multiplicities=False)
diffs = [(CC(r)-old_gen).abs() for r in rr]
new_gen = rr[diffs.index(min(diffs))]
emb0 = K.hom([new_gen], check=False)

# Take a polynomial with 3 roots in K:

e1 = -4+i
e2 = 1+i
e3 = 3-2*i
print("Original ei: %s with parent %s" % ([e1,e2,e3],parent(e1)))
x = polygen(K)
pol = (x-e1)*(x-e2)*(x-e3)

# Find the roots again in QQbar:

pol0 = PolynomialRing(QQbar,'x')([emb0(c) for c in list(pol)])
e1, e2, e3 = pol0.roots(QQbar,multiplicities=False)
print("Roots ei: %s with parent %s" % ([e1,e2,e3],parent(e1)))

# Attempt to compute sqrt(e1-e2) from these:

d = e1-e2
print("d=%s with parent %s" % (d,d.parent()))
# If the next 2 lines are commented out, an error is raised in the sqrt!
s = d.imag().is_zero()
print("d.imag().is_zero()=%s" % s)
print("d=%s with parent %s" % (d,d.parent()))
d = d.sqrt()
print("d=%s" % d)
}}}

URL: http://trac.sagemath.org/20064
Reported by: cremona
Ticket author(s): Nils Bruin
Reviewer(s): John Cremona
  • Loading branch information
Release Manager authored and vbraun committed Feb 18, 2016
2 parents 90ac40f + 48c12ef commit f9746f5
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/sage/rings/real_mpfi.pyx
Expand Up @@ -3191,6 +3191,45 @@ cdef class RealIntervalFieldElement(RingElement):
else:
raise ValueError("interval does not have a unique sign")

def argument(self):
r"""
The argument of this interval, if it is well-defined, in the
complex sense. Otherwise raises a ``ValueError``.
OUTPUT:
- an element of the parent of this interval (0 or pi)
EXAMPLES::
sage: RIF(1).argument()
0
sage: RIF(-1).argument()
3.141592653589794?
sage: RIF(0,1).argument()
0
sage: RIF(-1,0).argument()
3.141592653589794?
sage: RIF(0).argument()
Traceback (most recent call last):
...
ValueError: Can't take the argument of an exact zero
sage: RIF(-1,1).argument()
Traceback (most recent call last):
...
ValueError: Can't take the argument of interval strictly containing zero
"""
k=self.parent()
if mpfi_is_zero(self.value):
raise ValueError("Can't take the argument of an exact zero")
if mpfi_is_nonneg(self.value):
return k.zero()
elif mpfi_is_nonpos(self.value):
return k.pi()
else:
raise ValueError("Can't take the argument of interval strictly containing zero")

def unique_floor(self):
"""
Returns the unique floor of this interval, if it is well defined,
Expand Down

0 comments on commit f9746f5

Please sign in to comment.