在矩阵中查找所有零元素的邻居

时间:2014-03-25 18:21:52

标签: matlab vector matrix

在matlab中,我有一个非负项的矩阵A.请参阅以下内容:

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];

我想找到所有零元素的邻居期望零元素。这意味着我想在向量v中存储A(1,1),A(2,5),A(3,1),A(3,6),A(4,5)和A(5,1),如果其中一个邻居为零,那么我就不存储它。

元素(i,j)的邻居是指远离(i,j)一个元素的元素,即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)和A(i + 1,j + 1)。每个元素(i,j)都有7个邻居。

我不存储重复元素。这意味着,如果例如A(1,1)= 0且A(1,3)= 0且A(1,2)= 1那么我将仅存储A(1,2)一次。

在我之前的例子中,向量v将是这一个:

v=[2 1 8 1 2 4 5 2 9 8 5 5 8 4 6 5 8 3];

如何在没有循环的matlab中执行此操作?

这是我的方阵代码:cl_是矩阵中的零数。 ix_是零元素的行索引,iy_是零元素的列索引。

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

3 个答案:

答案 0 :(得分:5)

如果您不关心值的顺序:

mask = A==0;
neighborMask = xor(conv2(double(mask),ones(3),'same')>0,mask);
v = A(neighborMask)

答案 1 :(得分:3)

如果您想保留您在问题中说明的顺序,可能就是这样 -

<强>代码

%%// 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) = [];

<强>输出

OUT =

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

答案 2 :(得分:2)

首先,我假设你知道&#34;发现&#34;命令: 例如topbot=find(abs(zz)==H);找到zz的所有等于H的元素,并将它们存储在一个长向量中,&#34; topbot&#34;。

唯一不幸的是它将矩阵位置存储为单个数字,因此(3,1)存储为3,等等。因此,如果您希望行和列的公式为column = ceiling((number-1)/numrows)和{{ 1}}(没有语法不对,但你明白了)。 (编辑:哎呀,数学是超级难的,一个错误无处不在)

之后,它应该只是删除重复项并确保您不会得到负行或列。

最后,矩阵值可以由单个索引调用,因此如果A是8乘8矩阵,row = number mod numrows与调用A(15)相同。