2010-02-04 5 views
16

J'ai deux grands tableaux avec environ 1000 lignes et 1000 colonnes. J'ai besoin de comparer chaque élément de ces tableaux et de stocker 1 dans un autre tableau si les éléments correspondants sont égaux. Je peux le faire avec des boucles for, mais cela prend beaucoup de temps. Comment puis-je faire cela plus rapidement?Comment comparer tous les éléments de deux tableaux?

+2

Toujours, toujours vectoriser le code MATLAB lorsque cela est possible. – Doresoom

+0

Devrait être déplacé vers http://math.stackexchange.com/? – aaronsnoswell

Répondre

12

Si vos deux matrices A et B sont de la même taille, alors vous pouvez le faire:

index = A == B; 

et index sera un logical array avec ceux partout un élément de A et B sont égaux et zéro autrement.

Un mot d'avertissement ...

Si A et B contiennent des entiers, le devrait être bien au-dessus. Cependant, s'ils contiennent des valeurs à virgule flottante, vous pouvez obtenir des résultats non souhaités. Le code ci-dessus aura seulement des valeurs de un pour les éléments qui sont exactement égale. Même la plus petite différence fera que les éléments seront considérés comme inégaux.

Pour plus d'informations sur le traitement des «périls des opérations en virgule flottante», consultez le document this question's answers. Une solution serait de vérifier que les éléments tableau sont dans une tolérance donnée les uns des autres, comme si:

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

ci-dessus vous donnera un tableau logique index avec les partout les éléments de A et B sont à 0,0001 l'autre et zéro sinon.

+0

Matlab a une fonction eps, décrite comme une précision relative en virgule flottante.Vous pouvez l'utiliser à la place de la variable de tolérance dans le code de gnovice. indice = abs (A-B) <= eps; – yuk

+0

eps est la plus petite valeur qui peut être représentée, n'est-ce pas? Ce n'est pas très utile dans ce contexte. –

7

Il suffit d'utiliser l'opérateur == normal:

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

ans = 

    1  0 
    0  1 
29

Les réponses données sont tous corrects. Je voulais juste élaborer sur gnovice's remarque sur les tests à virgule flottante. Lorsque vous comparez des nombres à virgule flottante pour l'égalité, il est nécessaire d'utiliser une valeur de tolérance. Deux types de comparaisons de tolérance sont couramment utilisés: la tolérance absolue et la tolérance relative. (source)

Une comparaison de tolérance absolue de a et b ressemble à:

|a-b| < tol 

Une comparaison de tolérance relative ressemble:

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

Vous pouvez implémenter les deux fonctions ci-dessus comme anonymes:

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

Ensuite, vous pouvez les utiliser comme:

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

Quel est le problème avec 'isequal'? – Jacob

+4

essayez: 'isequal (0.3,0.1 * 3)' ce qui équivaut à '0.3 == 0.1 * 3'. La réponse dans les deux est fausse! – Amro

+1

Mes excuses - Je suppose que ma foi en MATLAB était mal placée! Je vais devoir changer beaucoup de code maintenant :( – Jacob

Questions connexes