73

Is there a built in MATLAB function to find out if a matrix contains a certain value? (ala PHP's in_array())

chappjc
  • 30,359
  • 6
  • 75
  • 132
zenna
  • 9,006
  • 12
  • 73
  • 101
  • For floating point data where a tolerance may be desired, note that version R2015a has added new functionality to handle this with a single built-in function. The accepted solutions for integer-valued data are great, but for floats, jump to [this answer](http://stackoverflow.com/a/28907857/2778484). Sorry for self promotion, but it's a big addition to MATLAB after years of people asking. – chappjc Mar 06 '15 at 21:32

4 Answers4

100

Many ways to do this. ismember is the first that comes to mind, since it is a set membership action you wish to take. Thus

X = primes(20);
ismember([15 17],X)
ans =
      0    1

Since 15 is not prime, but 17 is, ismember has done its job well here.

Of course, find (or any) will also work. But these are not vectorized in the sense that ismember was. We can test to see if 15 is in the set represented by X, but to test both of those numbers will take a loop, or successive tests.

~isempty(find(X == 15))
~isempty(find(X == 17))

or,

any(X == 15)
any(X == 17)

Finally, I would point out that tests for exact values are dangerous if the numbers may be true floats. Tests against integer values as I have shown are easy. But tests against floating point numbers should usually employ a tolerance.

tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
  • 2
    The fastest of the three seems to be `any`. But you might want to measure that yourself (using `tic` and `toc`). – Lewistrick Jul 03 '14 at 12:55
  • For floating point values, if you're using at least R2015a, just use [`ismembertol`](http://stackoverflow.com/a/28907857/2778484). – chappjc Dec 29 '15 at 21:58
11

you can do:

A = randi(10, [3 4]);      %# a random matrix
any( A(:)==5 )             %# does A contain 5?

To do the above in a vectorized way, use:

any( bsxfun(@eq, A(:), [5 7 11] )

or as @woodchips suggests:

ismember([5 7 11], A)
Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • why are u using [5 7 11] as an argument in ismember – Jordan Jul 10 '14 at 15:05
  • 1
    @Jordan: the answer returned is a logical array (true/false) of the same size as the argument, indicating whether the matrix `A` contains each of those values (e.g `[true, true, false]` meaning `A` contains the values `5` and `7` but not `11`). – Amro Jul 10 '14 at 15:54
  • 1
    @AnderBiguri: here are some tests you could run to compare: https://gist.github.com/amroamroamro/e66ac6a88b0692d995fd – Amro Apr 10 '15 at 18:04
3

If you need to check whether the elements of one vector are in another, the best solution is ismember as mentioned in the other answers.

ismember([15 17],primes(20))

However when you are dealing with floating point numbers, or just want to have close matches (+- 1000 is also possible), the best solution I found is the fairly efficient File Exchange Submission: ismemberf

It gives a very practical example:

[tf, loc]=ismember(0.3, 0:0.1:1) % returns false 
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true

Though the default tolerance should normally be sufficient, it gives you more flexibility

ismemberf(9.99, 0:10:100) % returns false
ismemberf(9.99, 0:10:100,'tol',0.05) % returns true
Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
2

For floating point data, you can use the new ismembertol function, which computes set membership with a specified tolerance. This is similar to the ismemberf function found in the File Exchange except that it is now built-in to MATLAB. Example:

>> pi_estimate = 3.14159;
>> abs(pi_estimate - pi)
ans =
   5.3590e-08
>> tol = 1e-7;
>> ismembertol(pi,pi_estimate,tol)
ans =
     1
chappjc
  • 30,359
  • 6
  • 75
  • 132