ASKSAGE: Sage Q&A Forum - Individual question feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 24 Sep 2020 07:29:23 -0500Incorrect results for comparison expressionhttps://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/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?Wed, 23 Sep 2020 02:48:15 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/Comment by svat for <p>Sage incorrectly evaluates <code>bool(1/47749 <= -5564456128*e + 15125759978)</code> as False.</p>
<p>In more detail, consider this:</p>
<pre><code>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
</code></pre>
<p>What is going on? Why does the last boolean evaluate to False? This results in the failure of the assertion that <code>1/ceil(1/x) <= x</code>, which should be true mathematically.</p>
<p>Is there a way to compare two quantities that will result in a correct answer, using as much precision as necessary?</p>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53571#post-id-53571Incidentally, `x.n(digits=6)` instead of giving something like `0.0000209431` gives `1024.00`, which is scary.Thu, 24 Sep 2020 07:29:23 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53571#post-id-53571Answer by svat for <p>Sage incorrectly evaluates <code>bool(1/47749 <= -5564456128*e + 15125759978)</code> as False.</p>
<p>In more detail, consider this:</p>
<pre><code>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
</code></pre>
<p>What is going on? Why does the last boolean evaluate to False? This results in the failure of the assertion that <code>1/ceil(1/x) <= x</code>, which should be true mathematically.</p>
<p>Is there a way to compare two quantities that will result in a correct answer, using as much precision as necessary?</p>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?answer=53552#post-id-53552I 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')Wed, 23 Sep 2020 14:23:50 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?answer=53552#post-id-53552Comment by svat for <p>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 <strong>avoid the "<" operator for comparison</strong> (what a gotcha!), and define one's own <code>smaller</code> function:</p>
<pre><code>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')
</code></pre>
<p>Then it works correctly:</p>
<pre><code>sage: bool(smaller(1/47749, -5564456128*e + 15125759978))
True
</code></pre>
<p>Note that this function assumes that a ≠ b:</p>
<pre><code>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')
</code></pre>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53568#post-id-53568Unfortunately 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.Thu, 24 Sep 2020 07:17:27 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53568#post-id-53568Comment by Emmanuel Charpentier for <p>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 <strong>avoid the "<" operator for comparison</strong> (what a gotcha!), and define one's own <code>smaller</code> function:</p>
<pre><code>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')
</code></pre>
<p>Then it works correctly:</p>
<pre><code>sage: bool(smaller(1/47749, -5564456128*e + 15125759978))
True
</code></pre>
<p>Note that this function assumes that a ≠ b:</p>
<pre><code>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')
</code></pre>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53557#post-id-53557Clever use of RIF... But you may want to catch the case where `a` and `b` *are* equal (possibly by trying `(a-b).is_zero()`). What does your function return when applied to John Machin's incredible [formula](https://en.wikipedia.org/wiki/Machin-like_formula) ?Wed, 23 Sep 2020 14:31:57 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53557#post-id-53557Comment by ShreevatsaR for <p>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 <strong>avoid the "<" operator for comparison</strong> (what a gotcha!), and define one's own <code>smaller</code> function:</p>
<pre><code>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')
</code></pre>
<p>Then it works correctly:</p>
<pre><code>sage: bool(smaller(1/47749, -5564456128*e + 15125759978))
True
</code></pre>
<p>Note that this function assumes that a ≠ b:</p>
<pre><code>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')
</code></pre>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53555#post-id-53555Here's the earlier question: https://ask.sagemath.org/question/32371/incorrect-result-for-comparison-precision-issues/ — 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.Wed, 23 Sep 2020 14:30:23 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53555#post-id-53555Answer by Emmanuel Charpentier for <p>Sage incorrectly evaluates <code>bool(1/47749 <= -5564456128*e + 15125759978)</code> as False.</p>
<p>In more detail, consider this:</p>
<pre><code>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
</code></pre>
<p>What is going on? Why does the last boolean evaluate to False? This results in the failure of the assertion that <code>1/ceil(1/x) <= x</code>, which should be true mathematically.</p>
<p>Is there a way to compare two quantities that will result in a correct answer, using as much precision as necessary?</p>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?answer=53553#post-id-53553FWIW :
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](http://sagebook.gforge.inria.fr/english.html) 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.Wed, 23 Sep 2020 14:27:01 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?answer=53553#post-id-53553Comment by ShreevatsaR for <p>FWIW :</p>
<pre><code>sage: x = -5564456128*e + 15125759978
sage: (x-1/47749).n(digits=50)
2.2327547500435249115043756744718383299006623385945e-10
</code></pre>
<p>As usual, stay exact as long as possible... The chapters of <a href="http://sagebook.gforge.inria.fr/english.html">this book</a> dedicated to numerical computation may enlighten you... </p>
<p>Note that a "visual" comparison based on :</p>
<pre><code>sage: "%8.6g, %8.6g"%(x,1/47749)
'2.09808e-05, 2.09428e-05'
</code></pre>
<p>misses the target by about two magnitude orders (implying a difference of about 4e-8...).</p>
<p>Note also that :</p>
<pre><code>sage: (x-1/47749).is_zero()
False
sage: (x-1/47749).is_positive()
False
sage: (x-1/47749).is_negative()
False
</code></pre>
<p>which is surprising, but conformant to the definitions of the methods : nothoing is <em>known</em> nor <em>deducible</em> about these quantities, and only numerical computation of their differences allows to answer the question.</p>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53560#post-id-53560For 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).Wed, 23 Sep 2020 15:48:23 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53560#post-id-53560Comment by ShreevatsaR for <p>FWIW :</p>
<pre><code>sage: x = -5564456128*e + 15125759978
sage: (x-1/47749).n(digits=50)
2.2327547500435249115043756744718383299006623385945e-10
</code></pre>
<p>As usual, stay exact as long as possible... The chapters of <a href="http://sagebook.gforge.inria.fr/english.html">this book</a> dedicated to numerical computation may enlighten you... </p>
<p>Note that a "visual" comparison based on :</p>
<pre><code>sage: "%8.6g, %8.6g"%(x,1/47749)
'2.09808e-05, 2.09428e-05'
</code></pre>
<p>misses the target by about two magnitude orders (implying a difference of about 4e-8...).</p>
<p>Note also that :</p>
<pre><code>sage: (x-1/47749).is_zero()
False
sage: (x-1/47749).is_positive()
False
sage: (x-1/47749).is_negative()
False
</code></pre>
<p>which is surprising, but conformant to the definitions of the methods : nothoing is <em>known</em> nor <em>deducible</em> about these quantities, and only numerical computation of their differences allows to answer the question.</p>
https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53556#post-id-53556Doesn'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.Wed, 23 Sep 2020 14:31:39 -0500https://ask.sagemath.org/question/53548/incorrect-results-for-comparison-expression/?comment=53556#post-id-53556