Ask Your Question
0

Incorrect results for comparison expression

asked 2020-09-23 02:48:15 -0500

svat gravatar image

updated 2020-09-24 07:28:22 -0500

Sage incorrectly evaluates bool(1/47749 <= -5564456128*e + 15125759978) as False.

In more detail, consider this:

sage: x = -5564456128*e + 15125759978
sage: (1/47749).n(digits=6)
0.0000209428
sage: x.n(digits=20)
0.000020943072740919888020
sage: bool(1/47749 <= x)
False

What is going on? Why does the last boolean evaluate to False? This results in the failure of the assertion that 1/ceil(1/x) <= x, which should be true mathematically.

Is there a way to compare two quantities that will result in a correct answer, using as much precision as necessary?

edit retag flag offensive close merge delete

Comments

Incidentally, x.n(digits=6) instead of giving something like 0.0000209431 gives 1024.00, which is scary.

svat gravatar imagesvat ( 2020-09-24 07:29:23 -0500 )edit

2 answers

Sort by » oldest newest most voted
0

answered 2020-09-23 14:23:50 -0500

svat gravatar image

updated 2020-09-24 07:39:09 -0500

I found a work-around in a question I had myself asked about 5 years ago (but apparently forgotten its lesson): "Incorrect result for comparison (precision issues?)" at ask.sagemath.org/question/32371 — the solution is to avoid the "<" operator for comparison (what a gotcha!), and define one's own smaller function:

def smaller(a, b):
    '''Returns True if a < b (and False if b < a). Assumes that a != b.'''
    prec = 53
    while prec < 100000:
        R = RealIntervalField(prec)
        try:
            R(a).intersection(R(b))
        except ValueError:
            return R(a) < R(b)
        else:
            #print '{} bits of precision is not enough'.format(prec)
            prec += prec // 10
    raise Exception('100000 bits of precision was not enough for comparing: ', a, b, ' -- Possibly they are equal')

Then it works correctly:

sage: bool(smaller(1/47749, -5564456128*e + 15125759978))
True

Note that this function assumes that a ≠ b:

sage: smaller(pi/4, 4*arctan(1/5) - arctan(1/239))
...
Exception: ('100000 bits of precision was not enough for comparing: ', 1/4*pi, 4*arctan(1/5) - arctan(1/239), ' -- Possibly they are equal')
edit flag offensive delete link more

Comments

Here's the earlier question: https://ask.sagemath.org/question/323... — I can't post it as a link from the account that asked the question, it's a new account with not enough karma, and I can't find a way to merge the accounts.

ShreevatsaR gravatar imageShreevatsaR ( 2020-09-23 14:30:23 -0500 )edit

Clever use of RIF... But you may want to catch the case where a and bare equal (possibly by trying (a-b).is_zero()). What does your function return when applied to John Machin's incredible formula ?

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2020-09-23 14:31:57 -0500 )edit

Unfortunately the Sage versions I have access to will all happily declare a and b to be equal even when they are not (see comments under your answer), so the best I could do was to add an assumption to the function that they are not equal.

svat gravatar imagesvat ( 2020-09-24 07:17:27 -0500 )edit
0

answered 2020-09-23 14:27:01 -0500

Emmanuel Charpentier gravatar image

FWIW :

sage: x = -5564456128*e + 15125759978
sage: (x-1/47749).n(digits=50)
2.2327547500435249115043756744718383299006623385945e-10

As usual, stay exact as long as possible... The chapters of this book dedicated to numerical computation may enlighten you...

Note that a "visual" comparison based on :

sage: "%8.6g, %8.6g"%(x,1/47749)
'2.09808e-05, 2.09428e-05'

misses the target by about two magnitude orders (implying a difference of about 4e-8...).

Note also that :

sage: (x-1/47749).is_zero()
False
sage: (x-1/47749).is_positive()
False
sage: (x-1/47749).is_negative()
False

which is surprising, but conformant to the definitions of the methods : nothoing is known nor deducible about these quantities, and only numerical computation of their differences allows to answer the question.

edit flag offensive delete link more

Comments

Doesn't bool(1/47749 <= -5564456128*e + 15125759978) satisfy your recommendation to "stay exact as long as possible"? The question is how to perform the comparison in a way that gives a correct answer.

ShreevatsaR gravatar imageShreevatsaR ( 2020-09-23 14:31:39 -0500 )edit

For some reason, (x-1/47749).is_zero()gives True for me… (Sage 8.3 which is a couple of years old, but also tried it on CoCalc Instant SageWorksheet linked from sagemath.org).

ShreevatsaR gravatar imageShreevatsaR ( 2020-09-23 15:48:23 -0500 )edit

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: 2020-09-23 02:48:15 -0500

Seen: 60 times

Last updated: Sep 24