Question

I have a cell matrix TILER that include some matrix with different sizes.

TILER=[22x4 double]    [1265x4 double]    [58x4 double]    [31x4 double]     [58x4 double]

and we know that some matrixes are duplicate, for example [58x4 double] matrix. how can we remove duplicate matrixes from a cell array to have :

TILER=[22x4 double]    [1265x4 double]    [58x4 double]    [31x4 double]

here is a link, but it doesn't work

Was it helpful?

Solution

In this case it's hard to avoid loops. You can go along the following lines:

ind = true(1,numel(TILER)); %// true indicates non-duplicate. Initiallization
for ii = 1:numel(TILER)-1
    for jj = ii+1:numel(TILER)
        if isequal(TILER{ii}, TILER{jj})
            ind(jj) = false; %// mark as duplicate
        end
    end
end
TILER2 = TILER(ind);

Some optimizations are possible. For example:

  • In the inner loop don't consider values that have been detected as duplicates in a previous iteration of the outer loop.
  • Do a first check for equality of matrix sizes (this can be done efficiently with bsxfun), and then only test for equality between matrices that have the same size.

OTHER TIPS

You can also manipulate it into a cell of strings and take advantage of the 'unique' command; starting with a cell 'a' of matrices:

b=cell(0);
for i=1:length(a), cat(2,b,mat2str(a{i}));, end
b=unique(b);
c=cell(0);
for i=1:length(b), cat(2,c,eval(b{i}));, end

If sizes could be considered a valid criteria for identifying duplicates in a cell array and the number of dimensions are consistent across the cell array elements, you may use this -

t1 = cellfun(@size,TILER,'uni',0) %%// TILER is your input cell array
t2 = vertcat(t1{:})
t3 = squeeze(reshape(bsxfun(@eq,t2,permute(t2,[3 2 1])),numel(t2),[],size(t2,1)))
[~,p2] = unique(t3','rows','stable') %%//'
TILER = TILER(p2)

Thank You Luis Mendo for providing us with your answer.

I slightly modified your version and better suits my needs. my data is a cell of cells i.e.

for kk = 1 : length(cellOfCells)
    TILER = cellOfCells{kk};
    ind = true(1,numel(TILER)); %// true indicates non-duplicate. Initialization
for ii = 1:numel(TILER)-1
    for jj = ii+1:numel(TILER)
        if size(TILER{ii},1) ~= size(TILER{jj},1)
            continue
        else
        membership = (ismember(TILER{ii}, TILER{jj},'rows'));

            if sum(membership)==size(TILER{ii},1)
                ind(jj) = false; %// mark as duplicate
            end
        end
    end
end
TILER2{kk} = TILER(ind);
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top