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

Commit 39bfd96

Browse files
committed
24440: Infinite loop from converting to QQbar
1 parent 0a674fd commit 39bfd96

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

src/sage/symbolic/expression_conversions.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,13 +956,28 @@ def composition(self, ex, operator):
956956
sage: a.composition(exp(pi*I*RR(1), hold=True), exp)
957957
Traceback (most recent call last):
958958
...
959-
TypeError: no canonical coercion from Real Field with 53 bits of precision to Rational Field
959+
TypeError: unable to convert e^(1.00000000000000*I*pi) to Algebraic Field
960960
sage: a.composition(exp(pi*CC.gen(), hold=True), exp)
961961
Traceback (most recent call last):
962962
...
963-
TypeError: no canonical coercion from Real Field with 53 bits of precision to Rational Field
963+
TypeError: unable to convert e^(1.00000000000000*I*pi) to Algebraic Field
964964
sage: bool(sin(pi*RR("0.7000000000000002")) > 0)
965965
True
966+
967+
Check that :trac:`24440` is fixed::
968+
969+
sage: QQbar(tanh(pi + 0.1))
970+
Traceback (most recent call last):
971+
...
972+
ValueError: unable to represent as an algebraic number
973+
sage: QQbar(sin(I*pi/7))
974+
Traceback (most recent call last):
975+
...
976+
ValueError: unable to represent as an algebraic number
977+
sage: QQbar(sin(I*pi/7, hold=True))
978+
Traceback (most recent call last):
979+
...
980+
ValueError: unable to represent as an algebraic number
966981
"""
967982
func = operator
968983
operand, = ex.operands()
@@ -971,11 +986,16 @@ def composition(self, ex, operator):
971986
# Note that comparing functions themselves goes via maxima, and is SLOW
972987
func_name = repr(func)
973988
if func_name == 'exp':
974-
if operand.real():
989+
if operand.is_trivial_zero():
990+
return self.field(1)
991+
if not (SR(-1).sqrt()*operand).is_real():
975992
raise ValueError("unable to represent as an algebraic number")
976993
# Coerce (not convert, see #22571) arg to a rational
977994
arg = operand.imag()/(2*ex.parent().pi())
978-
rat_arg = QQ.coerce(arg.pyobject())
995+
try:
996+
rat_arg = QQ.coerce(arg.pyobject())
997+
except TypeError:
998+
raise TypeError("unable to convert %r to %s"%(ex, self.field))
979999
res = QQbar.zeta(rat_arg.denom())**rat_arg.numer()
9801000
elif func_name in ['sin', 'cos', 'tan']:
9811001
exp_ia = exp(SR(-1).sqrt()*operand)._algebraic_(QQbar)
@@ -986,6 +1006,8 @@ def composition(self, ex, operator):
9861006
else:
9871007
res = -QQbar.zeta(4)*(exp_ia - ~exp_ia)/(exp_ia + ~exp_ia)
9881008
elif func_name in ['sinh', 'cosh', 'tanh']:
1009+
if not (SR(-1).sqrt()*operand).is_real():
1010+
raise ValueError("unable to represent as an algebraic number")
9891011
exp_a = exp(operand)._algebraic_(QQbar)
9901012
if func_name == 'sinh':
9911013
res = (exp_a - ~exp_a)/2

0 commit comments

Comments
 (0)