# 'Det' precision

Am I missing basic logic ?

We all know Determinant of both these matrices are 0.

But when executed on my system (Windows10 64bit)

The same when executed in Online Mathematica

I was trying to use a conditional statement based on Det , am I left with Det[...]<(10^-7) type of condition instead of checking equality?

• Related question on SO: stackoverflow.com/questions/588004/… Sep 12 '16 at 17:00
• See why. Solution: Chop@Det[{{-1, -2.5}, {-2.5, -6.25}}] == 0 yields True. Sep 12 '16 at 17:05
• How could online mathematica return it right ? ... So I may not use chop whenever I deal with floating numbers right ... How can I make sure this doesn't spoil my work ( It took a lot of time to find this as I was unaware of such thing ) Sep 12 '16 at 17:34
• It is curious as to why the Wolfram Cloud returns 0.. exp := Det[{{-1, -2.5}, {-2.5, -6.25}}], then {CloudEvaluate[exp], exp}. Difference in OS maybe?
– chuy
Sep 12 '16 at 18:12
• It is a difference between Linux and Windows at least.
– chuy
Sep 12 '16 at 19:02

## 1 Answer

It is a well known problem of floating point arithmetic that equality comparisons are unreliable. For example if you try

1.0 == 0.3 + 0.3 + 0.3 + 0.1


in Python or C or any other traditional language, you get false. Why? Because these numbers are not exactly representable in binary the same way as $1/3 = 0.33333333\dots$ is not exactly representable in decimal using a finite number of digits. Due to this, and potentially due to numerical roundoff errors the two sides won't be digit-for-digit equal up to the last binary digit.

You are probably aware of this.

Now try in Mathematica:

In[151]:= 1.0 == 0.3 + 0.3 + 0.3 + 0.1
Out[151]= True


Mathematica tries to be helpful and equality comparisons have some tolerance. This can be controlled by Internal$EqualTolerance, which is set to 7 binary digits by default. Internal$EqualTolerance
(* 2.10721 *)

Log[2, 10^Internal$EqualTolerance] (* 7. *)  This choice of 7 digits is of course rather arbitrary and even though equality comparisons behave in a nice and convenient way most of the time, you must keep in mind that they are not foolproof, and cannot be foolproof even in principle. The difficulty is that your determinant is zero: Det@N[{{-1, -5/2}, {-5/2, -25/4}}] (* 3.46945*10^-16 *)  When saying "equal except for the last 7 binary digits" (or$\sim 2.1$decimal digits), we are talking about a relative tolerance. Relative tolerances don't really work for zero values because we can't divide by zero. Or rather: since floating point numbers are stored as a separate exponent and mantissa, once the result is zero, the last few normally insignificant mantissa digits are shifted up into positions which appear significant. People have already pointed out Chop, which deals exactly with this problem. It converts floating point numbers smaller than a certain threshold ($10^{-10}\$ by default) into exact 0. I.e. it uses an absolute tolerance, not a relative one.

Another way to deal with it is to use Mathematica's arbitrary precision inexact numbers instead of machine precision numbers. The former have built-in precision tracking, so the system can detect that a zero that arises due to catastrophic cancellation has very few accurate digits. This is also not foolproof, but it's much better than no precision tracking at all. Arbitrary precision numbers can be forced by SetPrecision or by using N with a second argument on exact numbers. Observe:

Det[{{a, b}, {b, d}}]
(* -b^2 + a d *)

% /. N[{a -> -1, b -> -5/2, d -> -25/4}, 10]
(* 0.*10^-9 *)

Accuracy[%]
(* 8.60206 *)

%% == 0
(* True *)


The result is zero, but it has lost some accuracy. The zero comparison evaluates to True.

Unfortunately, when using Det directly on such an arbitrary precision matrix, it doesn't perform the precision tracking:

Det@N[{{-1, -5/2}, {-5/2, -25/4}}, 10]
(* -1.469367939*10^-38 *)

{Accuracy[%], Precision[%]}
(* {47.8329, 10.} *)


Note that we have both Precision and Accuracy in Mathematica. The former is a relative measure, the latter an absolute one. Since Precision is a relative measure, it is less meaningful with a zero result.

• It's curious that others seem to get nonzero results, but I get 0. for Det@N[{{-1, -5/2}, {-5/2, -25/4}}] on both V10.4.1 and V11.0.0. Sep 13 '16 at 1:21
• @MichaelE2 I get 0.` too in v. 10.0 Oct 5 '16 at 11:47