# classify "rows" of numbers contained in different arrays

2 views (last 30 days)
Sim on 12 Jan 2022
Edited: Sim on 12 Jan 2022
Hi, I would need to classify "rows" of numbers contained in different arrays, and I would like to optimize the code (with a more compact one), by removing a loop for at the (step 2.2) in the following script: any idea?
Otherwise, in general, any idea about how to classify my rows in a more compact way than what I did in this entire script?
% INPUT and GOAL
% I have 4 arrays/groups which contain "rows" of numbers (e.g. A1 contains
% row "1 3" and row "2 5"). My goal would be to create a matrix which
% contains all the unique "rows" appearing in all the 4 arrays/groups,
% and for each of them I would like to know to which array/group they
% belong to (e.g. by assigning a number 1 if a row belongs to one of the 4 groups,
% and assigning a number zero if a row does not belong to a certain group)
A1 = [1 3;
2 5;
6 1;
5 9;
1 2;
3 2;];
A2 = [5 9;
6 2;
1 2;
1 3;
3 2];
A3 = [1 3;
2 5;
6 1;
5 9;
2 3;
9 7;
3 4];
A4 = [3 1;
2 5;
6 1;
5 9;
2 1;
3 2];
% OUTPUT
% (step 1) I create a matrix with unique "rows" of numbers.
% This matrix should also tell me in which of the previous 4 arrays/groups
% my unique "rows" belong to.
A = {A1, A2, A3, A4};
ur = unique(vertcat(A{:}),'rows');
for i = 1 : length(A)
[idx1,~] = ismember(ur,A{i},'row');
belong_to_group(:,i) = idx1;
end
% M1 = | unique rows | which array/group my "rows" belong to, i.e. A1, A2, A3, A4 |
M1 = [ur belong_to_group]
% in the following matrix, for example, the row "1 2" appears in the
% arrays/groups A1 and A2
M1 =
1 2 1 1 0 0
1 3 1 1 1 0
2 1 0 0 0 1
2 3 0 0 1 0
2 5 1 0 1 1
3 1 0 0 0 1
3 2 1 1 0 1
3 4 0 0 1 0
5 9 1 1 1 1
6 1 1 0 1 1
6 2 0 1 0 0
9 7 0 0 1 0
% (step 2) Then, I have noticed that - in my system - some unique rows are actually duplicate, i.e.
% row "1 2" is equivalent to "2 1", or row "1 3" is equivalent to "3 1".
% I therefore decided to condense the information contained in both duplicates into a
% single row, i.e. by summarizing the two duplicate rows in my matrix
% M1(1,:) = [1 2 1 1 0 0]
% M1(3,:) = [2 1 0 0 0 1]
% into a single row in a new matrix:
% M2(1,:) = [1 2 1 1 0 1]
% (step 2.1) get non-duplicate rows in a sub-matrix
[~,idx2] = ismember(ur,ur(:,[2,1]),'row');
array2 = [idx2 (1:length(ur))'];
M2_unique = M1(find(~idx2),:);
% (step 2.2) condense duplicate rows into single rows
j = 1;
for i = 1 : length(ur)
if array2(i,1) ~= 0
M2_repeat(j,:) = [ M1(min(array2(i,1),array2(i,2)),1:2) ...
sum([M1(min(array2(i,1),array2(i,2)),3:end);M1(max(array2(i,1),array2(i,2)),3:end)]) ];
array2(array2(i,1),1) = 0;
array2(array2(i,2),1) = 0;
j = j + 1;
end
if all(array2(:,1))
return
end
end
% (step 2.3) join non-duplicate rows with condensed duplicate rows in a new matrix
M2 = vertcat(M2_repeat,M2_unique)
M2 =
1 2 1 1 0 1
1 3 1 1 1 1
2 3 1 1 1 1
2 5 1 0 1 1
3 4 0 0 1 0
5 9 1 1 1 1
6 1 1 0 1 1
6 2 0 1 0 0
9 7 0 0 1 0
My question: How can I write the (step 2.2) in a more compact way, without using the loop for?
Otherwise, in general, any idea about how to classify my rows in a more compact way than what I did in this entire script?