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

Commit

Permalink
#15114 remove coercions from RR, RDF, float to RIF
Browse files Browse the repository at this point in the history
Mainly because it makes it hard to use interval arithmetic reliably. See
the discussion on the trac ticket for details.

Note that RR → RIF is currently an exception among interval fields:
there are no coercions CC → CIF, RR → RBF, RR → CBF, or CC → CBF.
There are, however, coercions CC → SR and SR → CIF, but the bug here is
the existence of the latter, not that their composition is not defined.

fixR
  • Loading branch information
mezzarobba committed Dec 19, 2020
1 parent c4a802d commit 315ddc2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 49 deletions.
12 changes: 4 additions & 8 deletions src/sage/categories/pushout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2542,14 +2542,10 @@ def merge(self, other):
We check that :trac:`12353` has been resolved::
sage: RealIntervalField(53)(-1) > RR(1)
False
sage: RealIntervalField(54)(-1) > RR(1)
False
sage: RealIntervalField(54)(1) > RR(-1)
True
sage: RealIntervalField(53)(1) > RR(-1)
True
sage: RIF(1) > RR(1)
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for >: 'Real Interval Field with 53 bits of precision' and 'Real Field with 53 bits of precision'
We check that various pushouts work::
Expand Down
71 changes: 30 additions & 41 deletions src/sage/rings/real_mpfi.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ satisfying, but we have chosen the latter.
sage: a = R(1.25)
sage: a.str(style='brackets')
'[1.2 .. 1.3]'
sage: a == 1.25
sage: a == 5/4
True
sage: a == 2
False
Expand Down Expand Up @@ -228,21 +228,17 @@ specified if given a non-interval and an interval::
sage: val.overlaps(ref) # known bug
False
TESTS:
Comparisons with numpy types are right (see :trac:`17758` and :trac:`18076`)::
TESTS::
sage: import numpy
sage: RIF(0,1) < numpy.float('2')
True
sage: RIF(0,1) <= numpy.float('1')
True
sage: RIF(0,1) <= numpy.float('0.5')
False
sage: RIF(2) == numpy.int8('2')
True
sage: numpy.int8('2') == RIF(2)
True
sage: RIF(0,1) < numpy.float('2')
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for <: ...
"""

# ****************************************************************************
Expand Down Expand Up @@ -759,14 +755,11 @@ cdef class RealIntervalField_class(Field):
- this mpfi field itself
- any mpfr real field with precision that is as large as this
one
- any other mpfi real field with precision that is as large as
this one
- anything that canonically coerces to the mpfr real field
with same precision as ``self``.
- some exact or lazy parents representing subsets of the real
numbers, such as ``ZZ``, ``QQ``, ``AA``, and ``RLF``.
Values which can be exactly represented as a floating-point number
are coerced to a precise interval, with upper and lower bounds
Expand All @@ -781,48 +774,43 @@ cdef class RealIntervalField_class(Field):
To: Real Interval Field with 53 bits of precision
sage: phi(3^100)
5.153775207320114?e47
sage: phi = RIF.coerce_map_from(float); phi
Coercion map:
From: Set of Python objects of class 'float'
::
sage: phi = RIF.coerce_map_from(AA); phi
Conversion via _real_mpfi_ method map:
From: Algebraic Real Field
To: Real Interval Field with 53 bits of precision
sage: phi(math.pi)
3.1415926535897932?
Coercion can decrease precision, but not increase it::
sage: phi = RIF.coerce_map_from(RealIntervalField(100)); phi
Coercion map:
From: Real Interval Field with 100 bits of precision
To: Real Interval Field with 53 bits of precision
sage: phi = RIF.coerce_map_from(RealField(100)); phi
Coercion map:
From: Real Field with 100 bits of precision
To: Real Interval Field with 53 bits of precision
sage: print(RIF.coerce_map_from(RealIntervalField(20)))
None
sage: print(RIF.coerce_map_from(RealField(20)))
None
::
There are no coercions from plain floating-point numbers to intervals
(otherwise the rounding errors resulting from floating-point operations
could easily lead to incorrect interval results)::
sage: phi = RIF.coerce_map_from(AA); phi
Conversion via _real_mpfi_ method map:
From: Algebraic Real Field
To: Real Interval Field with 53 bits of precision
sage: RIF.has_coerce_map_from(RR)
False
sage: RIF.has_coerce_map_from(RDF)
False
sage: RIF.has_coerce_map_from(float)
False
"""
prec = self.__prec

# Direct and efficient conversions
if S is ZZ or S is QQ:
return True
if S is float or S is int or S is long:
if S is int or S is long:
return True
if isinstance(S, RealIntervalField_class):
return (<RealIntervalField_class>S).__prec >= prec
if isinstance(S, RealField_class):
return (<RealField_class>S).__prec >= prec
if S is RDF:
return 53 >= prec
from .number_field.number_field import NumberField_quadratic
if isinstance(S, NumberField_quadratic):
return S.discriminant() > 0
Expand Down Expand Up @@ -2550,7 +2538,7 @@ cdef class RealIntervalFieldElement(RingElement):
sage: I = RIF(e, pi)
sage: a, b = I.bisection()
sage: a.intersection(b) == I.center()
sage: a.intersection(b) == RIF(I.center())
True
sage: a.union(b).endpoints() == I.endpoints()
True
Expand Down Expand Up @@ -4385,7 +4373,7 @@ cdef class RealIntervalFieldElement(RingElement):
sage: r = RIF(16.0); r.log10()
1.204119982655925?
sage: r.log() / log(10.0)
sage: r.log() / RIF(10).log()
1.204119982655925?
::
Expand Down Expand Up @@ -4976,7 +4964,8 @@ cdef class RealIntervalFieldElement(RingElement):
-3.54490770181104?
sage: gamma(-1/2).n(100) in RIF(-1/2).gamma()
True
sage: 0 in (RealField(2000)(-19/3).gamma() - RealIntervalField(1000)(-19/3).gamma())
sage: RIF1000 = RealIntervalField(1000)
sage: 0 in (RIF1000(RealField(2000)(-19/3).gamma()) - RIF1000(-19/3).gamma())
True
sage: gamma(RIF(100))
9.33262154439442?e155
Expand Down Expand Up @@ -5005,7 +4994,7 @@ cdef class RealIntervalFieldElement(RingElement):
[-infinity .. +infinity]
"""
x = self._new()
if self > 1.462:
if self.lower() > 1.462:
# increasing
mpfr_gamma(&x.value.left, &self.value.left, MPFR_RNDD)
mpfr_gamma(&x.value.right, &self.value.right, MPFR_RNDU)
Expand All @@ -5017,7 +5006,7 @@ cdef class RealIntervalFieldElement(RingElement):
elif self.contains_zero():
# [-infinity, infinity]
return ~self
elif self < 1.461:
elif self.upper() < 1.461:
# 0 < self as well, so decreasing
mpfr_gamma(&x.value.left, &self.value.right, MPFR_RNDD)
mpfr_gamma(&x.value.right, &self.value.left, MPFR_RNDU)
Expand Down

0 comments on commit 315ddc2

Please sign in to comment.