How do I compare all elements of two arrays?

95,641

Solution 1

The answers given are all correct. I just wanted to elaborate on gnovice's remark about floating-point testing.

When comparing floating-point numbers for equality, it is necessary to use a tolerance value. Two types of tolerance comparisons are commonly used: absolute tolerance and relative tolerance. (source)

An absolute tolerance comparison of a and b looks like:

|a-b| < tol

A relative tolerance comparison looks like:

|a-b| < tol*max(|a|,|b|) + tol_floor

You can implement the above two as anonymous functions:

%# absolute tolerance equality
isequalAbs = @(x,y,tol) ( abs(x-y) <= tol );

%# relative tolerance equality
isequalRel = @(x,y,tol) ( abs(x-y) <= ( tol*max(abs(x),abs(y)) + eps) );

Then you can use them as:

%# let x and y be scalars/vectors/matrices of same size
x == y
isequalAbs(x, y, 1e-6)
isequalRel(x, y, 1e-6)

Solution 2

If your two matrices A and B are the same size, then you can do this:

index = A == B;

and index will be a logical array with ones everywhere an element of A and B are equal and zero otherwise.

A word of warning...

If A and B contain integers, the above should be fine. However, if they contain floating point values, you may get undesired results. The above code will only have values of one for elements that are exactly equal. Even the smallest difference will cause the elements to be considered unequal.

You can look at this question's answers for more information about dealing with the "perils of floating point operations". One solution would be to check that array elements are within a given tolerance of one another, like so:

tolerance = 0.0001;
index = abs(A-B) <= tolerance;

The above will give you a logical array index with ones everywhere the elements of A and B are within 0.0001 of each other and zero otherwise.

Solution 3

Just use the normal == operator:

>> [1 2; 3 4] == [1 5; 6 4]      

ans =

     1     0
     0     1
Share:
95,641
Admin
Author by

Admin

Updated on July 08, 2020

Comments

  • Admin
    Admin almost 4 years

    I have two big arrays with about 1000 rows and 1000 columns. I need to compare each element of these arrays and store 1 in another array if the corresponding elements are equal.

    I can do this with for loops but that takes a long time. How can I do this faster?

  • yuk
    yuk about 14 years
    Matlab has function eps, described as floating-point relative accuracy. You can use it instead of tolerance variable in gnovice's code. index = abs(A-B) <= eps;
  • Amro
    Amro about 14 years
    try: isequal(0.3,0.1*3) which is equivalent to 0.3 == 0.1*3. The answer in both is false!
  • Harsh Pathak
    Harsh Pathak about 14 years
    My apologies - I guess my faith in MATLAB was misplaced! I'm going to have to change a lot of code now :(
  • gnovice
    gnovice about 14 years
    One point about using EPS: it is also a relative function. Calling EPS with no argument gives you the distance from 1.0 to the next largest double-precision number. For your second anonymous function, you would probably want to use something like tol*eps(max(abs(x),abs(y))), which should give you the floating point accuracy in the range of the values in x and y (multiplied by tol).
  • shabbychef
    shabbychef about 14 years
    also isequal returns a single boolean; the OP wanted a binary function that takes 2 matrices of the same size and produces a boolean matrix of that size.
  • Amro
    Amro about 14 years
    @gnovice: Actually thats incorrect. if you follow the link I referenced (part of the documentation of MATLAB xUnit framework), it explains that the tol_floor value acts as an absolute tolerance when a and b are very close to 0. I just chose to use eps. As a matter of fact, you can omit it if you want and define it as: abs(x-y) <= tol*max(abs(x),abs(y)) where the user chooses a value for tol (a good default value is 1e-8)
  • gnovice
    gnovice about 14 years
    @Amro: Ahhh, OK. I see now how you were using EPS in your equation.
  • davidag
    davidag about 14 years
    eps is the smallest value that can be represented, isn't it? That is not very useful in this context.
  • user2469775
    user2469775 over 10 years
    @gnovice Shouldn't the tolerance depend on eps at the point: abs(x-y) < max( abs( eps(x), eps(y) ) )?