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

Commit

Permalink
Merge branch 'u/cheuberg/rings/RIF-min-max' (#17198) of git://trac.sa…
Browse files Browse the repository at this point in the history
…gemath.org/sage into fsm/fourier_2
  • Loading branch information
cheuberg committed Feb 7, 2015
2 parents 85836e1 + 27080b5 commit 8fe46d0
Showing 1 changed file with 143 additions and 134 deletions.
277 changes: 143 additions & 134 deletions src/sage/rings/real_mpfi.pyx
Expand Up @@ -3690,13 +3690,14 @@ cdef class RealIntervalFieldElement(sage.structure.element.RingElement):
mpfi_union(x.value, self.value, other_intv.value)
return x

def min(self, _other):
def min(self, *_others):
"""
Return an interval containing the minimum of ``self`` and ``other``.
Return an interval containing the minimum of ``self`` and the
arguments.
EXAMPLES::
sage: a=RIF(-1, 1).min(0).endpoints()
sage: a = RIF(-1, 1).min(0).endpoints()
sage: a[0] == -1.0 and a[1].abs() == 0.0 # in MPFI, the sign of 0.0 is not specified
True
sage: RIF(-1, 1).min(pi).endpoints()
Expand All @@ -3705,31 +3706,87 @@ cdef class RealIntervalFieldElement(sage.structure.element.RingElement):
(-100.000000000000, 1.00000000000000)
sage: RIF(-1, 1).min(RIF(-100, 0)).endpoints()
(-100.000000000000, 0.000000000000000)
sage: RIF(-1, 1).min(RIF(-100, 2), RIF(-200, -3)).endpoints()
(-200.000000000000, -3.00000000000000)
Note that if the minimum is one of the given elements,
that element will be returned. ::
sage: a = RIF(-1, 1)
sage: b = RIF(2, 3)
sage: c = RIF(3, 4)
sage: c.min(a, b) is a
True
sage: b.min(a, c) is a
True
sage: a.min(b, c) is a
True
It might also be convenient to call the method as a function::
sage: from sage.rings.real_mpfi import RealIntervalFieldElement
sage: RealIntervalFieldElement.min(a, b, c) is a
True
sage: elements = [a, b, c]
sage: RealIntervalFieldElement.min(*elements) is a
True
The generic min does not always do the right thing::
sage: min(0, RIF(-1, 1))
0
sage: min(RIF(-1, 1), RIF(-100, 100)).endpoints()
(-1.00000000000000, 1.00000000000000)
.. SEEALSO::
:meth:`~sage.rings.real_mpfi.RealIntervalFieldElement.max`
TESTS::
sage: a.min('x')
Traceback (most recent call last):
...
TypeError: Unable to convert number to real interval.
"""
cdef RealIntervalFieldElement constructed
cdef RealIntervalFieldElement result
cdef RealIntervalFieldElement other
if isinstance(_other, RealIntervalFieldElement):
other = <RealIntervalFieldElement>_other
else:
other = self._parent(_other)
if mpfr_cmp(&self.value.right, &other.value.left) <= 0:
return self
elif mpfr_cmp(&other.value.right, &self.value.left) <= 0:
return other
cdef RealIntervalFieldElement x = self._new()
mpfr_min(&x.value.left, &self.value.left, &other.value.left, GMP_RNDD)
mpfr_min(&x.value.right, &self.value.right, &other.value.right, GMP_RNDU)
return x
cdef bint initialized

def max(self, _other):
"""
Return an interval containing the maximum of ``self`` and ``other``.
initialized = False
result = self

for _other in _others:
if isinstance(_other, RealIntervalFieldElement):
other = <RealIntervalFieldElement>_other
else:
other = self._parent(_other)

if mpfr_cmp(&result.value.right, &other.value.left) <= 0:
pass
elif mpfr_cmp(&other.value.right, &result.value.left) <= 0:
result = other
else:
if not initialized:
constructed = self._new()
initialized = True
mpfr_min(&constructed.value.left,
&result.value.left,
&other.value.left,
GMP_RNDD)
mpfr_min(&constructed.value.right,
&result.value.right,
&other.value.right,
GMP_RNDU)
result = constructed

return result

def max(self, *_others):
"""
Return an interval containing the maximum of ``self`` and the
arguments.
EXAMPLES::
Expand All @@ -3739,27 +3796,83 @@ cdef class RealIntervalFieldElement(sage.structure.element.RingElement):
(2.00000000000000, 3.00000000000000)
sage: RIF(-1, 1).max(RIF(-100, 100)).endpoints()
(-1.00000000000000, 100.000000000000)
sage: RIF(-1, 1).max(RIF(-100, 100), RIF(5, 10)).endpoints()
(5.00000000000000, 100.000000000000)
Note that if the maximum is one of the given elements,
that element will be returned. ::
sage: a = RIF(-1, 1)
sage: b = RIF(2, 3)
sage: c = RIF(3, 4)
sage: c.max(a, b) is c
True
sage: b.max(a, c) is c
True
sage: a.max(b, c) is c
True
It might also be convenient to call the method as a function::
sage: from sage.rings.real_mpfi import RealIntervalFieldElement
sage: RealIntervalFieldElement.max(a, b, c) is c
True
sage: elements = [a, b, c]
sage: RealIntervalFieldElement.max(*elements) is c
True
The generic max does not always do the right thing::
sage: max(0, RIF(-1, 1))
0
sage: max(RIF(-1, 1), RIF(-100, 100)).endpoints()
(-1.00000000000000, 1.00000000000000)
.. SEEALSO::
:meth:`~sage.rings.real_mpfi.RealIntervalFieldElement.min`
TESTS::
sage: a.max('x')
Traceback (most recent call last):
...
TypeError: Unable to convert number to real interval.
"""
cdef RealIntervalFieldElement constructed
cdef RealIntervalFieldElement result
cdef RealIntervalFieldElement other
if isinstance(_other, RealIntervalFieldElement):
other = <RealIntervalFieldElement>_other
else:
other = self._parent(_other)
if mpfr_cmp(&self.value.right, &other.value.left) <= 0:
return other
elif mpfr_cmp(&other.value.right, &self.value.left) <= 0:
return self
cdef RealIntervalFieldElement x = self._new()
mpfr_max(&x.value.left, &self.value.left, &other.value.left, GMP_RNDD)
mpfr_max(&x.value.right, &self.value.right, &other.value.right, GMP_RNDU)
return x
cdef bint initialized

initialized = False
result = self

for _other in _others:
if isinstance(_other, RealIntervalFieldElement):
other = <RealIntervalFieldElement>_other
else:
other = self._parent(_other)

if mpfr_cmp(&result.value.right, &other.value.left) <= 0:
result = other
elif mpfr_cmp(&other.value.right, &result.value.left) <= 0:
pass
else:
if not initialized:
constructed = self._new()
initialized = True

mpfr_max(&constructed.value.left,
&result.value.left,
&other.value.left,
GMP_RNDD)
mpfr_max(&constructed.value.right,
&result.value.right,
&other.value.right,
GMP_RNDU)
result = constructed

return result

############################
# Special Functions
Expand Down Expand Up @@ -5030,107 +5143,3 @@ def __create__RealIntervalFieldElement_version1(parent, lower, upper):
2.226?
"""
return RealIntervalFieldElement(parent, (lower, upper))

def max_RIF(elements):
r"""
Compute the maximum of
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements.
INPUT:
- ``elements`` -- iterable of
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements.
OUTPUT:
A :class:`~sage.rings.real_mpfi.RealIntervalFieldElement` element.
EXAMPLES::
sage: a = RIF(1, 4)
sage: b = RIF(2, 3)
sage: from sage.rings.real_mpfi import max_RIF
sage: max_RIF([a, b]).endpoints()
(2.00000000000000, 4.00000000000000)
sage: max_RIF([b, a]).endpoints()
(2.00000000000000, 4.00000000000000)
For two elements, this corresponds to
:meth:`sage.rings.real_mpfi.RealIntervalFieldElement.max`::
sage: a.max(b).endpoints()
(2.00000000000000, 4.00000000000000)
sage: b.max(a).endpoints()
(2.00000000000000, 4.00000000000000)
Note that the standard Python ``max`` function does not handle
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements
correctly::
sage: max(a, b).endpoints()
(1.00000000000000, 4.00000000000000)
sage: max(b, a).endpoints()
(2.00000000000000, 3.00000000000000)
.. SEEALSO::
:meth:`sage.rings.real_mpfi.RealIntervalFieldElement.max`,
:func:`min_RIF`
"""
# we iterate twice, so store as a list.
data = list(elements)
max_upper = max(e.upper() for e in data)
max_lower = max(e.lower() for e in data)
return data[0].parent()(max_lower, max_upper)

def min_RIF(elements):
r"""
Compute the minimum of
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements.
INPUT:
- ``elements`` -- iterable of
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements.
OUTPUT:
A :class:`~sage.rings.real_mpfi.RealIntervalFieldElement` element.
EXAMPLES::
sage: a = RIF(1, 4)
sage: b = RIF(2, 3)
sage: from sage.rings.real_mpfi import min_RIF
sage: min_RIF([a, b]).endpoints()
(1.00000000000000, 3.00000000000000)
sage: min_RIF([b, a]).endpoints()
(1.00000000000000, 3.00000000000000)
For two elements, this corresponds to
:meth:`sage.rings.real_mpfi.RealIntervalFieldElement.min`::
sage: a.min(b).endpoints()
(1.00000000000000, 3.00000000000000)
sage: b.min(a).endpoints()
(1.00000000000000, 3.00000000000000)
Note that the standard Python ``min`` function does not handle
:class:`~sage.rings.real_mpfi.RealIntervalFieldElement` elements
correctly::
sage: min(a, b).endpoints()
(1.00000000000000, 4.00000000000000)
sage: min(b, a).endpoints()
(2.00000000000000, 3.00000000000000)
.. SEEALSO::
:meth:`sage.rings.real_mpfi.RealIntervalFieldElement.min`,
:func:`max_RIF`
"""
# we iterate twice, so store as a list.
data = list(elements)
min_upper = min(e.upper() for e in data)
min_lower = min(e.lower() for e in data)
return data[0].parent()(min_lower, min_upper)

0 comments on commit 8fe46d0

Please sign in to comment.