Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I know that Intersection is a pattern matching function and will not evaluate list elements to determine if two or more list have equal elements. So my question is, what can be done to do this? Say, determine if two lists have numerically equal elements within some tolerance dx?

share|improve this question
Have you seen the SameTest option? – Sjoerd C. de Vries Jul 16 '13 at 22:51
No, I had not. Thank you. – Phillip Dukes Jul 16 '13 at 23:08
I'm glad you found my answer helpful but you should not be so quick to Accept an answer, as it can discourage other, better, answers from being posted. I suggest you wait 24 hours to let everyone have a chance to answer. – Mr.Wizard Jul 16 '13 at 23:21
I added a method to my answer. Rounding is not ideal as two close values might be rounded in opposite directions but I cannot think of a fast way that obeys a strict tolerance. – Mr.Wizard Jul 17 '13 at 6:04
up vote 10 down vote accepted

Closely related questions:

The most direct method is to make use of the SameTest option:

a = {1, 2.2, 3.14159};
b = {11/5, Pi, 1/2, 1/4};

Intersection[a, b, SameTest -> (Abs[# - #2] < 0.0001 &)]
{2.2, 3.14159}

This however requires a pairwise comparison that has a much higher computational complexity than the default method. A different method that does not require a pairwise compare will be much faster on long lists. Iff each list is internally free of duplicates and your tolerance requirement can be relaxed to rounding you could use this:

Cases[GatherBy[Join[b, a], Round[#, 0.0001] &], {x_, _} :> x]
{11/5, π}

Note here that the exact values are returned despite the use of Round, because list b is given first in Join.

The speed advantage can be great:

a = RandomReal[99, 1000];
b = RandomReal[99, 1000];

Intersection[a, b, SameTest -> (Abs[# - #2] < 0.0001 &)]       // Timing // First
Cases[GatherBy[Join[b, a], Round[#, 0.0001] &], {x_, __} :> x] // Timing // First



If a list is not internally free of duplicates any of those values will be returned as well:

a = {1, 2.2, 3.14159};
b = {11/5, Pi, 1/2, 0.5}; (* note 1/2 and 0.5 *)

Cases[GatherBy[Join[b, a], Round[#, 0.0001] &], {x_, __} :> x]
{11/5, π, 1/2}
share|improve this answer

Couldn't find a way to do it with built-in functions, but here's a manual loop that's not much slower than Mr.Wizard's solution, but has no problems with duplicates and rounding:

TolerantIntersection[a_List, b_List, dx_] := 
  Module[{sb = Sort@b, i = 1, imax = Length@b, dif},
      (While[(dif = sb[[i]] - #) <= -dx, 
         If[i == imax, Return@False]; ++i];
      dif < dx) &]]

P.S. I edited to make the comparisons with dx strict. 'Not much slower' - I mean, in the same order of magnitude, compared to Intersection, actually it's 2-3 times slower. Note, that it's not equivalent to Intersection, in cases like

a = {0.00011, 0.00012};
b = {0.0002};

Intersection returns one arbitrary(?) element from a, my function returns both, which I believe is more correct.

share|improve this answer
Looks good from here. +1 – Mr.Wizard Jul 17 '13 at 8:48

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.