Segmenting sinusoidal time-series data

I have some data that was collected by a mobile phone's gyroscope sensors. I would like to be able to chunk out one "repetition" of the motion. An example of a sample run is shown here (apparently the MathWorks image upload didn't work right): http://i.imgur.com/GuEgK2y.png
I would like to be able to determine how long a period is, and where they start (doesn't matter if the starting point is max or min amplitude or a center amplitude). I tried using xcorr, which resulted in a plot with some waves centered around 50, whereas manual inspection of the data shows a period of about 2000 between the first two peaks. What should I be looking into to figure out how to do this?

 採用された回答

Star Strider
Star Strider 2016 年 2 月 2 日

0 投票

Without your actual data, I can only guess at an approach. I would begin by detrending it (I used polyfit and polyval, there are several options), then use circshift to identify the zero-crossings, and from them the periods and frequencies:
t = 0:1.3E+4;
s = 60 + 5*exp(-5*t/1.3E+4) + sin(2*pi*t/3000); % Create Data
figure(1)
plot(t, s); % Original Data
p = polyfit(t, s, 3);
sd = s - polyval(p, t); % Detrend
xci = find(sd.*circshift(sd, [0 -1]) <= 0);
xci = xci(1:end-1); % Find Inices Of Zero-Crossings
figure(2)
plot(t, sd)
hold on
plot(t(xci), sd(xci), '+r')
hold off

4 件のコメント

Ben
Ben 2016 年 2 月 4 日
Hmm. When I plot sd vs t (using my data), I see that the data has been adjusted as expected and has zero-crossings, but xci is an empty array.
Could you explain a little more what you're doing with find and circshift? I don't understand why you're shifting the array.
Star Strider
Star Strider 2016 年 2 月 4 日
If ‘xci’ is empty, that means your data are a column rather than a row vector. (This is the problem of not having your original data to work with.) The first approach is to switch the argument vector in the circshift call:
xci = find(sd.*circshift(sd, [-1 0]) <= 0);
Try it now.
The circshift call shifts the vector (in this instance, see the documentation for details) one position to the left (or up) (-1), then multiplies it by the unshifted vector. This creates negative values only where zero-crossings occur. The find call then locates the indices of them. It is possible to extend this to include a loop with an interp1 call at each iteration (for coarsely-sampled data) to get more accurate zero-crossing estimates. I kept it simple here.
Ben
Ben 2016 年 2 月 4 日
Ok, switching which dimension was shifted worked, thank you.
Star Strider
Star Strider 2016 年 2 月 4 日
My pleasure.

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

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeTime Series についてさらに検索

製品

質問済み:

Ben
2016 年 2 月 2 日

コメント済み:

2016 年 2 月 4 日

Community Treasure Hunt

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

Start Hunting!

Translated by