Search code examples
matlabduplicateslogicuniqueremove-if

Matlab: Remove rows when first and last 2 elements are shuffled


I have a matrix where each element is a single unit of a 2d coordinate. As such, each element in any given row are paired, where elements in the first column are paired with those in the second, and elements in the third column paired with the fourth. All possible combinations of the 4 numbers are present in the matrix.

What I need to do is depup the matrix by removing rows where the first set of coordinates (e.g columns 1 and 2 in a row) are swapped with the second set of coordinates. For example if one row contains the value "3, 4, 2, 1" then I would need to remove "2, 1, 3, 4" from else where in the matrix.

An example of this could be seen below, where I would want to remove the last row, as it is the reverse of the first row;

3 3 1 1 1 2 2 3 3 4 1 2 4 4 3 1 4 1 4 4 1 1 3 3

I'm quite stumped as to how to do this, and my previous attempts have all failed. Whilst it may not be useful to the answer, I have included my code showing how I am constructing the initial matrix below;

%create list of all piece coordinates
p1_row_index=(1:n);
p1_column_index=(1:n);
p2_row_index=(1:n);
p2_column_index=(1:n);

% get all possible combinations of these variables
[p1_row_index,p1_column_index,p2_row_index,p2_column_index]=BalanceFactors(1,1,1:n,1:n,1:n,1:n); 
pc_list(:,1)=p1_row_index; % piece1 coordiantes for rows
pc_list(:,2)=p1_column_index; % piece1 coordiantes for columns
pc_list(:,3)=p2_row_index; % piece2 coordiantes for rows
pc_list(:,4)=p2_column_index; % piece2 coordiantes for columns

Thank you for your time.

Many thanks,

Matt


Solution

  • Complex numbers come in handy for this:

    [~, ind] = unique(sort(M(:,[1 3])+1j*M(:,[2 4]), 2), 'rows', 'stable');
    result = M(ind, :);
    

    The code works as follows:

    1. M(:,[1 3])+1j*M(:,[2 4]) creates a complex matrix with half the columns, where each pair of coordinates of the original matrix becomes a complex number.
    2. sort(..., 2) sorts each row. Rows that originally were shuffled versions of each other now become identical.
    3. [~, ind] = unique(..., 'rows', 'stable') gives the index of the first occurrence of each unique (complex, sorted) row.
    4. M(ind, :) selects the desired rows from M.