# Comparing exact expressions for equality — is it really OK if I get wrong answer?

Bug introduced in 7.0 or earlier and fixed in 10.2.0

I found an unexpected behavior (that I think of as a bug) in evaluation of the equality operator applied to mathematical functions with exact arguments (i.e. not containing any approximate floating-point numbers):

AppellF1[1/2, 1/2, 1/2, 3/2, 1/2 + I √3 / 2, 1/2 - I √3 / 2] == EllipticK[3/4] / 2
(* False *)


This result is wrong. In fact, these two expressions are equal, so the ideal correct result would be True. I understand that Mathematica may not be able to immediately prove this equality, so it could return it unevaluated.

I guess that the wrong answer False is a result of round-off errors occurred when Mathematica tried to evaluate both operands numerically. But I believe that numerical approximations should only be used to decide equality if precision is enough to establish provably non-zero difference.

Here are some excerpts from Mathematica help confirming this point:

When given precise numbers, the Wolfram Language does not convert them to an approximate representation, but gives a precise result.

When Equal cannot decide whether two numeric expressions are equal it returns unchanged.

I reported this issue to support@wolfram.com (CASE:3353933), but received a response saying this is not a bug. Update: we followed up on this issue and agreed that it's indeed a bug.

So I would like to know your opinion, whether this behavior is indeed by design?

• May be a related question – Vladimir Reshetnikov Jun 2 '15 at 22:57
• Just to check your conjecture that Equal is using N[] internally, try doing InputForm[N[(* number *)]] on each constant. You might also want to try varying the setting of the system variable Internal$EqualTolerance. – J. M.'s torpor Jun 2 '15 at 22:58 • As far as I can tell Equal does what it's supposed to, the incorrect result is due to the AppelF1 evaluation at high precision not being sufficiently accurate. It should definitely be looked at and I'll let the developers know. – ilian Jun 3 '15 at 0:57 • To verify @ilian's note, maybe somebody can do a Table[] of the Appell function value evaluated at different levels of precision… the elliptic integral I would expect to be very accurately evaluated, as that is computed using AGM. – J. M.'s torpor Jun 3 '15 at 2:21 • Fixed in version 10.2. – ilian Jul 14 '15 at 17:09 ## 1 Answer I first suspected that the small imaginary component in the numeric approximation was the source of the problem but adding Re did not change the False result. Next I checked to see if the first fifty digits matched and they do: x1 = AppellF1[1/2, 1/2, 1/2, 3/2, 1/2 + I √3/2, 1/2 - I √3/2]; x2 = EllipticK[3/4]/2; Equal @@ RealDigits[{Re@x1, x2}, 10, 50]  True  However in the next fifty digits a mismatch is reported: Equal @@ RealDigits[{Re@x1, x2}, 10, 50, -50]  False  RealDigits[{Re@x1, x2}, 10, 10, -88]  {{{5, 8, 2, 9, 4, 3, 2, 3, 5, 8}, -87}, {{9, 3, 7, 8, 9, 0, 7, 2, 2, 9}, -87}}  I then tried increasing $MinPrecision with the same result:

Block[{$MinPrecision = 500}, RealDigits[{Re@x1, x2}, 10, 10, -88] ]  However if I apply N first the digits are reported to match: RealDigits[{Re@x1, x2} ~N~ 200, 10, 10, -88] {{{9, 3, 7, 8, 9, 0, 7, 2, 2, 9}, -87}, {{9, 3, 7, 8, 9, 0, 7, 2, 2, 9}, -87}}  I do not feel qualified to interpret the meaning of this but I would have expected this output to match the former one. I thought that RealDigits was the more robust tool and that all the digits it reported for an exact number would be correct. Perhaps this is not the case. Or perhaps this reveals a bug somewhere? • What happens if you do Block[{Internal$EqualTolerance = (* tiny number *)}, x1 == x2]? and vary that system variable accordingly? (Maybe $MachineEpsilon is a good first setting to try?) – J. M.'s torpor Jun 3 '15 at 0:03 • @J. M. Strangely after performing the evaluations for the answer above x1 == x2 then returned unevaluated! After restarting the kernel it again gave False! I'll try to explore this more later. – Mr.Wizard Jun 3 '15 at 0:12 • N caches its results, so performing the 200-digit computation first makes the two RealDigits agree a bit further. – ilian Jun 3 '15 at 0:53 • Block[{$MaxExtraPrecision = 100}, (N[x1 - x2, 20] // Chop[#, 10^-75] &) == 0] returns True – Bob Hanlon Jun 3 '15 at 2:10
• @Mr.Wizard Yes, the caching comment was meant to expand on the last part of your answer. Also, for an exact number, RealDigits internally computes a numerical approximation (with sufficiently many extra digits beyond the requested) using the same code as N so it is susceptible to this kind of problem. – ilian Jun 3 '15 at 3:27