3

Can you help me with this common problem I have?

Given two lists:

a={339.66666666666697`, -287.4444444444446`, 0.`}

and

b = {339.6666666666667`, -287.44444444444684`, -2.1316282072803006`*^-13}

Equal[a,b] gives False because

-2.1316282072803006`*^-13 

is not equal to 0.

How can I solve this problem? I understand that it is something about precision settings, but I don't know how to write this.

  • 1
    Another helpful function could be PossibleZeroQ – IntroductionToProbability Nov 16 '22 at 15:09
  • I would do a - b // Norm // Chop but for very large lists the sum of the errors accumulate so then you might want to only check the maximal error in the list with a - b // Norm[#, Infinity] & // Chop. That said they output 0 rather than True. – userrandrand Nov 16 '22 at 20:50

3 Answers3

6
a = {339.66666666666697, -287.4444444444446, 0.}
b = {339.6666666666667, -287.44444444444684, -2.1316282072803006*^-13}

In order to chop values close to zero to exactly zero and compare:

Chop[a] == Chop[b]

True

Chop takes a second argument as well.


For checking up to 3 decimal places:

Round[a, 10^-3] == Round[b, 10^-3]

True


To within a multiple of the second argument:

Round[a, 10^-#] == Round[b, 10^-#] & /@ Range[15]

{True, True, True, True, True, True, True, True, True, True, False,
False, False, False, False}

Syed
  • 52,495
  • 4
  • 30
  • 85
3

There are several ways to do this:

Equal[a, Chop[b]] (*True*)

SetAccuracy[a, 10] === SetAccuracy[b, 10] (*True*)
3

You may define a function, that compares two numbers or arrays, where you can specify how much difference you want to tolerate: E.g.

equalBy[a_, b_, tol_] := Max[Abs[a - b]] <= tol;

where a and b are the objects to compare and tol is the allowed tolerance.

Now with your example:

a = {339.66666666666697`, -287.4444444444446`, 0.`};
b = {339.6666666666667`, -287.44444444444684`,-2.1316282072803006`*^-13};

the largest difference is:

Max[Abs[a - b]]  (*2.21689*10^-12*)

and we may write:

equalBy[a, b, 10^-12]  (* False *)

equalBy[a, b, 10^-11] (True *)

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57