1
votes

Lets say I've two matrices A and x:

A=[10,10;
   20,20;
   30,30;
   NaN,NaN
   NaN,NaN];
x=[10,9;
   32,25;
   19,21;
   11,10;
   NaN,NaN];

I want to compare both matrices and find rows of x that correspond to any row of A within a certain tolerance of +-0.01 (=+-10%). So in this case:

Row 1 of x matches a row (row 1) in A that is within the tolerance.

Row 2 of x nearly matches a row (row 2) in A, but it is outside of +- 10%.

Row 3 of x matches a row (row 2) in A that is within the tolerance.

Row 4 of x matches a row (row 1 again) in A within the tolerance.

Row 5 of x can be ignored (only NaN).

It is guaranteed that A and x have the same size and number of elements. However, the rows are not in order, so I can't compare row-by-row. I just want to know if a row in x matches ANY row in A and if so, I'd like to save the index of that row. So in my case I'd prefer to have an output (logical) vector like:

v=[1,0,1,1,0]; % Logical vector with matching rows of x
id=find(v==1); % Result is [1,3,4], finds the indices

I tried various combinations of

ismembertol(A,x,0.1) % and ismembertol(A,x,0.1,'ByRows',true)

by using 'find', 'any', 'all' but I can't figure out the solution.

1
The problem is the NaN values. If a row contains NaN, it won't match any other value, even another NaN. It seems you want to disregard those NaN' values. But then if the row is only NaN you say it shouldn't match any other row. You need to clarify these criteria. Also, are the "unwanted" NaN values always in the last column, and so that column can just be ignored? - Luis Mendo
I can 'reduce' the problem by ignoring the 3rd column, I'll edit my post. The whole lines of NaN can still happen and will always be the last lines. Let's say both matrices can have a maximum of 10 rows, then it can e.g. happen that A has 6 NaN-rows (5-10) and x may have another amount of NaN-rows (higher, lower or equal to A). - user10790707
So, if the last column is ignored, can it be assumed that any remaining NaN should cause the row to not match any other row? - Luis Mendo
Yes, sorry I didn't clarify that before. Also the rows of both A and x will always be of type 'number,number' or 'NaN,NaN'. A case like 'number,NaN' or vice-versa can't happen. - user10790707

1 Answers

1
votes

You can use ismembertol with the 'ByRows' option:

result = ismembertol(x, A, 0.1, 'ByRows', true);

Note that:

  • NaN values cause a row to not match any other row.
  • As per the documentation, tol is interpreted as a fraction of tol*max(abs([A(:); x(:)])).