IDL 1D FFT tests Friday 03 Oct 03 PRO fft2dteste ; why are frequency peaks shifted from analytic w? IDL> n=100 IDL> j=findgen(n) IDL> dt=0.1 IDL> t=j*dt IDL> yt=sin(t)+ 2*sin(3*t) IDL> plot,t,yt, title='yt = sin(t) + 2 sin(3t) vs t' IDL> dx=0.2 IDL> x=j*dx IDL> yx=sin(2*x) IDL> plot,x,yx, title='yx=sin(2x) vs x' IDL> fw=FFT(yt,-1) IDL> plot, ABS(fw), title='ABS(fw)' IDL> fk=FFT(yx,-1) IDL> plot, ABS(fk),title='ABS(fk)' Expect one peak at 1, a bigger peak at 3 Fine, but frequencies are at about 1*pi and 3*pi. 1=dt*sqrt(n)=0.1*10 Expect one peak at 2 Fine, but frequency is at about 2*pi/2 2=dx*sqrt(n)=0.2*10 IDL> PRINT, 'Maximum value in array fw is:', MAX(fw, I) Maximum value in array fw is: 0.686987 IDL> PRINT, 'The location of the maximum value is', I The location of the maximum value is 10 IDL> semimax=max(fw[0:5],i) IDL> print,semimax,i 0.506744 3 Guess general relationship for 1D FFT: frequency spectrum peaks at (w*pi/m) where m= dx*sqrt(n) Check: first, find actual values of frequency peaks here, then plot some cases with n.ne.100 Increase resolution of the same case to see if the peaks at 1,3 are actually at pi, 3*pi. IDL> n=1000 IDL> j=findgen(n) IDL> dt=0.01 IDL> t=j*dt IDL> yt=sin(t)+ 2*sin(3*t) IDL> plot,t,yt, title='yt = sin(t) + 2 sin(3t) vs t' IDL> fw=FFT(yt,-1) IDL> plot, ABS(fw), title='ABS(fw)' Analytic peaks at w=1 and w=3 Guess FFT peaks will be at w’=(w*pi/m) where m= dt*sqrt(n) M=dt*sqrt(n)=0.01*31.6227766=0.316, so pi/m=0.9935 <10 Then peaks should be at about 10*pi =31.2 and 10*3*pi=93.6 WRONG: here is the IDL result – just the same as with lower resolution. INPUT OUTPUT ; Find location of highest peak Maximum value in array fw is: 0.683548 PRINT, 'Maximum value in array fw is:', MAX(fw, i) The location of the highest peak is 10 PRINT, 'The location of the highest peak is', i ; ; Find location of second-highest peak Value of peak between fw[0:5] is: 0.508961 ; (determined to lie between elements 0-5, in testd). The location of this lower peak is 3 semimax=max(fw[0:5],i) print,'Value of peak between fw[0:5] is:', semimax,i PRINT, 'The location of this lower peak is', i 3 NEW GUESS: Resolution and number of points is irrevelant. Frequencies are simply multiplied by Pi. TESTF: Try a different function and see how the frequencies shift. n=100 j=findgen(n) ; Construct a function varying in time, with higher resolution dt=0.2 t=j*dt yt=sin(2* t)+ 2*sin(4*t) Maximum value in array fw is: 0.883451 The location of the highest peak is 13 Value of peak between fw[0:10] is: 0.436424 The location of this lower peak is 6 6 2*pi = 6.28 ~ 6, and 4*pi = 12.6 ~ 13 New guess looks correct. Try one more case... TEST G PRO FFTtestG ; Try different frequencies and resolutions to find how ; spectral peaks compare to analytic frequencies, ; in general. n=200 j=findgen(n) dt=0.2 t=j*dt yt=sin(t) + 2*sin(2* t)+ 3*sin(3*t) Maximum value in array fw is: 1.48652 The location of the highest peak is 19 Value of peak between fw[0:10] is: The location of this lower peak is 0.437406 6 6 Analytic frequencies: 1, 2, 3 FFT peaks: 6, 13, 19 = 2 pi, 4 pi, 6 pi. So number of points matters after all. n=200 -> w’ = 2Pi*w. Two more tests: Check if w’=3Pi*w for n=300 and Redo n=200 for dt = 0.1 TestG1 = same as testG above, except dt = 0.1 instead of 0.2: PRO FFTtestG1 ; same as testG except dt = 0.1 instead of 0.2 n=200 j=findgen(n) dt=0.1 t=j*dt yt=sin(t) + 2*sin(2* t)+ 3*sin(3*t) Value and location of highest peak is: 1.08077 10 The location of the highest peak is 10 Value and location of peak between fw[0:8] is: 0.929409 Value and location of peak between fw[0:4] is: 0.622931 Analytic f=1, 2, 3 FFT peaks = 3, 6, 10 = 1*pi, 2*pi, 3*pi 6 3 TEST G3: Check if w’=3Pi*w for n=300 PRO FFTtestG3 ; same as testG2 except dt = 0.1 and n=300 instead of 200 n=300 j=findgen(n) dt=0.1 t=j*dt yt=sin(t) + 2*sin(2* t)+ 3*sin(3*t) Value and location of highest peak is: 1.22145 14 Value and location of peak between fw[0:10] is: 0.649463 Value and location of peak between fw[0:5] is: 0.391206 9 5 PRO FFTtestG3b ; same as testG3 except dt = 0.2 instead of 0.1 n=300 j=findgen(n) dt=0.2 t=j*dt yt=sin(t) + 2*sin(2* t)+ 3*sin(3*t) INPUT ; Find location of highest peak PRINT, 'Value and location of highest peak is:', MAX(fw, i), i ; ; Find location of second-highest peak n2=3*i/4 semimax=max(fw[0:n2],i2) print,'Value and location of peak between fw[0:',n2,'] is:', semimax,i2 ; ; Find location of third-highest peak n3=n2/2 semimax=max(fw[0:n3],i3) print,'Value and location of peak between fw[0:',n3,'] is:', semimax,i3 ; OUTPUT Value and location of highest peak is: 1.20775 29 Value and location of peak between fw[0: 0.982564 19 21] is: Value and location of peak between fw[0: 0.329043 9 10] is: