Ask Your Question
1

unable to coerce <type 'sage.rings.real_mpfi.RealIntervalFieldElement'> to an integer

asked 2017-07-20 16:11:57 -0500

david gravatar image

I am very desperate. I just want to convert a real number to an integer. I have tried int(x), Integer(x), floor(x), ceil(x) but nothing seems to work.

edit retag flag offensive close merge delete

Comments

Both floor and ceil work for me. (Although this is no coercion, rather a forced push.)

sage: import random
sage: a = random.uniform( 10**5,10**9 )
sage: a
595085086.3412846
sage: floor(a)
595085086
sage: type( floor(a) )
<type 'sage.rings.integer.Integer'>
sage: floor(a).factor()
2 * 297542543
sage: ceil(a)
595085087
sage: ceil(a).factor()
5437 * 109451

As seen, the type of the floored a is a "sage integer", it has for instance the method factor.

Please provide code that fails for floor and/or ceil.

How to create an instance of that ...RealIntervalFieldElement type? (And this is no real number...)

dan_fulea gravatar imagedan_fulea ( 2017-07-21 04:04:34 -0500 )edit

3 answers

Sort by ยป oldest newest most voted
0

answered 2017-07-21 09:48:47 -0500

tmonteil gravatar image

If you want a more precise help, you need to provide your code (e.g. what is the precision of the number you are considering).

RealIntervalField elements are pairs of floating-point numbers representing an interval where the actual value is supposed to live. Such a representation is used to do numerical computations wile guaranteeing the error.

Since ZZ is an exact ring, it is not safe to transform such an interval into an integer, unless the two endpoints are equal and correspond to an integer (which could be implemented by the way).

The dirty way is to first transform your real interval element into a floating-point number, and then into an integer, for example:

sage: a = RIF(4)
sage: ZZ(RR(a))
4

Note however, the map from RIF to RR just takes the middle of the two endpoints:

sage: a = RIF(0,1)
sage: a
1.?
sage: a.endpoints()
(0.000000000000000, 1.00000000000000)
sage: RR(a)
0.500000000000000

Hence it can be dangerous:

sage: a = RIF(0,10)
sage: ZZ(RR(a))
5

sage: a = RIF(pi)
sage: b = RIF(3+pi)
sage: c = b-a
sage: c.endpoints()
(2.99999999999999, 3.00000000000001)
sage: c.center()
3.00000000000000
sage: c.center() in ZZ
True
sage: ZZ(RR(c))
3

(you could hence imagine situations where the center is an integer by chance while the represented number is not an integer, just close to one).

The only safe way to convert from RIF to ZZ is to first check that the endpoints are equal and in this case return it as an integer if it is an integer, something like:

sage: def intify(r):
....:     if r.is_exact():
....:         c = r.center()
....:         if c in ZZ:
....:             return ZZ(c)
....:         else:
....:             raise ValueError('The interval is exact but not an integer.')
....:     else:
....:         raise ValueError('The interval is not exact.')
sage: intify(RIF(2))
2
sage: intify(RIF(sqrt(2))*RIF(sqrt(2)))
ValueError: The interval is not exact.
sage: intify(RIF(0.5))
ValueError: The interval is exact but not an integer.
sage: intify(RIF(0,1))
ValueError: The interval is not exact.
edit flag offensive delete link more

Comments

Please note that we get errors for ZZ( RR( a ) ) when a "has a fractional part":

sage: a = RIF(4)
sage: ZZ( RR( a ) )
4
sage: try:    a = ZZ( RR( RIF( pi ) ) )
....: except TypeError:    print "TypeError!"
....: 
TypeError!

Also:

sage: try:    print ZZ( RR( RIF( 0, 9 ) ) )
....: except TypeError:    print "TypeError!"
....: 
TypeError!
sage: try:    print ZZ( RR( RIF( 0, 10 ) ) )
....: except TypeError:    print "TypeError!"
....: 
5
dan_fulea gravatar imagedan_fulea ( 2017-07-21 11:30:36 -0500 )edit
0

answered 2017-07-21 09:53:02 -0500

updated 2017-07-21 10:11:17 -0500

A real interval field element is a pair of real numbers (lower and upper)

sage: a = RIF(pi)
sage: a.lower()
3.14159265358979
sage: a.upper()
3.14159265358980
sage: b = RIF(3.24, 5.4)
sage: b.lower()
3.24000000000000
sage: b.upper()
5.40000000000001

You can see above that the interval is not necessarily small! And you can check that applying floor not necessarily leads to a unique possibility

sage: b.floor()
4.?
sage: b.floor().lower()
3.00000000000000
sage: b.floor().upper()
5.00000000000000

If you want to go from a real interval field to an integer there are the following methods

sage: a.unique_floor()
3
sage: a.unique_ceil()
4
sage: c = RIF(2.9, 3.1)
sage: c.unique_integer()
3

These methods might give errors when not appropriate

sage: a.unique_integer()
Traceback (most recent call last):
...
ValueError: interval contains no integer
sage: b.unique_floor()
Traceback (most recent call last):
...
ValueError: interval does not have a unique floor
edit flag offensive delete link more
0

answered 2017-07-21 05:09:02 -0500

dan_fulea gravatar image

updated 2017-07-21 05:10:46 -0500

I think, the problem occurs as in the following case:

sage: a = RIF( pi^3 )
sage: a
31.0062766802999?
sage: floor(a), type(floor(a))
(31, <type 'sage.rings.real_mpfi.RealIntervalFieldElement'>)
sage: ceil(a), type(ceil(a))
(32, <type 'sage.rings.real_mpfi.RealIntervalFieldElement'>)

and the two methods work, but still do not leave the encapsulation, so no real number is provided. If this is the problem, then note that the "interval instance" a has a lower and an upper method, which leave the class, offer real numbers, where we can apply as desired floor and ceil... For instance:

sage: a = RIF( pi^3 )
sage: a
31.0062766802999?

sage: a.lower(), type( a.lower() )
(31.0062766802998, <type 'sage.rings.real_mpfr.RealNumber'>)
sage: floor( a.lower() ), type( floor( a.lower() ) )
(31, <type 'sage.rings.integer.Integer'>)
sage: floor( a.lower() ) . is_prime()
True

sage: a.upper(), type( a.upper() )
(31.0062766802999, <type 'sage.rings.real_mpfr.RealNumber'>)
sage: ceil( a.upper() ), type( ceil( a.upper() ) )
(32, <type 'sage.rings.integer.Integer'>)
sage: ceil( a.upper() ) . is_prime_power()
True
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-07-20 16:11:57 -0500

Seen: 55 times

Last updated: Jul 21