what should be "in RIF"?

63 views
Skip to first unread message

Ralf Stephan

unread,
Mar 19, 2015, 5:48:56 AM3/19/15
to sage-...@googlegroups.com
Hello,
single reals can be represented in RIF. But they are not elements
of that field, right? Due to some code quirks (discussed in #12984)
we have at the moment:
sage: 1/2 in RIF
True
sage
: 1/5 in RIF
False
sage
: 3.14 in RIF
True
sage
: 3 in RIF
True
sage
: pi in RIF
False

As this behaviour is a RIF specialty it is more effective (and better design)
to implement a dedicated RIF.__contains__ method than to fix
the quirky Parent.__contains__. But what should be "in RIF"?
Only intervals? Intervals and reals?

Regards,

William Stein

unread,
Mar 19, 2015, 12:33:04 PM3/19/15
to sage-devel
Please don't implement a new special case __contains__ just yet. That
could make things harder and more confusing, since it will definitely
break the intention of contains, which is that "a in RIF" means that
there is b in RIF such that a==b is true, and probably mask a deeper
issue. The problem above is being caused by this:

sage: RIF(1/5) == RIF(1/5)
False

What's going on there? I don't know. But let's sort out why RIF(1/5)
isn't equal to itself. Even more surprising

sage: a = RIF(1/5)
sage: a == a
False
sage: a is a
True

However,

sage: a.lower() == a.lower()
True
sage: a.upper() == a.upper()
True

The code to compare intervals is here:

https://github.com/sagemath/sage/blob/master/src/sage/rings/real_mpfi.pyx#L3517

It looks like it just compares the endpoints, so I don't understand
why a == a is false...

Anyway, it's really hard looking at the code to come up with any
argument for why a == a shouldn't be true!

> Only intervals? Intervals and reals?
>
> Regards,
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-devel+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-devel.
> For more options, visit https://groups.google.com/d/optout.



--
William (http://wstein.org)

Clemens Heuberger

unread,
Mar 19, 2015, 12:40:34 PM3/19/15
to sage-...@googlegroups.com
Am 2015-03-19 um 17:32 schrieb William Stein:
> On Thu, Mar 19, 2015 at 2:48 AM, Ralf Stephan <gtr...@gmail.com> wrote:
> sage: RIF(1/5) == RIF(1/5)
> False
>
> What's going on there? I don't know. But let's sort out why RIF(1/5)
> isn't equal to itself. Even more surprising

Two RealIntervalFieldElements are only equal, if they are exact.
As RIF(1/5) is not exact, it is not equal to itself.

We chose a different behaviour for RealBalls implemented with Frederik's arb
library: there, "is" is a subset of "==" (but otherwise, RBF(1/5) is still not
equal to RBF(1/5).

Regards,

CH

Marc Mezzarobba

unread,
Mar 19, 2015, 12:40:49 PM3/19/15
to sage-...@googlegroups.com
William Stein wrote:
> sage: a = RIF(1/5)
> sage: a == a
> False
> sage: a is a
> True

That's how interval arithmetic usually works! Quoting from the
documentation of real_mpfi:

| Comparison operations (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``)
| return ``True`` if every value in the first interval has the given
| relation to every value in the second interval.
| [...]
| This convention for comparison operators has good and bad points.
| [...]

> However,
>
> sage: a.lower() == a.lower()
> True
> sage: a.upper() == a.upper()
> True
>
> The code to compare intervals is here:
>
>
https://github.com/sagemath/sage/blob/master/src/sage/rings/real_mpfi.pyx#L3517
>
> It looks like it just compares the endpoints, so I don't understand
> why a == a is false...

That's because you are looking at the wrong function; intervals also
implement richcmp.

--
Marc

William Stein

unread,
Mar 19, 2015, 12:58:13 PM3/19/15
to sage-devel
On Thu, Mar 19, 2015 at 9:40 AM, Marc Mezzarobba <ma...@mezzarobba.net> wrote:
> William Stein wrote:
>> sage: a = RIF(1/5)
>> sage: a == a
>> False
>> sage: a is a
>> True
>
> That's how interval arithmetic usually works! Quoting from the
> documentation of real_mpfi:
>
> | Comparison operations (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``)
> | return ``True`` if every value in the first interval has the given
> | relation to every value in the second interval.
> | [...]
> | This convention for comparison operators has good and bad points.
> | [...]

OK, fair point. I guess the idea is that one thinks of an element
of RIF not as an interval, but as "some unspecified element of an
interval". It should be called "unspecified element of an interval
arithmetic"...

It says:'Comparison operations (``==``, ``!=``, ``<``, ``<=``, ``>``,
``>=``) return ``True`` if every value in the first interval has the
given relation to every value in the second interval. The ``cmp(a,
b)`` function works differently; it compares two intervals
lexicographically. (However, the behavior is not specified if given a
non-interval and an interval.)'

Is there a proposal to leverage the remark " (However, the behavior is
not specified if given a non-interval and an interval.)", and change
the behavior of

sage: RIF(1/5) == 1/5

Right now I'm guessing the above comparison is done by first coercing
1/5 to RIF, then comparing, which is False.

Anyway, you've convinced me that "1/5 in RIF" shouldn't be true, since
there is no element of RIF that is equal to 1/5. Due to things being
base 2 in computers, there's a funny thing in RIF that is a little
interval around 1/5. But it's definitely not equal to 1/5. In
contrast, 1/2 is in RIF, since it can be represented exactly there.

In any case, I am against "a in X" being true if there is no element b
of X such that a==b is true. One motivation for this the Python
reference manual which says that the fallback for __contains__ is:
"For user-defined classes which do not define __contains__() but do
define __iter__(), x in y is true if some value z with x == z is
produced while iterating over y. If an exception is raised during the
iteration, it is as if in raised that exception." [1]

[1] https://docs.python.org/2/reference/expressions.html#membership-test-details

William


>
>> However,
>>
>> sage: a.lower() == a.lower()
>> True
>> sage: a.upper() == a.upper()
>> True
>>
>> The code to compare intervals is here:
>>
>>
> https://github.com/sagemath/sage/blob/master/src/sage/rings/real_mpfi.pyx#L3517
>>
>> It looks like it just compares the endpoints, so I don't understand
>> why a == a is false...
>
> That's because you are looking at the wrong function; intervals also
> implement richcmp.
>
> --
> Marc
>

Jeroen Demeyer

unread,
Mar 19, 2015, 1:12:25 PM3/19/15
to sage-...@googlegroups.com
On 2015-03-19 17:57, William Stein wrote:
> Is there a proposal to leverage the remark " (However, the behavior is
> not specified if given a non-interval and an interval.)", and change
> the behavior of
>
> sage: RIF(1/5) == 1/5

The coercion framework indeed calls RIF(1/5) == RIF(1/5). Changing this
would either mean changing low-level coercion framework stuff or
special-casing RIF for comparison. I wouldn't recommend either option.

William Stein

unread,
Mar 19, 2015, 1:20:36 PM3/19/15
to sage-devel
Thanks for checking. +1 to not recommending either option.
Reply all
Reply to author
Forward
0 new messages