Optimizing zero-crossing indices

filename='AAA'
load = xlsread(filename,1,'C:C');
extension = xlsread(filename,1,'D:D');
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
zxidx= zci(load);
figure
plot(extension, load)
hold on
plot(s(zxidx),l(zxidx),'o')
Capture.PNG
As you can see from the plot, it generally capture the targeted data well. But they are not correct.
I feel like I need to control the zero-crossing indexing function, but I am challenging how to even fine-tune it further.
Thank you.

 采纳的回答

Star Strider
Star Strider 2019-1-19
I wrote ‘zci’ so I will do my best to help you with it.
It contains no error checking, so there can be a ‘wrap-around’ effect because of circshift, such that if the end of a sequence is on one side of zero and the beginning of the sequence is on the other, ‘zci’ will consider this a true zero-crossing, even though it is not. That may be what you are seeing. The solution is simply to delete the last index.
(I may consider writing a full function version of it as a File Exchange contribution that checks the ends of the sequence, and automatically deletes the end index in that event. The anonymous function version does not have that option.)

6 个评论

Wow!
The function is very useful for finding zero-crossing points. As you have mentioned, I just picked every other point instead of every point to eliminate overlapping points.
It would be a very good contributuion to MATLAB community if you can include the missing part in the current version. Thank you!
Capture.PNG
As always, my pleasure!
I intend to create a function file version of ‘zci’ and upload it to the File Exchange when it works the way I want it to, and is reliable and sufficiently robust. Your particular problem would require that it also return a vector indicating the direction of the data at a particular zero-crossing. I had not considered that before, so thank you for discovering it.
I gotta say I really don't get it, how does this even work, why DOES THIS WORK? haha
would be very thankfull if u explain..
A more robust version —
zci = @(x) find(diff([sign(x(:)); 0]));
t = linspace(0, 1, 500);
s = sin(2*pi*5*t);
zxv = zci(s);
figure
plot(t, s)
hold on
plot(t(zxv), s(zxv), 'rs')
hold off
grid
The original version element-wise-multiplied the signal with a one-index-shifted version of the signal. The explanation is simple arithmetic, nothing more is involved. Vectors of the same sign will always produce positive values when multiplied together, whether the vector elements are positive or negative. The zero-crossings occur where the elements to be multiplied together have opposite signs, producing a negative value in the resulting vector, that the find call then detects. The problem with that approach is that if the first and last elements of the vector had opposite signs, the last element of the vector would be detected (erroneously) as zero-crossing, due to the ‘wrap-around’ effect that circshift produced.
The more robust version simply looks for the sign changes directly, and since it uses diff rather than circshift, avoids the wrap-around effect. Concatenating the 0 at the end of the vector corrects for the diff function result being one element less than the original vector.
The indices returned are approximate, so not the exact zero-crossings, however that was always the intent anyway. Creating a short range of indices around the returned indices and interpolating those segments to find the actual zero-crossings in that region produces correct and reasonably precise zero-crossing estimates. There are several ways to do the interpolation. I generally use interp1 for this, althoough for very large numbers of interpolations in a very long signal, using direct linear regression with the mldivide,\ operator is usually more efficient. Both require looping over the number of zero-crossings detected to do the interpolations. For extremely noisy signals, removing as much of the noise as possible first is always necessary, since there can be multiple spurious zero-crossings near the actual zero-crossings in extremely noisy signals, and removing the noise first is usually easier that searching for and correcting closely-spaced zero-crossings aftwerwards.
.
How can we find the value of zero crosssing points in the form of array.
The ‘zci’ function should produce an array (vector) of indices.
The exact values of the zero-crossings require interpolation of both the independent and dependent variables in a narrow range of indices around each index returned by ‘zci’. This requires a loop.
.

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Matrix Indexing 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by