Efficient method for finding a value surrounded by zeros in a vector

I want to find the zero peaks in the vector with the shortest width, that is, peaks in which one sample is different from zero, and the neighboring samples are zero, that is, [0 ~0 0] with ~0 is the peak. Example: if x = [1 0 2 0 0 3 0 4 5 6 0 7 0 8] , then I want to find 2, 3 and 7 and make them 0, i.e. x will become [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 is there a Matlab function that finds a specific pattern in 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 
+5
source share
3 answers

You are looking for elements where the convolution with the kernel [1,1,1] does not differ in the original. The only complication is that we must 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 

Faced with the prospect of both positive and negative numbers, it is then based on Craigim's suggestions in the comments:

 xx = abs(x); x(find(xx(2:end-1)==conv(xx,[1,1,1],'valid'))+1) = 0 
+8
source

Using conv (along Dan's response line) is probably the best approach; but this can also be done with strfind :

 x(strfind(x~=0, [0 1 0]) + 1) = 0; 

Or using diff to calculate the second order difference:

 x(find(diff(~x, 2)==2) + 1) = 0; 
+5
source

Here is my way to do it

 x_add = x(1:end-2) + x(2:end-1) + x(3:end); x(find([0,x(2:end-1)==x_add,0]))=0; 

It adds the previous value and the next value to each of them and checks which one has not changed.

+5
source

All Articles