Как сравнить все элементы двух массивов?

У меня есть два больших массива примерно с 1000 строками и 1000 столбцами. Мне нужно сравнить каждый элемент этих массивов и сохранить 1 в другом массиве, если соответствующие элементы равны.

Я могу сделать это с помощью циклов for, но это займет много времени. Как мне сделать это быстрее?


person anon    schedule 04.02.2010    source источник
comment
Всегда, всегда векторизуйте код MATLAB, когда это возможно.   -  person Doresoom    schedule 04.02.2010
comment
Следует переместить на math.stackexchange.com?   -  person aaronsnoswell    schedule 31.07.2012


Ответы (3)


Все ответы верны. Я просто хотел подробнее остановиться на замечании gnovice о тестировании с плавающей запятой.

При сравнении чисел с плавающей запятой на равенство необходимо использовать значение допуска. Обычно используются два типа сравнения допусков: абсолютный допуск и относительный допуск. (источник)

Сравнение абсолютных допусков a и b выглядит так:

|a-b| < tol

Сравнение относительной толерантности выглядит так:

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

Вы можете реализовать две вышеуказанные функции как анонимные:

%# 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) );

Затем вы можете использовать их как:

%# let x and y be scalars/vectors/matrices of same size
x == y
isequalAbs(x, y, 1e-6)
isequalRel(x, y, 1e-6)
person Amro    schedule 04.02.2010
comment
попробуйте: isequal(0.3,0.1*3), что эквивалентно 0.3 == 0.1*3. Ответ в обоих случаях ложный! - person Amro; 05.02.2010
comment
Мои извинения - я полагаю, моя вера в MATLAB была неуместной! Теперь мне придется изменить много кода :( - person Jacob; 05.02.2010
comment
Одно замечание об использовании EPS: это также относительная функция. Вызов EPS без аргументов дает вам расстояние от 1,0 до следующего по величине числа с двойной точностью. Для вашей второй анонимной функции вы, вероятно, захотите использовать что-то вроде tol*eps(max(abs(x),abs(y))), что должно дать вам точность с плавающей запятой в диапазоне значений в x и y (умноженных на tol). - person gnovice; 05.02.2010
comment
также isequal возвращает одно логическое значение; OP хотел двоичную функцию, которая принимает 2 матрицы одинакового размера и создает логическую матрицу этого размера. - person shabbychef; 05.02.2010
comment
@gnovice: На самом деле это неверно. если вы перейдете по ссылке, на которую я ссылался (часть документации MATLAB xUnit framework), она объясняет, что значение tol_floor действует как абсолютный допуск, когда a и b очень близки к 0. Я просто решил использовать eps. Фактически, вы можете опустить его, если хотите, и определить его как: abs(x-y) <= tol*max(abs(x),abs(y)), где пользователь выбирает значение для tol (хорошее значение по умолчанию - 1e-8) - person Amro; 05.02.2010
comment
@ Амро: Ааааааааааааааааааааааааааааааааааааааааааааааааааааа, хорошо Теперь я понимаю, как вы использовали EPS в своем уравнении. - person gnovice; 05.02.2010
comment
@gnovice Разве допуск не должен зависеть от eps в точке: abs(x-y) < max( abs( eps(x), eps(y) ) )? - person user2469775; 29.07.2013

Если две ваши матрицы A и B имеют одинаковый размер, вы можете сделать это:

index = A == B;

и index будет логическим массивом с единицами повсюду элементы A и B равны и равны нулю в противном случае.

Предупреждение ...

Если A и B содержат целые числа, все должно быть хорошо. Однако, если они содержат значения с плавающей запятой, вы можете получить нежелательные результаты. В приведенном выше коде будет только одно значение для элементов, которые точно равны. Даже самая маленькая разница приведет к тому, что элементы будут считаться неравными.

Вы можете посмотреть ответы на этот вопрос для получения дополнительной информации о том, как бороться с «опасностями операций с плавающей запятой». Одним из решений было бы проверить, находятся ли элементы массива в пределах заданного допуска друг к другу, например:

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

Вышеупомянутое даст вам логический массив index с единицами везде, где элементы A и B находятся в пределах 0,0001 друг от друга и нуля в противном случае.

person gnovice    schedule 04.02.2010
comment
В Matlab есть функция eps, описываемая как относительная точность с плавающей запятой. Вы можете использовать его вместо переменной допуска в коде gnovice. index = abs (A-B) ‹= eps; - person yuk; 04.02.2010
comment
eps - это наименьшее значение, которое можно представить, не так ли? В данном контексте это не очень полезно. - person davidag; 08.02.2010

Просто используйте обычный оператор ==:

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

ans =

     1     0
     0     1
person Thomas    schedule 04.02.2010