I've stored (row,col,val) information of
key1: (1,1) (1,2) (1,3) (4,2) (3,4)
attribute1: 2 3 4 2 5
as follows:
Structure A1:
key row1: 1 1 1 4 3
key col1: 1 2 3 2 4
attribute1: 2 3 4 2 5
Similarly, for structure A2
Structure A2:
key row2: 2 2 1 3
key col2: 1 2 3 4
attribute2: 1 0 1 5
Now, I'd like to be able to search for common entries in both row and column key items between structure A1 and A2 simultaneously. That is conceptually find [common_item, index]=intersect([row2,col2],[row1,col1]). I'd like the final result is insensitive to the order of row and col. So, in my example (1,2) key value is equal to (2,1) value. Then, the attribute value of common entries should be added together. The intended result is
Structure Result: //it recognizes (1,2) and(2,1) are the same.
key row: 2 1 3
key col: 1 3 4
attribute: 4 5 10
How should I proceed to search for common entries and do some operation ? ismember
function can search for common item just in one row and if there are multiple occurrence, it just count the first. In addition, as I said, I want it to be order insensitive in key values.
Thanks for any help.
first use sort
to achieve row-col order insensitivity, next use unique
to handle row-col duplicates within each structure, and finally use ismember
(with 'rows'
) to find common keys between the structures. note that I added an inner duplication to each structure to show the second stage effect:
% struct1
row1 = [1 1 1 2 4 3];
col1 = [1 2 3 1 2 4];
att1 = [2 3 4 6 2 5];
% struct2
row2 = [2 2 1 3 3];
col2 = [1 2 3 1 4];
att2 = [1 0 1 1 5];
% sort in 2nd dimension to get row-column indexes insensitive for order
idx1 = sort([row1(:) col1(:)],2);
idx2 = sort([row2(:) col2(:)],2);
% search for duplicates inside each struct
[idx1,~,bins1] = unique(idx1,'rows','stable');
att1 = accumarray(bins1,att1);
[idx2,~,bins2] = unique(idx2,'rows','stable');
att2 = accumarray(bins2,att2);
% search common entries
common1 = ismember(idx1,idx2,'rows');
row = idx1(common1,1);
col = idx1(common1,2);
common2 = ismember(idx2,[row col],'rows');
% add common values
att = att1(common1) + att2(common2);
Result.row = row';
Result.col = col';
Result.attribute = att';
disp(Result)
and you get:
Result =
row: [1 1 3]
col: [2 3 4]
attribute: [10 6 10]