フィルターのクリア

finding zeroes of data

36 ビュー (過去 30 日間)
Luke Radcliff
Luke Radcliff 2016 年 7 月 28 日
編集済み: Pietro Innocenzi 2022 年 11 月 14 日
How do you find zeroes from data? I have two data sets, a for acceleration and t for time. I plotted acceleration with respect to time, and I want to find when the acceleration hits zero, so at what time. I know there is fzero, but that is mainly for functions and this is just a plot from data. Do I make the data into some sort of function or can I use the find function somehow?

採用された回答

Star Strider
Star Strider 2016 年 7 月 28 日
This is a routine I use to find as many zero-crossings in data as may exist. It interpolates or extrapolates from the points it identifies near the zero crossings to closely (linearly) approximate the actual zero crossings:
x = linspace(0,10*pi,1E+5); % Create Data
y = sin(10*pi*x.*cos(10*x).^2); % Create Data
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
dy = zci(y); % Indices of Approximate Zero-Crossings
for k1 = 1:size(dy,1)-1
b = [[1;1] [x(dy(k1)); x(dy(k1)+1)]]\[y(dy(k1)); y(dy(k1)+1)]; % Linear Fit Near Zero-Crossings
x0(k1) = -b(1)/b(2); % Interpolate ‘Exact’ Zero Crossing
mb(:,k1) = b; % Store Parameter Estimates (Optional)
end
It should work for your data without much, if any, modification. The zero-crossings are in the ‘x0’ vector.
  2 件のコメント
LRW
LRW 2020 年 12 月 21 日
Hi, Star Strider. I have found that your method works for finding the zeros of my data. However, I have 81 columns of data that I am trying to find the zeros for. I have added a for loop to go through each column that incorporates your code (see below). But, I'm not sure how to make it so the x0 values are stored through each iteration for the each column of data. I'm sure it is an easy fix. I am new to Matlab and would appreciate any help. Thanks!
for i=size(QF02num,2);
x = QF02num(:,1);
y = QF02num (:,i);
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
dy = zci(y); % Indices of Approximate Zero-Crossings
for k1 = 1:size(dy,1)-1
b = [[1;1] [x(dy(k1)); x(dy(k1)+1)]]\[y(dy(k1)); y(dy(k1)+1)]; % Linear Fit Near Zero-Crossings
x0(k1) = -b(1)/b(2); % Interpolate :Exact, Zero Crossing
mb(:,k1) = b; % Store Parameter Estimates (Optional)
end
end
Star Strider
Star Strider 2020 年 12 月 21 日
Lauren Williams —
It’s been a while ( years) since I wrote that, so I had to go back and remember what I was doing.
Updating it to calculate the zero-crossings of columns of a matrix:
xv = linspace(0, 5*pi, 250); % Create xv’
yv = 1:81; % Create ‘yv’
[X,Y] = ndgrid(xv, yv); % Create Independent Variable Matrix
Z = sin(10*X) .* cos(Y*2*pi*2/size(Y,2)); % Create Dependent Variable Matrix
zci = @(v) find(diff(sign(v))); % New Version Of ‘zci’
for k2 = 1:size(Z,2)
dy = zci(Z(:,k2)); % Iterate Through Columns
x = X(:,k2); % Column Independent Variable
y = Z(:,k2); % Column Dependent Variable
for k1 = 1:numel(dy)-1
b = [[1;1] [x(dy(k1)); x(dy(k1)+1)]]\[y(dy(k1)); y(dy(k1)+1)]; % Linear Fit Near Zero-Crossings
x0 = -b(1)/b(2); % Interpolate :Exact, Zero Crossing
mb(k1,k2) = x0; % Store Parameter Estimates (Optional)
end
end
figure
col = randi(size(Z,2));
plot(X(:,col), Z(:,col), '-b')
hold on
plot(mb(:,col), zeros(size(mb(:,col))), '.r')
hold off
grid
title('Be Sure It Works!')
The figure at the end is not necessary, however I wanted to be certain my code variation was working, so I plotted random columns.
Note that all columns have to have the same number of zero-crossings for this to work. If that is not the situation, create ‘mb’ as a cell array instead:
mb{k1,k2} = x0;
(note the curly brackets {} denoting cell array indexing) and then use the appropriate method to recover the numeric values from the cell array. See Access Data in Cell Array for guidance on that.
That should work with your matrix. A Vote would be appreciated if it does what you want!

サインインしてコメントする。

その他の回答 (2 件)

Walter Roberson
Walter Roberson 2016 年 7 月 28 日
accpos = acceleration>0;
goes_nonpos = strfind(accpos, [1 0]);
now goes_nonpos is the index of locations where the acceleration is positive and then is non-positive immediately after (which might be 0 exactly or might have passed through to negative)
Generally when you use this kind of strfind() trick, you need to pay careful attention to the edge conditions: what do you want to do if the acceleration starts zero?
Also this pattern does not locate places where the acceleration stays 0 (or non-positive), which might be of interest to you. It is common to be interested not just in when it goes from positive to zero (perhaps by passing through on the way to negative) but also when it ends that and goes positive again. You can do that with a pair of strfind() but to you need to be think about the boundary conditions and also about whether you want to use equalities or inequalities for the comparisons.
  2 件のコメント
Luke Radcliff
Luke Radcliff 2016 年 7 月 28 日
ohh okay, now how to I find the time stamp at these indexes?
Walter Roberson
Walter Roberson 2016 年 7 月 28 日
YourTimeStamps(goes_nonpos)

サインインしてコメントする。


Pietro Innocenzi
Pietro Innocenzi 2022 年 11 月 14 日
編集済み: Pietro Innocenzi 2022 年 11 月 14 日
If you consider the absolute value of your signal, the minimum will be at zero. Now consider the opposite of the absolute value: the maxima will be your zeros. So you need to find the peaks of the opposite of the absolute value of your signal.
In one line:
[zeros, ind_zeros] = findpeaks(-abs(acceleration));

カテゴリ

Help Center および File ExchangeInterpolation についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by