Lowest initial row indices for at least 2 consecutive non-zero values ββper column
Given the sample matrix:
A =
0 0 0 0 -4 3
0 2 1 0 0 0
0 5 0 8 7 0
0 9 10 3 1 2
I want to find the smallest starting locations (row indices) for each column A
where at least two consecutive non-zero values ββare found. The result will look like this:
Output = [0, 2, 0, 3, 3, 0]
0
the output indicates that the condition minimum 2 consecutive non-zero values
does not hold.
Also, can this be generalized to the case of finding the initial indices of the minimum N
consecutive nonzero values?
source to share
At least 2 consecutive non-zero case values
%// Mask of non-zeros in input, A
mask = A~=0
%// Find starting row indices alongwith boolean valid flags for minimum two
%// consecutive nonzeros in each column
[valid,idx] = max(mask(1:end-1,:) & mask(2:end,:),[],1)
%// Use the valid flags to set invalid row indices to zeros
out = idx.*valid
Example run -
A =
0 0 0 0 -4 3
0 2 1 0 0 0
0 5 0 8 7 0
0 9 10 3 1 2
mask =
0 0 0 0 1 1
0 1 1 0 0 0
0 1 0 1 1 0
0 1 1 1 1 1
valid =
0 1 0 1 1 0
idx =
1 2 1 3 3 1
out =
0 2 0 3 3 0
General case
For the general case, the minimum N sequential case without zero can be used 2D convolution
with kernel as column vectors, e.g N
.:
mask = A~=0 %// Mask of non-zeros in input, A
%// Find starting row indices alongwith boolean valid flags for minimum N
%// consecutive nonzeros in each column
[valid,idx] = max(conv2(double(mask),ones(N,1),'valid')==N,[],1)
%// Use the valid flags to set invalid row indices to zeros
out = idx.*valid
Note that the 2D convolution can be replaced with a split version of the convolution as pointed out in Luis's comments, and it seems to be a little faster. More information on this can be obtained on this link
. So,
conv2(double(mask),ones(N,1),'valid')
can be replaced with conv2(ones(N,1),1,double(mask),'valid')
.
Example run -
A =
0 0 0 0 0 3
0 2 1 0 1 2
0 5 0 8 7 9
0 9 0 3 1 2
mask =
0 0 0 0 0 1
0 1 1 0 1 1
0 1 0 1 1 1
0 1 0 1 1 1
N =
3
valid =
0 1 0 0 1 1
idx =
1 2 1 1 2 1
out =
0 2 0 0 2 1
source to share