4

I have two values (k and j) which I know are within an nx3 matrix (M). I know that they're and on the same row and that j is always to the right of k, so if k is in M(2,1), then j will be in M(2,2). I tested for this earlier in the function, but now I want to know which row that is for a given k and j. I need the row number of their location to proceed. There are no duplicate combinations of k and j in the matrix.

So if I have the matrix

M=

1 4 5
1 5 7
k j 5
4 5 6
2 3 1

Then I want to know that they're in row 3. None of the columns are ordered.

What I have tried:

I used the code below

[row,~] = find(M==k);

I'm not sure how to look for a combination of them. I want to avoid using the find function. I hope to potentially use logical indexing.

How do I go about doing this? I hope this question makes sense.

Carly Coop
  • 47
  • 3
  • You wrote, *"j is always to the right of k"*. But your matrix `M` negate this statement! – Sardar Usama Aug 12 '16 at 10:51
  • @Sardar_Usama Thank you for the observation - corrected – Carly Coop Aug 12 '16 at 10:54
  • "I'm not sure how to look for a combination of them." But if you **know** that "j is always to the right of k", then you don't need to find the combination. Or did you mean that *if* `j` is on the same rows as `k`, you know it will be (immediately?) to the right of `j`? Your specification is still unclear. – beaker Aug 12 '16 at 17:45

3 Answers3

1

Use this:

row = find(((M(:,1) == k ) & ( M(:,2) == j)) | ((M(:,1) == k ) & ( M(:,3) == j)) | ((M(:,2) == k ) & ( M(:,3) == j)) )

Also, logical indexing can only give you a matrix with zeros at all other positions and one at your required position. But to get the index of that position, you will have to use find.

Nishant
  • 2,571
  • 1
  • 17
  • 29
  • 1
    but this assumes that `j` is in the first column and `k` in the second. I think the problem is more general, so `j` can be in any column except the last one (otherwise there will be no room for `k`). In this case, since the matrix has 3 columns, `j` could be in the second one and `k` in the last one –  Aug 12 '16 at 11:38
  • @SembeiNorimaki Thank you for pointing it out. Fixed it, not sure if it is optimal though. – Nishant Aug 12 '16 at 11:52
  • just remove the part where j is in column 1 and k in column 3, since I think is not a valid answer, the other two cases are ok. –  Aug 12 '16 at 12:22
1

You can use bsxfun -

find(all(bsxfun(@eq,A(:,1:2),[k,j]),2) | all(bsxfun(@eq,A(:,2:3),[k,j]),2))

Being a relational operation with bsxfun, according to this post on benchmarked results, this should be pretty efficient.

Sample runs

Case #1 :

A =
     1     4     5
     1     5     7
     6     7     1
     4     5     6
     2     3     1
k =
     6
j =
     7
>> find(all(bsxfun(@eq,A(:,1:2),[k,j]),2) | all(bsxfun(@eq,A(:,2:3),[k,j]),2))
ans =
     3

Case #2 :

A =
     1     4     5
     1     5     7
     1     6     7
     4     5     6
     2     3     1
k =
     6
j =
     7
>> find(all(bsxfun(@eq,A(:,1:2),[k,j]),2) | all(bsxfun(@eq,A(:,2:3),[k,j]),2))
ans =
     3
Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
1

Slightly different version on bsxfun. This one doesn't limit the matrix to three columns.

find(sum(((bsxfun(@eq,M,j) + bsxfun(@eq,M,k)) .* M).' ) == j+k >0)

Case 1:

M = [
     1     4     5
     1     5     7
     6     7     1
     4     5     6
     2     3     1]
k=6;j=7; 

ans =  3

Case 2:

M=[
     1     4     5
     1     5     7
     1     6     7
     4     5     6
     2     3     1
     ];
k=6;j=7;

ans =  3
kkuilla
  • 2,226
  • 3
  • 34
  • 37