Reputation: 301
I have a list as given below:
A= {[1 2], [2 1], [2 1 3],[3 4],[4 3]}
I need to simplify the matrix. For example, [3 4]
and [4 3]
form the same combination, only one of them is enough. Also, [1 2]
and [2 1]
is the same combinations, so I should be left with
newA= {[1 2],[2 1 3],[3 4]}
How do I do that?
Upvotes: 3
Views: 158
Reputation: 15837
Here is a solution using accumarray:
n = cellfun(@numel,A);
C=accumarray(n(:),1:numel(A),[],@(x){num2cell(unique(sort(vertcat(A{x}),2),'rows'),2)});
result = vertcat(C{~cellfun(@isempty,C)})
I tested 3 proposed answers with the following data in Octave:
A=arrayfun(@(x){randi([1 10],1,randi([1 10000]))},1:50);
Here is the result:
======NUM2STR=======:
Elapsed time is 1.13129 seconds.
======FOR LOOP=======:
Elapsed time is 0.237398 seconds.
======ACCUMARRAY=======:
Elapsed time is 0.036804 seconds.
With the following data:
A=arrayfun(@(x){randi([1 3],1,randi([1 5]))},1:500);
Result:
======NUM2STR=======:
Elapsed time is 0.384026 seconds.
======FOR LOOP=======:
Elapsed time is 10.9931 seconds.
======ACCUMARRAY=======:
Elapsed time is 0.0271118 seconds.
Upvotes: 3
Reputation: 112699
The most efficient way is probably to sort each vector and use two nested loops as follows:
As = cellfun(@sort, A, 'UniformOutput', false); % sort each vector
remove = false(size(A)); % initiallize. Entries to be removed will be marked true
for ii = 1:numel(A)
for jj = ii+1:numel(A)
remove(jj) = remove(jj) || isequal(As{jj}, A{ii}); % short-circuit OR
end
end
result = A(~remove);
Upvotes: 5
Reputation: 12214
One approach is to sort
the values and use unique
:
A = {[1 2], [2 1], [2 1 3],[3 4],[4 3]};
tmp = cellfun(@sort, A, 'UniformOutput', false);
tmp = cellfun(@num2str, tmp, 'UniformOutput', false);
[~, idx] = unique(tmp);
newA = A(idx);
Note 1 that I've had to make a dummy array of the string equivalent of A
due to unique
's handling of cell arrays. unique
can only work on cell arrays of strings/character vectors so we have to do a little manipulation to get the desired output.
Note 2 that cellfun
is almost always slower than the explicit loop, but I've used it here for brevity.
Upvotes: 5