1
votes

So, I have this cell array contains n x 2 matrix in each cell. Here is the sample data :

[16 17;17 17]
<6x2 double>
<52x2 double>
[17 17;17 18]
[17 18;17 17]

What I am going to do is eliminate the duplicated matrix (matrices with same values or reversed values). in this case is [17 18; 17 17] (5th row), because we already have [17 17; 17 18] (4th row)

I tried using unique function but it says that the function just worked for strings. I also tried to find it with cellfun like this

cellfun(@(x) x==whatToSearch, lineTraced, 'UniformOutput', false)

but it says 'Matrix dimension must agree'

Thanks in advance.

2
So if two matrices A and B are equal, they are still equivalent after some arbitrary permutation of rows? - eigenchris
No, A and B considered equal if A is a 'mirrored' version of B vice versa (e.g if A=[1 2 3 4 5] and B=[5 4 3 2 1], A and B is considered equal). Thanks for noticing this, I'll update my question. - Abdullah Al Mubarok
If mirrored or flipped, is it upside down flipped or left-right flipped? It appears to be upside-down flipped to me. - Divakar
Yes, it is upside-down flipped - Abdullah Al Mubarok
Let me revise my previous example to make it clear. If A=[1 2; 3 4; 5 6] and B=[5 6; 3 4; 1 2], A and B is considered equal - Abdullah Al Mubarok

2 Answers

1
votes

Here's code that does what you want.

mydup = rand(5,2);
mycell = {mydup;mydup;rand(7,2);rand(3,2);rand(5,2)}

myNewCell = trimCell(mycell)

Where trimCell is the function below:

function myNewCell = trimCell(myCell)


exclude = false(size(myCell));
for iter = 1:size(myCell,1)
    toCompare = myCell{iter};
    comparisons = cellfun(@(x) all(size(x)==size(toCompare)) && myEquals(x, toCompare),myCell);
    % comparisons has at least 1 true in it, because toCompare==toCompare
    exclude(iter) = sum(comparisons)>1;
end

myNewCell = myCell(~exclude);

end

function boolValue = myEquals(x,y)

assert(all(size(x)==size(y)));

boolValue = true;
for iter = 1:size(x,1)
    thisRow = all(sort(x(iter,:))==sort(y(iter,:)));
    boolValue = boolValue && thisRow;
    if ~boolValue
       return 
    end

end

end

Basically, what this function does, is, for each matrix in the cell it checks first if the sizes are equal. If the sizes aren't equal, then we know the matrices aren't equal, even if we reorder the rows.

If they are the same size, then we need to check if they're equal after row reordering. That's accomplished by the function myEquals which goes through row by row and sorts the rows before comparing them. It exits with false on the first row it finds that is not equal after reordering.

Hope this helps, Andrew

1
votes

Here is a solution. Given a m x 1 column cell array C of matrices, this code deletes the equivalent duplicates. (Here it will delete the 4th and 5th matrices, which are equivalent to the 1st).

C{1} = magic(3);
C{2} = magic(4);
C{3} = magic(5);
C{4} = C{1};
C{5} = flipud(C{1});

myEq = @(A,B) isequal(A,B) | isequal(A,flipud(B)); %// equivalence operator tests for same or up-down flipped matrix
C = C(:);                                          %// ensure the cell array is a column
Crep = repmat(C,1,size(C,1));                      %// repeat cell array along rows to get a square
comp = cellfun(myEq,Crep,Crep');                   %'//get a comparison matrix by comparing with transpose
comp = tril(comp) - eye(size(comp));               %// ignore upper triangle and diagonal
idx = find( sum(comp,2)==0 );                      %// get index of matrices we want to keep
result = C(idx);                                   %// get result

The output is deletes the 4th and 5th matrices, leaving the first three magic matrices:

>> result

result = 

[3x3 double]    [4x4 double]    [5x5 double]

>> result{1}, result{2}, result{3}

ans =

     8     1     6
     3     5     7
     4     9     2


ans =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1


ans =

    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9