Find the unique arrays in a list of arrays

10 views (last 30 days)
Hi everyone.
This question is easy to describe, but I can't think of an easy way to do it. Given a list of binary matrices (i.e., elements are all '1's and '0's), how do I remove any duplicate matrices from that list. I.e,, I only want the unique matrices. Note that matrices in this list do not necessarily have to be the same size. For example, if
A = [0 1 1;1 1 1], B = [1 1 1;0 0 1], C = [0 1 1;1 1 1], D = [1 0;1 1]
Then the procedure must automatically remove either A or C as they are identical. By the way, I was thinking of storing all my arrays in a cell array.
Thank you.
Marcus.

Accepted Answer

Marcus
Marcus on 19 Feb 2023
Think I've found what I need. This code loops through each matrix in the list and checks if it's already in the unique_mats array using the isequal() function. If it's not already in the array, the current matrix is added to the unique_mats array. At the end of the loop, the code displays the unique matrices. PS: Chat GPT wrote this code for me !!!
% Example list of matrices
mat_list = { [0 1 1;1 1 1], [1 1 1;0 0 1], [0 1 1;1 1 1], [1 0;1 1] };
% Initialize empty array to store unique matrices
unique_mats = {};
% Loop through each matrix in the list
for i = 1:numel(mat_list)
mat = mat_list{i};
% Check if the current matrix is unique
is_unique = true;
for j = 1:numel(unique_mats)
if isequal(mat, unique_mats{j})
is_unique = false;
break;
end
end
% Add the current matrix to the unique_mats array if it's unique
if is_unique
unique_mats{end+1} = mat;
end
end
% Display the unique matrices
unique_mats{:}
  1 Comment
the cyclist
the cyclist on 19 Feb 2023
This solution follows the same principle as mine, but I would expect it will be faster because it will avoid some of the pairwise comparisons (where mine does all of them).
Good AI.

Sign in to comment.

More Answers (3)

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 19 Feb 2023
Edited: Sulaymon Eshkabilov on 19 Feb 2023
One of the viable fcns to use here is isequal(), e.g.:
A = [0 1 1;1 1 1]; B = [1 1 1;0 0 1]; C = [0 1 1;1 1 1];
ALL{1} = A;
ALL{2} = B;
ALL{3} = C;
if isequal(ALL{1}, ALL{2})
ALL{2}=[];
elseif isequal(ALL{2}, ALL{3})
ALL{3} = [];
elseif isequal(ALL{1}, ALL{3})
ALL{3} = [];
else
displ('OK')
end
ALL{:}
ans = 2×3
0 1 1 1 1 1
ans = 2×3
1 1 1 0 0 1
ans = []
  2 Comments
Marcus
Marcus on 19 Feb 2023
Yes, I see that this works. But this approach becomes very awkward if the number of matrices is even modestly large, e.g. >= 10. What would you do if there were 50 matrices to compare?
Sulaymon Eshkabilov
Sulaymon Eshkabilov on 19 Feb 2023
Edited: Sulaymon Eshkabilov on 19 Feb 2023
for .. end loop or switch might be an option. There might be some other more efficient ways to get it done for larger sizes.

Sign in to comment.


the cyclist
the cyclist on 19 Feb 2023
% Input
A = [0 1 1;
1 1 1];
B = [1 1 1;
0 0 1];
C = [0 1 1;
1 1 1];
D = [1 0;
1 1];
% Put them in cell array (as you suggested)
cellABCD = {A, B, C, D};
% Get the number of arrays
numberArrays = numel(cellABCD);
% Preallocate the array that holds the equality check
equalityCheck = zeros(numberArrays,numberArrays);
% For each unique pair of arrays, check for equality
for nc1 = 1:numberArrays
for nc2 = (nc1+1):numberArrays
equalityCheck(nc1,nc2) = isequal(cellABCD(nc1),cellABCD(nc2));
end
end
% Find the indices of the duplicates
[~,indexToDuplicate] = find(equalityCheck);
% Initialize the solution to be the full array, then delete the duplicates
uniqueCellABCD = cellABCD;
uniqueCellABCD(indexToDuplicate) = [];

Walter Roberson
Walter Roberson on 19 Feb 2023
Edited: Walter Roberson on 19 Feb 2023
find the maximum number of rows and columns and do a pass that pads each array with inf to maximum rows and columns and reshape to row. put all the rows into a 2d array. unique by rows and take the second output; that will be indices to one copy of each unique matrix, so retrieve those into your output.
This relies on the padding being a value not found in the matrices. Possibly nan would work but I didn't want to have to deal with the question of whether unique treats nan as equal.
  2 Comments
the cyclist
the cyclist on 19 Feb 2023
Indeed, padding with NaN will not serve the purpose here ...
unique([0 1 NaN; 0 1 NaN],"rows")
ans = 2×3
0 1 NaN 0 1 NaN
unique([0 1 Inf; 0 1 Inf],"rows")
ans = 1×3
0 1 Inf

Sign in to comment.

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!