COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### find the column index of the first occurance of a value in each row

• Email
• Follow

```I have a matrix A where
A=[1 0 0;
0 1 1;
1 1 1;
0 0 1]

I need to find the column index of the first occurance of 1 in each row. So in the example above, the resulting vector B should be:
B=[1;2;1;3]

Does anyone have any idea how to do it?

Many thanks!
```
 0
Reply hxhu76 (4) 8/19/2010 12:01:28 PM

See related articles to this posting

```metaug <hxhu76@gmail.com> wrote in message <1339137264.30660.1282233718285.JavaMail.root@gallium.mathforum.org>...
> I have a matrix A where
> A=[1 0 0;
>    0 1 1;
>    1 1 1;
>    0 0 1]
>
> I need to find the column index of the first occurance of 1 in each row. So in the example above, the resulting vector B should be:
> B=[1;2;1;3]
>
> Does anyone have any idea how to do it?
>
> Many thanks!

One way:
%Data
A=[1 0 0;
0 1 1;
1 1 1;
0 0 1];

%Engine
idx = find(A);
[r c] = ind2sub(size(A),idx);
cmin = accumarray(r,c,[],@min)
```
 0

```For a binary matrix, as shown in your example:

[idx,idx] = max(A,[],2);
idx
```
 0

```"Matt Fig" <spamanon@yahoo.com> wrote in message <i4jo0s\$6sb\$1@fred.mathworks.com>...
> For a binary matrix, as shown in your example:
>
> [idx,idx] = max(A,[],2);
> idx

Matt, that will return an incorrect result if a row has all zeros.

Also, to simplify mine from above: it could just be:
[r c] = find(A); %skip finding linear indices and the call to ind2sub
```
 0

```"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <i4jpg7\$c7t\$1@fred.mathworks.com>...
> "Matt Fig" <spamanon@yahoo.com> wrote in message <i4jo0s\$6sb\$1@fred.mathworks.com>...
> > For a binary matrix, as shown in your example:
> >
> > [idx,idx] = max(A,[],2);
> > idx
>
> Matt, that will return an incorrect result if a row has all zeros.
>
> Also, to simplify mine from above: it could just be:
> [r c] = find(A); %skip finding linear indices and the call to ind2sub

Good point!  I would ask what the OP wants to do in such a case.
For example:

A = [0 0 0 0;1 0 1 0;0 0 1 1;0 0 0 1]

[h,cmin2] = max(A,[],2);
cmin2 = cmin2.*h

Now this matches your ACCUMARRAY solution.  Still for binary matrices.
```
 0

```I am using 2007b, on XP 64.  I am surprised to find that the niave FOR loop is WAY faster than either of our solutions.  Sean, what are you using, and is this still true?

N = 5000;
A = round(rand(N));

cmin3 = zeros(N,1);
for ii=1:N
for jj = 1:N
if A(ii,jj)
cmin3(ii) = jj;
break
end
end
end
```
 0

```metaug <hxhu76@gmail.com> wrote in message <1339137264.30660.1282233718285.JavaMail.root@gallium.mathforum.org>...
> I have a matrix A where
> A=[1 0 0;
>    0 1 1;
>    1 1 1;
>    0 0 1]
>
> I need to find the column index of the first occurance of 1 in each row. So in the example above, the resulting vector B should be:
> B=[1;2;1;3]
>
> Does anyone have any idea how to do it?
>
> Many thanks!

This does exactly what you want:

http://www.mathworks.com/matlabcentral/fileexchange/24641-vectorized-find-with-first-option

>> B = findfirst(A,2)

B =

1
2
1
3

% Bruno
```
 0

```"Matt Fig" <spamanon@yahoo.com> wrote in message <i4jque\$du4\$1@fred.mathworks.com>...
> I am using 2007b, on XP 64.  I am surprised to find that the niave FOR loop is WAY faster than either of our solutions.  Sean, what are you using, and is this still true?
>
>
> N = 5000;
> A = round(rand(N));
>
>
> cmin3 = zeros(N,1);
> for ii=1:N
>     for jj = 1:N
>         if A(ii,jj)
>             cmin3(ii) = jj;
>             break
>         end
>     end
> end

Very Nice!
I am able to replicate that (64bit Mac with R2009b):
%%%
N = 5000;
A = round(rand(N));

tic
[r c] = find(A);
cmin1 = accumarray(r,c,[],@min);
toc
tic
[h,idx] = max(A,[],2);
cmin2 = h.*idx;
toc
tic
cmin3 = zeros(N,1);
for ii=1:N
for jj = 1:N
if A(ii,jj)
cmin3(ii) = jj;
break
end
end
end
toc
isequal(cmin1,cmin2,cmin3)

%{

Elapsed time is 2.553398 seconds.
Elapsed time is 0.068724 seconds.
Elapsed time is 0.000727 seconds.

ans =

1
%}
```
 0

```"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <i4js2i\$suu\$1@fred.mathworks.com>...
> "Matt Fig" <spamanon@yahoo.com> wrote in message <i4jque\$du4\$1@fred.mathworks.com>...
> > I am using 2007b, on XP 64.  I am surprised to find that the niave FOR loop is WAY faster than either of our solutions.  Sean, what are you using, and is this still true?
> >
> >
> > N = 5000;
> > A = round(rand(N));
> >
> >
> > cmin3 = zeros(N,1);
> > for ii=1:N
> >     for jj = 1:N
> >         if A(ii,jj)
> >             cmin3(ii) = jj;
> >             break
> >         end
> >     end
> > end
>
> Very Nice!
> I am able to replicate that (64bit Mac with R2009b):

I figured out why the for loops are much faster.  In that example the round function is going to force approximately half of the first column to be 1 and the second/3rd columns will soon follow.  Thus the jj-loop never has to traverse particularly deep.

I padded the rows with N zeros at the front and time tested it:
N = 5000;
A = [false(N),round(rand(N))];

tic
[r c] = find(A);
cmin1 = accumarray(r,c,[],@min);
toc
tic
[h,idx] = max(A,[],2);
cmin2 = h.*idx;
toc
tic
cmin3 = zeros(N,1);
for ii=1:N
for jj = 1:2*N
if A(ii,jj)
cmin3(ii) = jj;
break
end
end
end
toc
isequal(cmin1,cmin2,cmin3)

%{

Elapsed time is 2.775707 seconds.
Elapsed time is 0.143720 seconds.
Elapsed time is 0.906551 seconds.

ans =

1
%}
```
 0

```"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message
> I figured out why the for loops are much faster.  In that example the round function is going to force approximately half of the first column to be 1 and the second/3rd columns will soon follow.  Thus the jj-loop never has to traverse particularly deep.
>
> I padded the rows with N zeros at the front and time tested it:
> N = 5000;
> A = [false(N),round(rand(N))];

Padding is an ultra worst-case for sure.  A more likely worst case (perhaps) would be a sparse A.

A = rand(N)>.9  % Or even .99 -- whatever.
```
 0