12

Suppose I have an (m x n) matrix Q, and a row vector r, e.g.

Q = [ 1 2 3 ; 4 2 3 ; 5 6 7 ; 1 2 3 ; 1 2 3 ; 1 2 5 ];

r = [ 1 2 3 ];

What is the easiest way to obtain a logical vector (of length m) that indicates which of the rows in Q are identical (for all elements) to the specified row r?

In the sample case above, that should be

[ 1 0 0 1 1 0 ];
reddish
  • 1,360
  • 2
  • 12
  • 27
  • Very closely related to: http://stackoverflow.com/questions/6209904/find-given-row-in-a-matrix – eric Mar 07 '15 at 18:16

4 Answers4

21

You can use ismember and do it in a single line:

>> ismember(Q,r,'rows')'

ans =

     1     0     0     1     1     0
petrichor
  • 6,459
  • 4
  • 36
  • 48
13
all(bsxfun(@eq, r, Q),2)'

bsxfun(@eq, r, Q) compares each row and returns a matrix with same size as Q:

>> bsxfun(@eq, r, Q)

ans =

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

the all function computes if the result of bsxfun is all true along each row separately. Thus it returns:

>> all(ans,2)'

ans =

   1     0     0     1     1     0

and yeah, there is also a transpose operator ' to match your desired row output

Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58
1
a = [1 1 1; 2 2 2; 3 3 3];
b = a(1:2,;);
[temp locb] = ismember(a,b,'rows');
b(locb(locb~=0),:)

ans =

     1     1     1
     2     2     2
neouyghur
  • 1,577
  • 16
  • 31
0

Easier way with repmat:

a = [1 2 3; 4 5 6; 7 8 9];
t = [4 5 6];
[x,y] = size(a);
r = all(a==repmat(t,y,1), 2)'
Castilho
  • 3,147
  • 16
  • 15
  • also less efficient and slower, see: http://blogs.mathworks.com/loren/2008/08/04/comparing-repmat-and-bsxfun-performance/#9 – Gunther Struyf May 09 '12 at 11:19
  • Efficiency where it is not needed is a curse. Simplicity to write and understand relates directly to better code. – Castilho May 09 '12 at 11:29
  • what's so difficult to understand about `bsxfun(@eq, r, Q)`?? If you learn it with such easy examples, you benefit from it later when applying on complex problems.. – Gunther Struyf May 09 '12 at 11:31
  • Readability. You've just threw that out of the window. And to gain what? 0,01 second. Use arrayfun, spfun, cellfun, bsxfun when performance is really an issue. Otherwise, you'll be unnecessarily overcomplicating the code. Besides that, minus voting a right answer is downright juvenile. – Castilho May 09 '12 at 11:35
  • 2
    if you know what bsxfun does, readability is not an issue at all; Every function has to be learned at some point.. By the way, in case that readability still is an issue, they invented something for that: comments. If I didn't know what repmat does, your code wouldn't make sense either – Gunther Struyf May 09 '12 at 11:39
  • http://stackoverflow.com/questions/183201/should-a-developer-aim-for-readability-or-performance-first http://stackoverflow.com/questions/30754/performance-vs-readability http://programmers.stackexchange.com/questions/43151/should-you-sacrifice-code-readability-with-how-efficient-code-is – Castilho May 09 '12 at 11:47
  • I repeat myself: "If I didn't know what repmat does, your code wouldn't make sense either" Why is using `repmat` easier to understand? In the [doc of repmat](http://www.mathworks.nl/help/techdoc/ref/repmat.html) , bsxfun is literally mentioned as a (sometimes) better alternative: "If you have code that uses repmat and also a binary operator or function, you can transform the code to use the bsxfun function instead. In certain cases, this can provide a simpler and faster solution." – Gunther Struyf May 09 '12 at 11:55
  • 3
    I find `repmat` to be on a similar level of readability as `bsxfun` - it's the `ismember` solution that is much clearer. – Jonas May 09 '12 at 13:22