basic workflow to solve this problem can be described as described below -
- Sort all nonzero points.
- Start at the point with the highest point and set all nonzero points in your N-neighborhood to zeros.
- Do the same for the second highest and set all non-zeros in your N-neighborhood to zeros , excluding non-zero points with a higher value than the current one . This exclusive part can be implemented using the very useful MATLAB
triu inside codes. - Continue until any non-zero point is covered. Of course, as you move up this ladder, the search will be less, since the offer exception has been discussed previously.
These steps can be implemented using a vectorized approach without using special toolkits and assuming that A as an input is
%// Distance parameter N = 2; %// Find all non-zero points and then sort them in descending manner [x,y] = find(A~=0) pts = [xy] [val,sorted_idx] = sort(A(A~=0),'descend') pts = pts(sorted_idx,:) %// Find euclidean distances distmat = sqrt(squared_dist(pts,pts)) %// Find points to be removed (set to zero); then calculate their linear indices rm_pts = pts(any(triu(distmat<N,1),1),:) rm_lin_idx = sub2ind(size(A),rm_pts(:,1),rm_pts(:,2)) %// Use those linear indices to set those in the input as zeros out = A; out(rm_lin_idx) = 0;
Associated functional code (for finding squares of Euclidean distances) -
function sq_distmat = squared_dist(A,B) [nA,dim] = size(A); nB = size(B,1); A_ext = ones(nA,dim*3); A_ext(:,2:3:end) = -2*A; A_ext(:,3:3:end) = A.^2; B_ext = ones(nB,dim*3); B_ext(:,1:3:end) = B.^2; B_ext(:,2:3:end) = B; sq_distmat = A_ext * B_ext.'; return;
Code Execution -
A = 0 0 0 0.9000 0 0 0 0 0.2000 0 0 0.5000 0 0 0.7000 0 0 0 0 0.4000 0.1000 0 0 0 out = 0 0 0 0.9000 0 0 0 0 0 0 0 0.5000 0 0 0.7000 0 0 0 0 0 0 0 0 0
source share