I want to find and zero peaks in a vector with the shortest width, i.e. peaks that have a single sample being non-zero and the neighbouring samples zero, i.e. [0 ~0 0]
with ~0
being the peak. Example: if x = [1 0 2 0 0 3 0 4 5 6 0 7 0 8]
, then I want to find the 2, 3 and 7 and make them 0, i.e. x
becomes [1 0 0 0 0 0 0 4 5 6 0 0 0 8]
. The following code does the trick, but is there a more efficient or better way to do this, or does a Matlab function exist that finds a certain pattern in a vector (or even matrix)?
% remove peaks of shape [0 ~0 0]
k = find(x);
for j=k'
if j==numel(x) || j==1
elseif ~x(j-1) && ~x(j+1)
x(j) = 0;
end
end
You are looking for elements where the convolution with the kernel [1,1,1]
does not differ with the original. The only complication is that we have to ignore the edge case:
x = [1 0 2 0 0 3 0 4 5 6 0 7 0 8];
y = conv(x,[1,1,1],'same');
ind = find(x==y);
x(ind(2:end-1)) = 0
or
x(find(x(2:end-1)==conv(x,[1,1,1],'valid'))+1) = 0
if faced with the prospect of both positive and negative numbers, then based on Craigim's suggestion in the comments:
xx = abs(x);
x(find(xx(2:end-1)==conv(xx,[1,1,1],'valid'))+1) = 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With