2009-06-02 10 views
14

J'ai deux matrices x et y, les deux sont des résultats de différents algorithmes/routines qui sont supposés calculer le même résultat. Bien que je sache que isequal() vérifierait si x et y sont la même matrice, les entrées dans ces matrices ne seraient pas exactement les mêmes (c'est-à-dire que certaines entrées pourraient être avec 5% de réduction dans le pire des cas). Dans ce scénario, quelle serait la meilleure méthode de comparaison pour voir si elles sont assez proches pour être considérées comme le même résultat? Merci d'avance pour les conseils.Comparaison de deux matrices dans Matlab

+1

Cette question est assez vieux, mais mathématiquement vous voulez utiliser 'norme (A-B)/norme (A)', pas les solutions ci-dessous. – rlbond

Répondre

5

Modification solution Edric's:

absTol = 1e-3; % You choose this value to be what you want! 
relTol = 0.05; % This one too! 
absError = x(:)-y(:); 
relError = absError./x(:); 
relError(~isfinite(relError)) = 0; % Sets Inf and NaN to 0 
same = all((abs(absError) < absTol) & (abs(relError) < relTol)); 

Le variable même sera faux si soit l'absolu ou l'erreur relative d'un élément est plus grande que les tolérances que vous choisissez. En outre, si des éléments de x se trouvent exactement à 0, alors certains des éléments de relError pourraient finir par être infinis ou non-nombre, donc j'ai utilisé la fonction ISFINITE pour ignorer ces valeurs en les réglant

Je ne suggérerais pas d'utiliser IMAGESC pour comparer des graphiques, puisque 1) les données sont mises à l'échelle lorsqu'elles sont affichées, 2) la carte de couleurs pour l'affichage a un nombre discret de valeurs de couleur (ce qui est 256 par défaut, donc beaucoup d'arrondis), et 3) de subtiles variations de couleur peuvent ne pas être si évidentes à partir de la comparaison visuelle de deux parcelles.

13

Essayez ceci:

tf = abs((A-B)./B)<0.05 

Ceci renvoie une matrice logique qui est vrai pour chaque élément si la différence relative entre A et B par rapport à B est inférieur à 5 pour cent.

Si vous voulez demander si tous ces éléments sont vraies (tous satisfaire à la condition ci-dessus):

all(tf(:)) 
+0

une meilleure réponse de ce que je mets en effet. – bastijn

+1

N'avez-vous pas besoin d'une valeur absolue ici quelque part? – Jim

+0

Oui, je l'ai ajouté maintenant. Merci. –

4

je considère faire quelque chose comme ceci avec une tolérance absolue ainsi qu'une tolérance relative:

function same = tol(x, y) 
absTol = 1e-3; 
relTol = 0.05; 
errVec = abs(x(:) - y(:)); 
same = all((errVec < absTol) | (errVec./x(:) < relTol)); 
+0

J'ai essayé la méthode d'Edric et d'Andrew.Même si j'ai une sortie de la fonction étant fausse, quand j'ai comparé les deux résultats visuellement en les traçant en utilisant la fonction imagesc(), ils ont l'air très similaires. Par conséquent, je ne suis toujours pas sûr de ce qu'il faut en faire. – stanigator

1

Lorsque vous avez de très petites paires de valeurs en x et y, le résultat retournerait 0 même si les valeurs sont ignorable elles-mêmes. Ainsi, un ajout à la solution acceptée

relError(x < absTol) = 0;

pourrait être utilisé pour rejeter de très petites erreurs. Ainsi, l'erreur relative n'est pas prise en compte pour ces valeurs.

-2

faire usage de « IsEqual (a, b) où a et b sont deux matrices, le cas 1, il est vrai

+1

Notez que op précise que isequal ne fonctionnerait pas car il y a une erreur. –

0

pour les matrices X et Y contenant des valeurs en virgule flottante, on peut vérifier si les éléments de matrice sont à une tolérance donnée les uns aux autres. Exemple de code:

tol = 0.05; 

result = abs(x - y) <= tol; 
Questions connexes