# Zero-crossing calculation

42 views (last 30 days)
Jayanta Deb on 12 Aug 2017
Commented: GIULIA CISOTTO on 3 Nov 2020
Hi all, I need a script which can calculate zero crossing of the signal. I have the value of x and y. The script should be able to calculate the exact position of zero crossing points. Help!

Star Strider on 12 Aug 2017
This is reasonably robust:
function ZC = ZeroX(x,y)
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
zxidx = zci(y);
for k1 = 1:numel(zxidx)
idxrng = max([1 zxidx(k1)-1]):min([zxidx(k1)+1 numel(y)]);
xrng = x(idxrng);
yrng = y(idxrng);
ZC(k1) = interp1( yrng(:), xrng(:), 0, 'linear', 'extrap' );
end
end
x = linspace(0, 11*pi, 42); % Create Data
y = sin(x); % Create Data
ZC = ZeroX(x,y);
figure(1)
plot(x, y, '-r')
hold on
plot(ZC, zeros(size(ZC)), 'pg')
hold off
grid
GIULIA CISOTTO on 3 Nov 2020
Dear Ike Brown,
thank you for sharing your code. However, I would like to let you know that it seems to incorrectly detect ZC points.
I wrote an alternative Matlab script (myZC.m) to find the ZC. Here, you can find it.
To test the difference between ZeroX and myZC, you can run a modified version of your toy example as follows:
rng(shuffle)
x = linspace(0, 11*pi, 42); % Create Data
y = sin(x); % Create Data
n = 1 + 2.*randn(1,length(y)); % add Gaussian noise
y = y+n;
% myZC
[myZC, myZCx, myZCy, ys] = myZC(x,y);
% Comparison with ZeroX
ZC = ZeroX(x,y);
% Print ZC values
[length(myZC), length(ZC)]
% Plot figure
figure, hold all
plot(x,y,'k'), xlabel('No. samples'), ylabel('Amplitude [A.U.]')
plot(x,ys,'b:')
plot(x(myZC), zeros(size(myZC)), 'bs', 'markerface', 'b')
plot(myZCx, myZCy, 'cd', 'markerface', 'c')
plot(ZC, zeros(size(ZC)), 'pr'), grigrid on, legend('y', 'ys', 'myZC', 'myZC-refined', 'ZC')
In attach, you can also find a representative plot: you can notice that ZeroX can mostly correctly detect the zero-crossigs, but sometimes it misses one (between sample no.17 and sample no.18) or it detects a false one (at sample 27).
ZeroX returns a correct number of zero-crossings, but when plotted, they are mismatched to the raw signal, while myZC can correctly compute the number of zero-crossing and precisely get their locations.

MSP on 12 Aug 2017
zeroindex=find(y==0)
x(zeroindex)
GIULIA CISOTTO on 3 Nov 2020
Dear Shubhashree, this is not actually true: zero-crossing is defined as the number of times a signal changes its sign. If you apply your computation, then you might have an incorrect number of ZC. Let's consider a signal with a number of consecutive samples set to zero: then, you will add all of them to the ZC counter. However, you would be wrong in that. Please, check my answer above for the correct computation of ZC.