Zero-crossing calculation
13 次查看(过去 30 天)
显示 更早的评论
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!
0 个评论
采纳的回答
Star Strider
2017-8-12
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
5 个评论
Ike Brown
2019-10-19
Thanks for posting this Star Strider! I found this very helpful. Here is a slight modification in order to avoid the following error "grid vectors not strictly monotonic increasing". This modification is based off of a forum answer by Jos (10584)
% ZeroX has been modified so as to avoid the following error "Error using griddedInterpolant
% The grid vectors are not strictly monotonic increasing."
%
% The following modifications are based off of this MatLab forum answer:
% https://www.mathworks.com/matlabcentral/answers/283718-grid-vectors-not-strictly-monotonic-increasing
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);
% Beginning of ZeroX2 modifications. The naming conventions follow
% those in the referenced MatLab forum, except that "X" is "yrng" and
% "Y" is "xrng".
[yrng2, ~, jyrng] = unique(yrng); %yrng is a new array containing the unique values of yrng. jyrng contains the indices in yrng that correspond to the original vector. yrng = yrng2(jyrng)
xrng2 = accumarray(jyrng, xrng, [], @mean); %This function creates a new array "xrng2" by applying the function "@mean" to all elements in "xrng" that have identical indices in "jyrng". Any elements with identical X values will have identical indices in jyrng. Thus, this function creates a new array by averaging values with identical X values in the original array.
ZC(k1) = interp1( yrng2(:), xrng2(:), 0, 'linear', 'extrap' );
end
end
GIULIA CISOTTO
2020-11-3
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.
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.
更多回答(1 个)
MSP
2017-8-12
zeroindex=find(y==0)
x(zeroindex)
3 个评论
Shubhashree Bal
2019-7-2
It is not necessary that there is sample at amplitude equal to 0.
Example:
x = [ 1 2 3 4 5];
y = [1 -1 -2 -3 -4];
k= find (y==0);
Conclusion: Instead of having zero crossing it will not return any index. Thus, we can check sign change for finding zero crossing accurately.
Thanks!
GIULIA CISOTTO
2020-11-3
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!