开发者

Using Fourier Transform to get frequency and phase

开发者 https://www.devze.com 2023-03-19 05:20 出处:网络
Suppose I have samples of a periodic function, what is a good way to get frequency and phase information out of it?

Suppose I have samples of a periodic function, what is a good way to get frequency and phase information out of it?

In particular, I'd like to get a form like

a+b Cos[c x + d]

Here's a part of the sample

{255,255,255,249,64,0,0,0,0,0,0,0,0,0,0,0,0,233,255,255开发者_如何学Go,255,255,255,255,255,255,255,209,0,0,0,0,0,0,0,0,0,0,0,0,118,255,255,255,255,255,255,255,255,255,255,132,0,0,0,0,0,0,0,0,0,0,0,0,200,255,255,255,255,255,255,255,255,255,239,19,0,0,0,0,0,0,0,0,0,0,0,46,245,255,255,255,255,255,255,255,255,255,186,0}


Using Autocorrelation and FindFit[ ]

(*Your list*)
ListPlot@l

Using Fourier Transform to get frequency and phase

(*trim the list*)
l1 = Drop[l, (First@Position[l, 0])[[1]] - 1];
l2 = Drop[l1, Length@l1 - (Last@Position[l1, 0])[[1]] - 1];
(*autocorrelate*)
ListLinePlot@(ac = ListConvolve[l2, l2, {1, 1}])

Using Fourier Transform to get frequency and phase

(*Find Period by taking means of maxs and mins spacings*)
period = Mean@
   Join[
    Differences@(maxs = Table[If[ac[[i - 1]] < ac[[i]] > ac[[i + 1]], i, 
                               Sequence @@ {}], {i, 2, Length@ac - 1}]), 
    Differences@(mins = Table[If[ac[[i - 1]] > ac[[i]] < ac[[i + 1]], i, 
                               Sequence @@ {}], {i, 2, Length@ac - 1}])];

(*Show it*)
Show[ListLinePlot[(ac = ListConvolve[l2, l2, {1, 1}]), 
  Epilog -> 
   Inset[Framed[Style["Mean Period = " <> ToString@N@period, 20], 
     Background -> LightYellow]]], 
 Graphics[Join[{Arrowheads[{-.05, .05}]}, {Red}, 
   Sequence @@@ Arrow[{{{#[[1]], Min@ac}, {#[[2]], Min@ac}}}] & /@ 
    Partition[mins, 2, 1], {Blue}, 
   Sequence @@@ Arrow[{{{#[[1]], Max@ac}, {#[[2]], Max@ac}}}] & /@ 
    Partition[maxs, 2, 1]]]]

Using Fourier Transform to get frequency and phase

(*Now let's fit the Cos[ ] to find the phase*)
model = a + b Cos[x (2 Pi)/period + phase];
ff = FindFit[l, model, {a, b, phase}, x, 
             Method -> NMinimize, MaxIterations -> 100];

(*Show results*)
Show[ListPlot[l, PlotRange -> All, 
  Epilog -> 
   Inset[Framed[Style["Phase = " <> ToString@N@(phase /. ff), 20], 
     Background -> LightYellow]]], Plot[model /. ff, {x, 1, 100}]]

Using Fourier Transform to get frequency and phase


Please look at FourierDCT ref page.

Your data looks very much like SquareWave function. By manual inspection it seems like your data fit SquareWave[{0, 255}, (x + 5)/23 ].

Using Fourier Transform to get frequency and phase

0

精彩评论

暂无评论...
验证码 换一张
取 消