Find the neighbors of all zeros elements in a matrix

matlab, matrix, vector

Solution

If you would like to keep the order in which you have stated in your question, this might be it -

Code

%%// Given data
A=[0 2 3 5 4 7 8
   1 8 2 7 5 2 9
   0 1 2 4 8 0 5
   2 4 8 6 0 5 8
   1 1 2 5 8 3 6];

%%// Find indices that have value zero
[indx,indy] = find(A==0);

%%// OP seems to be travelling row-wise, so sort the indices column-wise
[indx,y1] = sort(indx);
indy = indy(y1);

%%// Get the 8 neighboring row and column offsets  
row1 = bsxfun(@plus,indx,[-1 -1 -1 0 0 1 1 1]);
col1 = bsxfun(@plus,indy,[-1 0 1 -1 1 -1 0 1]);

%%// Get the valid positions
valid_pos = row1>0 & row1<=size(A,1) & col1>0 & col1<=size(A,2);

%%// Get valid row and column numbers and then valid indices
ind1 = (valid_pos.*col1-1).*size(A,1) + valid_pos.*row1;

%%// Get valid linear indices
ind1 = reshape(ind1',1,numel(ind1)); %%//'
ind1 = ind1(ind1>0);

%%// Find the unique indices without sorting
[~, idxs, ~] = unique(ind1, 'first');
ind1 = ind1(sort(idxs));

%%// Get matrix values from indices and remove the zeros themselves
OUT = A(ind1);
OUT(OUT==0) = [];

Output

OUT =

     2     1     8     1     2     4     5     2     9     8     5     5     8     4     6     5     8     3

Problem

In matlab, I have a matrix A of non-negative entries. See the following one: ``` A=[0 2 3 5 4 7 8 1 8 2 7 5 2 9 0 1 2 4 8 0 5 2 4 8 6 0 5 8 1 1 2 5 8 3 6]; ``` I want to find the neighbors of all zero elements expect the zero element. This means that I want to store in a vector v the neighbors of A(1, 1), A(2, 5), A(3, 1), A(3, 6), A(4, 5), and A(5, 1) and if one of these neighbors is zero then I do not store it. By neighbors of element (i, j) I mean the elements that are far away from (i, j) by one element, i.e., A(i, j+1), A(i, j-1), A(i-1, j), A(i-1, j-1), A(i-1, j+1), A(i+1, j), A(i+1, j-1), and A(i+1, j+1). Every element (i, j) has 7 neighbors. I do not store repetition elements. This means that, if for example A(1, 1)=0 and A(1,3)=0 and A(1,2)=1 then I will store A(1, 2) only once. In my previous example the vector v will be this one: ``` v=[2 1 8 1 2 4 5 2 9 8 5 5 8 4 6 5 8 3]; ``` How to do this in matlab without loops? This my code for square matrix: cl_ is the number of zero in my matrix. ix_ is the row indices of the zero elements and iy_ is the column indices of the zero elements. ``` for i_=1:length(cl_) ixn1_(1:2)=ix_(i_); ixn2_(1:3)=ix_(i_)-1; ixn3_(1:3)=ix_(i_)+1; iyn1_=iy_(i_)-1; iyn2_=iy_(i_)+1; iyn3_(1:3)=[iy_(i_)-1, iy_(i_), iy_(i_)+1]; ixn_{i_}=[ixn1_, ixn2_, ixn3_]; iyn_{i_}=[iyn1_, iyn2_, repmat(iyn3_, 1, 2)]; end % find the neighbors ```

Original source