tags:

views:

84

answers:

3

For an arbitrary sized matrix x, find the index of the last non-zero element in each row of a given matrix.

For example. For the matrix

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ]

The vector [ 3 6 0 5 ] should be obtained.

+3  A: 

Here's one version:

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
c = arrayfun(@(k) find(x(k,:)~=0,1,'last'), 1:size(x,1), 'UniformOutput',false);
c( cellfun(@isempty,c) ) = {0};
v = cell2mat(c);

v =
     3     6     0     5

EDIT: Consider this alternative solution:

[m,v] = max( cumsum(x'~=0) );
v(m==0) = 0;

v =
     3     6     0     5
Amro
you cab probably write a better vectorized solution using a combination of CUMSUM and DIFF.. Let's see if I can figure one out :)
Amro
I really Appreciate that ..
Jack Lu
@Jack Lu: If you find a solution useful, please consider upvoting/accepting it.
Jonas
@Jack Lu: I think I got it, check out the new version..
Amro
+4  A: 

Here's a shorter version, combining find and accumarray

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
%# get the row and column indices for x
[rowIdx,colIdx] = find(x);
%# with accumarray take the maximum column index for every row
v = accumarray(rowIdx,colIdx,[],@max)'
v =
     3   6   0   5
Jonas
nice accumarray usage, i'll try to remember it. +1
Adrien
+1  A: 

My answer's a bit twisted but it should work too

x = [ 0 9 7 0 0 0; 5 0 0 6 0 3; 0 0 0 0 0 0; 8 0 4 2 1 0 ];
[~,pos] = max([fliplr(x~=0),ones(size(x,1))],[],2);
v = size(x,2)-pos' +1;
Adrien
@Adrien: you need to add one to `v`...
Amro
Adrien

related questions