Функция для 'содержит ли матрица значение X?'

67

Есть ли встроенная функция MATLAB, чтобы узнать, содержит ли матрица определенное значение? (ala PHP in_array())

  • 0
    Для данных с плавающей запятой, где может потребоваться допуск, обратите внимание, что версия R2015a добавила новые функциональные возможности для обработки этого с помощью одной встроенной функции. Принятые решения для целочисленных данных хороши, но для поплавков перейдите к этому ответу . Извините за саморекламу, но это большое дополнение к MATLAB после многих лет, когда люди спрашивают.
Теги:
floating-point
function
matrix

4 ответа

90
Лучший ответ

Много способов сделать это. ismember - это первое, что приходит на ум, поскольку это набор действий, которые вы хотите принять. Таким образом,

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

Так как 15 не является простым, но 17 is, ismember хорошо выполнил свою работу здесь.

Конечно, поиск (или любой) также будет работать. Но они не векторизуются в том смысле, что это было. Мы можем проверить, есть ли 15 в наборе, представленном X, но для проверки обоих этих чисел потребуется цикл или последовательные тесты.

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

или,

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

Наконец, я хотел бы указать, что тесты для точных значений опасны, если числа могут быть истинными поплавками. Тесты на целочисленные значения, как я показал, просты. Но тесты с номерами с плавающей запятой обычно должны использовать допуск.

tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
  • 2
    Самый быстрый из трех, кажется, any . Но вы можете измерить это самостоятельно (используя tic и toc ).
  • 0
    Для значений с плавающей запятой, если вы используете хотя бы R2015a, просто используйте ismembertol .
10

вы можете сделать:

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

Чтобы сделать это выше, используйте:

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

или @woodchips предлагает:

ismember([5 7 11], A)
  • 0
    почему вы используете [5 7 11] в качестве аргумента в ismember
  • 1
    @Jordan: возвращаемый ответ представляет собой логический массив (true / false) того же размера, что и аргумент, указывающий, содержит ли матрица A каждое из этих значений (например, [true, true, false] означающее, что A содержит значения 5 и 7 но не 11 ).
Показать ещё 3 комментария
3

Если вам нужно проверить, находятся ли элементы одного вектора в другом, лучшее решение ismember, как указано в других ответах.

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

Однако, когда вы имеете дело с числами с плавающей запятой или просто хотите иметь близкие совпадения (+ - 1000 также возможно), лучшим решением, которое я нашел, является довольно эффективным Подача обмена файлами: ismemberf

Это дает очень практичный пример:

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

Хотя допустимое значение по умолчанию должно быть достаточным, оно дает вам большую гибкость

ismemberf(9.99, 0:10:100) % returns false
ismemberf(9.99, 0:10:100,'tol',0.05) % returns true
2

Для данных с плавающей запятой вы можете использовать новую функцию ismembertol, которая вычисляет членство набора с заданным допуском. Это похоже на функцию ismemberf, найденную в File Exchange, за исключением того, что она теперь встроена в MATLAB. Пример:

>> pi_estimate = 3.14159;
>> abs(pi_estimate - pi)
ans =
   5.3590e-08
>> tol = 1e-7;
>> ismembertol(pi,pi_estimate,tol)
ans =
     1

Ещё вопросы

Сообщество Overcoder
Наверх
Меню