2
votes

I am working with two matrices, M and N, where matrix M is 20154x169 and matrix N is 20183x169. The first two columns of both M and N are x,y coordinates, and the rest of the columns are measurements of a physical property that were collected at each of these coordinates. As an analogy, I defined two arbitrary matrices, A and B, as

A=[0,0.1,0.2,13,0,0.1,0.2,0,0.1,0.2;0,0,0,9,2,2,2,4,4,4]';
B=[12,200,45,92,0.1,0.2,14,0,0.1,0.2,0,0.1,0.21;0,3,0,0,0,0,6,2,2,2,4,4,4]';

and I'd like to do either intersect with the rows option:

[C,iA_xy,iB_xy]=intersect(A_xy(:,1:2),B_xy(:,1:2),'rows');

or use ismember, with a tolerance so that the coordinates (0.21,4) and (0.2,4) are identified as being the same.

Ideally, I would take advantage of Matlab's new ismembertol command, but I'm working with Octave. I've searched for alternatives, and the closest I've found is the bsxfun solution posted as an answer to the question posed by InquilineKea in 2013, namely,

tol=0.01;
Ax=bsxfun(@minus,B(:),A(:)');
indA=any(abs(Ax)<tol,1);
[rA,cA]=ind2sub(size(A),indA);

but this isn't a row-by-row solution equivalent to using the 'rows' option in ismember or intersect and it indicates that first row (0,0) in matrix A is common in matrix B because the x-coordinate 0 appears elsewhere in B, but the entire row isn't in both. Is there another good, simple way to pick out all similar (x,y) pairs in two matrices within a tolerance and identify their row position, especially for big matrices? Have I missed an obvious extension of this solution to my problem? Does anyone have insight into the mechanisms of the Matlab ismembertol function?

1
What would the result be for the proposed example, exactly? Which output of ismember (with tolerance) would you want? - Luis Mendo
Ideally, the result for indA = ismember(A,B,'rows'); would be indA = 0 1 1 0 1 1 1 1 1 1, and indB = ismember(B,A, 'rows'); would then give indB = 0 0 0 0 1 1 0 1 1 1 1 1 1. The bsxfun solution listed above gives rA = 1 2 3 5 6 7 8 9 10, so the x-value in the 10th pair is identified as being within tolerance but the first pair is also identified as being within B (which it isn't.) I would be interested in what, I suppose, would be intersecttol since it will take an extra step to identify the 1's in the ismember function output, but will take whatever I can get. - k.mat27
Got it. See my answer - Luis Mendo

1 Answers

1
votes

I think this does what you want (in Matlab). It corresponds to ind = ismember(A,B,'rows') with a tolerance tol.

ind = any(squeeze(all(abs(bsxfun(@minus, B, permute(A, [3 2 1]))) <= tol, 2)), 1);

(Of course, for ind = ismember(B,A,'rows') with a tolerance just swap A and B in the above code).