Find zeropoints with interpolation

4 views (last 30 days)
malik abdelli
malik abdelli on 20 Nov 2023
Edited: Matt J on 20 Nov 2023
Hello i have a very long vector a = [2000000x1].
I want to find the indexes of all the zeropoints in this vektor, when the values go from negative to positive.
Below you can find a part of the graph where you can see what i mean.
Does anyone know how i can code this?
i just found this function but this does only give me the nearest points before the zeropoints and not the exact index of the zeropoint crossing and then theres still the problem that i dont know how to get only the zeropoints that go from negative to positive values. "https://de.mathworks.com/matlabcentral/answers/267222-easy-way-of-finding-zero-crossing-of-a-function"
Thank you.

Accepted Answer

Matt J
Matt J on 20 Nov 2023
Edited: Matt J on 20 Nov 2023
x = linspace(0, 30, 100);
y = 80*sin(2*pi/5*x);
xq=linspace(min(x),max(x),numel(x)*1000);
yq= interp1(x,y,xq,'cubic');
cross=find(diff(sign(yq))>0);
plot(x, y,'o-b', xq(cross),yq(cross),'xr'),
xlabel('x'), ylabel('y')

More Answers (2)

Sam Chak
Sam Chak on 20 Nov 2023
Check this out to see if this approach, using the zerocrossrate() function, is acceptable for finding the indices of the zero points.
x = linspace(0, 10, 101);
y = sin(2*pi/5*x);
plot(x, y), grid on, xlabel('x'), ylabel('y')
[~, count, indices] = zerocrossrate(y, Method="comparison")
count = 3
indices = 1×101 logical array
Columns 1 through 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Columns 50 through 98 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Columns 99 through 101 0 0 0
%% Indices of the zero points
idx = find(indices == 1)
idx = 1×3
27 52 77

John D'Errico
John D'Errico on 20 Nov 2023
Edited: John D'Errico on 20 Nov 2023
Almost trivial. LEARN TO USE MATLAB! I'll start with a long vector.
x = linspace(0,20,1e7)';
y = cos(x);
Yes, we know where the zero points should lie, at least in this trivial example. For reference, those locations will happen at
syms X
solve(cos(X) == 0,'returnconditions',true)
ans = struct with fields:
X: pi/2 + pi*k parameters: k conditions: in(k, 'integer')
(Yes, I know that is also trivial to do, but it is nice to let MATLAB do the work in a maTLAB forum.) So we should expect to see zeros at:
format long g
k = (0:5)';
pi/2 + k*pi
ans = 6×1
1.5707963267949 4.71238898038469 7.85398163397448 10.9955742875643 14.1371669411541 17.2787595947439
First find where the crossing happens.
cloc = find(diff(y >= 0));
So cloc tells us the index of those points.
[x(cloc),y(cloc),y(cloc+1)]
ans = 6×3
1.57079615707962 1.69715281001129e-07 -1.83028491911755e-06 4.71238847123885 -5.09145843003367e-07 1.49085435711576e-06 7.85398078539808 8.48576404117367e-07 -1.1514237951138e-06 10.9955730995573 -1.18800696611945e-06 8.11993233111705e-07 14.1371654137165 1.52743752812139e-06 -4.72562671109517e-07 17.2787577278758 -1.86686808834681e-06 1.33132109107275e-07
Can you see that we have identified a zero crossing in each case? And of course, we are already quite close to the true zero in each case.
plot(x,y,'b-',x(cloc),y(cloc),'rx')
grid on
Next, just use linear interpolation between each pair of points. You could be more sophisticated, perhaps using a higher order interpolant. But a linear interpolant is trivial to use and inplement, and at this fine of an interval, a linear interpolant will be quite accurate.
And, yes, a linear interpolant is trivial to write. But again, this is a MATLAB forum! This is the point-slope form of a line therough two points. Just use solve!
syms a b ya yb
Y = ya + (yb - ya)/(b-a)*(X-a)
Y = 
solve(Y == 0,X)
ans = 
Having now gotten MATLAB to do the thinking for me, we can now do a linear interpolation.
ya = y(cloc);yb = y(cloc+1);
xlinear = (x(cloc).*yb - x(cloc+1).*ya)./(yb - ya);
How well did we do?
[pi/2 + k*pi,xlinear]
ans = 6×2
1.5707963267949 1.5707963267949 4.71238898038469 4.71238898038469 7.85398163397448 7.85398163397448 10.9955742875643 10.9955742875643 14.1371669411541 14.1371669411541 17.2787595947439 17.2787595947439
And we soo that to the accuracy of double precision arithmetic, in each case, we have a perfect prediction, merely using linear interpolation.
In the end, the result took me about 3 lines of code to write. (If you exclude the places where i used solve to do work that was just playing around with MATLAB.)
  1 Comment
malik abdelli
malik abdelli on 20 Nov 2023
Thank you for the answer, and sorry if my question offended you, wasnt meant to do so

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!