6

I have a matrix

[1 2
 3 6
 7 1
 2 1]

and would like to remove mirror imaged pairs..i.e. output would be either:

[1 2
 3 6
 7 1] 

or

[3 6
 7 1 
 2 1]

Is there a simple way to do this? I can imagine a complicated for loop, something like (or a version which wouldn't delete the original pair..only the duplicates):

for i=1:y
    var1=(i,1);
    var2=(i,2);
    for i=1:y
        if array(i,1)==var1 && array(i,2)==var2 | array(i,1)==var2 && array(i,2)==var1
            array(i,1:2)=[];
        end
    end 
end

thanks

Divakar
  • 218,885
  • 19
  • 262
  • 358
user3470496
  • 141
  • 7
  • 33
  • 1
    Note that you are using `i` as a loop index for both loops, that will not work. I'd also argue caution against [using `i` as a variable](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab). – Adriaan Jan 20 '16 at 20:38

2 Answers2

9

How's this for simplicity -

A(~any(tril(squeeze(all(bsxfun(@eq,A,permute(fliplr(A),[3 2 1])),2))),2),:)

Playing code-golf? Well, here we go -

A(~any(tril(pdist2(A,fliplr(A))==0),2),:)

If dealing with two column matrices only, here's a simpler version of bsxfun -

M = bsxfun(@eq,A(:,1).',A(:,2)); %//'
out = A(~any(tril(M & M.'),2),:)

Sample run -

A =
     1     2
     3     6
     7     1
     6     5
     6     3
     2     1
     3     4
>> A(~any(tril(squeeze(all(bsxfun(@eq,A,permute(fliplr(A),[3 2 1])),2))),2),:)
ans =
     1     2
     3     6
     7     1
     6     5
     3     4
>> A(~any(tril(pdist2(A,fliplr(A))==0),2),:)
ans =
     1     2
     3     6
     7     1
     6     5
     3     4
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

Here a not so fancy, but hopefully understandable and easy way.

% Example matrix
m = [1 2; 3 6 ; 7 1; 2 1; 0 3 ; 3 0];

Comparing m with its flipped version, the function ismember returns mirror_idx, a 1D-vector with each row containing the index of the mirror-row, or 0 if there's none.

[~, mirror_idx] = ismember(m,fliplr(m),'rows');

Go through the indices of the mirror-rows. If you find one "mirrored" row (mirror_idx > 0), set its counter-part to "not mirrored".

for ii = 1:length(mirror_idx)
    if (mirror_idx(ii) > 0)
        mirror_idx(mirror_idx(ii)) = 0;
    end
end

Take only the rows that are marked as not having a mirror.

m_new = m(~mirror_idx,:);

Greetings

misch
  • 41
  • 4