Skip to content

Commit

Permalink
Trac #20756: sign is slow (if not wrong) for number field elements
Browse files Browse the repository at this point in the history
{{{
sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^100 - 3, embedding=AA(3)**(1/100))
sage: %time sign(a)
CPU times: user 1.34 s, sys: 0 ns, total: 1.34 s
Wall time: 1.33 s
1
sage: b = continued_fraction(a).convergent(20) - a
sage: sign(b)
sgn(-1/1495877943276*(1/4)^(1/5)*(-(sqrt(5) - I*sqrt(-2*sqrt(5) + 10) +
1)*(-3^(1/4))^(1/5))^(1/5)*(373969485819*sqrt(5) -
373969485819*I*sqrt(-2*sqrt(5) + 10) + 373969485819) +
378100611523/373969485819)
}}}
With the branch applied
{{{
sage: %time sign(a)
CPU times: user 4 ms, sys: 0 ns, total: 4 ms
Wall time: 4.65 ms
1
sage: b = continued_fraction(a).convergent(20) - a
sage: %time sign(b)
CPU times: user 4 ms, sys: 0 ns, total: 4 ms
Wall time: 6.02 ms
-1
}}}

URL: http://trac.sagemath.org/20756
Reported by: vdelecroix
Ticket author(s): Vincent Delecroix
Reviewer(s): Marc Mezzarobba
  • Loading branch information
Release Manager authored and vbraun committed Jun 15, 2016
2 parents 54cfcb0 + 31e8874 commit 167fc8d
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions src/sage/rings/number_field/number_field_element.pyx
Expand Up @@ -930,6 +930,58 @@ cdef class NumberFieldElement(FieldElement):
"""
return self.abs(prec=53, i=None)

def sign(self):
r"""
Return the sign of this algebraic number (if a real embedding is well
defined)
EXAMPLES::
sage: K.<a> = NumberField(x^3 - 2, embedding=AA(2)**(1/3))
sage: K.zero().sign()
0
sage: K.one().sign()
1
sage: (-K.one()).sign()
-1
sage: a.sign()
1
sage: (a - 234917380309015/186454048314072).sign()
1
sage: (a - 3741049304830488/2969272800976409).sign()
-1
If the field is not embedded in real numbers, this method will only work
for rational elements::
sage: L.<b> = NumberField(x^4 - x - 1)
sage: b.sign()
Traceback (most recent call last):
...
TypeError: sign not well defined since no real embedding is
specified
sage: L(-33/125).sign()
-1
sage: L.zero().sign()
0
"""
if ZZX_deg(self.__numerator) == -1:
return 0
if ZZX_deg(self.__numerator) == 0:
return ZZ_sign(ZZX_coeff(self.__numerator, 0))

if not (<number_field_base.NumberField> self._parent)._embedded_real:
raise TypeError("sign not well defined since no real embedding is specified")

from sage.rings.real_mpfi import RealIntervalField
i = 0
a = RealIntervalField(53)(self)
while a.contains_zero():
i += 1
a = RealIntervalField(53<<i)(self)
return a.unique_sign()

def floor(self):
r"""
Return the floor of this number field element.
Expand Down Expand Up @@ -968,7 +1020,7 @@ cdef class NumberFieldElement(FieldElement):
...
TypeError: floor not uniquely defined since no real embedding is specified
"""
if ZZX_deg(self.__numerator) == 0:
if ZZX_deg(self.__numerator) <= 0:
return self._rational_().floor()

if not (<number_field_base.NumberField> self._parent)._embedded_real:
Expand Down Expand Up @@ -1024,7 +1076,7 @@ cdef class NumberFieldElement(FieldElement):
...
TypeError: ceil not uniquely defined since no real embedding is specified
"""
if ZZX_deg(self.__numerator) == 0:
if ZZX_deg(self.__numerator) <= 0:
return self._rational_().ceil()

if not (<number_field_base.NumberField> self._parent)._embedded_real:
Expand Down

0 comments on commit 167fc8d

Please sign in to comment.