I have a little utility function that I wrote for just that purpose:
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
Because it can produce a false zero-crossing at the end of the vector, it may be necessary to discard the last index it returns.
To find the ‘exact’ zero-crossings from the indices it returns, a for loop and interp1 is the easiest way.
Example:
idx_vct = zci(your_y_data);
for k1 = 1:length(idx_vct)
idx_rng = (idx_vct(k1)-1:idx_vct(k1)+1);
x_zero(k1) = interp1(y(idx_rng), x(idx_rng), 0);
end
Note — This is UNTESTED CODE. It should work, but may require modification. Be certain that ‘idx_vct(k1)-1’ and ‘idx_vct(k1)+1’ do not over-write the vector.