user1778985
user1778985

Reputation:

Matlab: Find row indexes with common elements

I have a Matrix:

1 2 3  
4 5 6  
7 8 1 

How may I use matlab to find this:

for 1st row: row3
for 2nd row: ---
for 3rd row: row1

I want to have row indices for each row witch have common elements.

Upvotes: 4

Views: 1732

Answers (3)

Patrick
Patrick

Reputation: 1027

Depending on what you are planning to do with this output it could be redundant to have a match for "3rd row: row1".

You already have this match earlier in your output in the form of "1st row: row3"

Upvotes: 0

German Gomez-Herrero
German Gomez-Herrero

Reputation: 533

The solution proposed by Acorbe can be quite slow if you have many rows and/or long rows. I have checked that in most cases the two solutions that I present below should be considerably faster. If your matrix contains just few different values (relative to the size of the matrix) then this should work pretty fast:

function rowMatches = find_row_matches(A)
% Returns a cell array with row matches for each row

c = unique(A);
matches = false(size(A,1), numel(c));
for i = 1:numel(c)
   matches(:, i) = any(A == c(i), 2);
end

rowMatches = arrayfun(@(j) ...
    find(any(matches(:, matches(j,:)),2)), 1:size(A,1), 'UniformOutput', false); 

This other alternative might be faster when you have short rows, i.e. when size(A,2) is small:

function answers = find_answers(A)
% Returns an "answers" matrix like in Acorbe's solution

c = unique(A);
answers = false(size(A,1), size(A,1));
idx = 1:size(A,1);

for i = 1:numel(c)  
    I = any(A == c(i), 2);
    uMatch = idx(I);
    answers(uMatch, uMatch) = true;
    isReady = all(A <= c(i), 2);
    if any(isReady),
        idx(isReady) = [];
        A = A(~isReady,:);
    end
end

Upvotes: 0

Acorbe
Acorbe

Reputation: 8391

Consider this

A =  [1 2 3;       %Matrix A is a bit different from yours for testing
      4 5 6;
      7 8 1;
      1 2 7;
      4 5 6];

[row col] =size(A)            

answers = zeros(row,row);     %matrix of answers,...
                              %(i,j) = 1 if row_i and row_j have an equal element 

for i = 1:row
    for j = i+1:row                       %analysis is performed accounting for
                                          % symmetry constraint
        C = bsxfun(@eq,A(i,:),A(j,:)');   %Tensor comparison
        if( any(C(:)) )                   %If some entry is non-zero you have equal elements
            answers(i,j) = 1;               %output               
        end
    end
end
answers =  answers + answers';              %symmetric

The output here is

answers =

  0     0     1     1     0
  0     0     0     0     1
  1     0     0     1     0
  1     0     1     0     0
  0     1     0     0     0

of course the answers matrix is symmetric because your relation is.

Upvotes: 3

Related Questions