FFT tests Wed.8. Oct.03 (fftest4.pro) For a timeseries y(t) constructed of analytic functions of win, call its FFT Y(wout), which has peaks at values wout. If y(t) ~ sin(cw 2*t/(n*dt)) = sin(wint), then output peaks wout = win. If y(t) ~ sin(cw t)) = sin(wint), then output peaks wout = win n*dt/(), and we can recover the original input frequencies from win=wout 2/(n*dt) PRO fftest4 ; See FFTtest4.doc and green notebook p.28 ff, Wed.8.Oct.03 ; Recover input frequencies win from output peaks wout ; For y ~ sin (cw t), I think win = cw= wout 2 pi /(n dt) print,'Enter a power of 2 and a time interval, separated by commas:' read,p,dt n=2^p j=findgen(n) t=j*dt ;tt = period of fundamental tt=n*dt w=2*!PI/tt print,'Number of points=',n,', period=',tt,', w=',w print,'Enter three frequency factors:' read,c1, c2, c3 print,'Enter three amplitudes, from lowest to highest:' read,A1, A2, A3 yt= A1*sin(c1*t) + A2*sin(c2*t) + A3*sin(c3*t) ; Find the frequency spectrum fw=ABS(FFT(yt,-1)) ; Plot emf files, which can be pasted into word.doc set_plot, 'metafile' device, filename='plotyt.emf' plot,t,yt, title='yt = A1 sin(c1*t) + A2 sin(c2*t)+ A3*sin(c3*t)' device, /close device, filename='plotfw.emf' plot,fw, title='fw=|FFT(yt)|' device, /close ; Find location of highest peak PRINT, 'Amp and freq of highest FT peak is:', MAX(fw, i3), i3 ; Find location of middle peak semimax=max(fw[0:i3-1],i2) print,'Amp and freq of peak between fw[0:',i3-1,'] is:', semimax,i2 ; Find location of lowest peak semimax=max(fw[0:i2-1],i1) print,'Amp and freq of peak between fw[0:',i2-1,'] is:', semimax,i1 ; Recover input frequency (factors) from FT peaks: ; win=wout*2*!PI/(n*dt) m=2*!PI/(n*dt) w1=m*i1 w2=m*i2 w3=m*i3 Print,'Transformed output peaks', i1, i2, i3 print,' Calculated frequencies ', w1, w2, w3 print,' Original input freqs ', c1, c2, c3 END _________ IDL> fftest4 Enter a power of 2 and a time interval, separated by commas: : 5, .1 Number of points= 32.0000, period= 3.20000, w= 1.96350 Enter three frequency factors: : 1, 4, 6 Enter three amplitudes, from lowest to highest: : 1, 2, 3 Amp and freq of highest FT peak is: 1.43235 3 Amp and freq of peak between fw[0: 2] is: 1.05184 2 Amp and freq of peak between fw[0: 1] is: 0.614930 0 Transformed output peaks 0 2 3 Calculated frequencies 0.000000 3.92699 5.89049 Original input freqs 1.00000 4.00000 6.00000 This missed the lowest peak, because it can only pick out integers and w1 is less than 1. That’s ok. Run a few more tests… IDL> fftest4 Enter a power of 2 and a time interval, separated by commas: : 5, .2 Number of points= 32.0000, period= 6.40000, w= 0.981748 Enter three frequency factors: : 3, 5, 7 Enter three amplitudes, from lowest to highest: : 1, 2, 3 Amp and freq of highest FT peak is: 1.37615 7 Amp and freq of peak between fw[0: 6] is: 1.03020 5 Amp and freq of peak between fw[0: 4] is: 0.551626 3 Transformed output peaks 3 5 7 Calculated frequencies 2.94524 4.90874 6.87223 Original input freqs 3.00000 5.00000 7.00000 CORRECT DL> fftest4 Enter a power of 2 and a time interval, separated by commas: : 6, .3 Number of points= 64.0000, period= 19.2000, w= 0.327249 Enter three frequency factors: : 5, 10, 14 Enter three amplitudes, from lowest to highest: : 1, 2, 3 Amp and freq of highest FT peak is: 1.39538 21 Amp and freq of peak between fw[0: 20] is: 0.409125 15 Amp and freq of peak between fw[0: 14] is: 0.0778750 14 Transformed output peaks 14 15 21 Calculated frequencies 4.58149 4.90874 6.87223 Original input freqs 5.00000 10.0000 14.0000 Well, w1=4.6 ~ c1=5, but w2 and w3 are half what they should be. Why? Not enough points? Try increasing p: Increase p from 5 to 6, but frequencies are still wrong, because last peak is too close to Nyquist limit. IDL> fftest4 Enter a power of 2 and a time interval, separated by commas: : 7, .3 Number of points= 128.000, period= 38.4000, w= 0.163625 Enter three frequency factors: : 5, 10, 14 Enter three amplitudes, from lowest to highest: : 1, 2, 3 Amp and freq of highest FT peak is: 1.07350 42 Amp and freq of peak between fw[0: 41] is: 0.388264 31 Amp and freq of peak between fw[0: 30] is: 0.249579 30 Transformed output peaks 30 31 42 Calculated frequencies 4.90874 5.07236 6.87223 Original input freqs 5.00000 10.0000 14.0000 Decrease dt and see if that helps: IDL> fftest4 Enter a power of 2 and a time interval, separated by commas: : 7, .1 Number of points= 128.000, period= 12.8000, w= 0.490874 Enter three frequency factors: : 5, 10, 14 Enter three amplitudes, from lowest to highest: : 1, 2, 3 Amp and freq of highest FT peak is: 1.02837 29 Amp and freq of peak between fw[0: 28] is: 0.877537 28 Amp and freq of peak between fw[0: 27] is: 0.831137 20 Transformed output peaks 20 28 29 Calculated frequencies 9.81748 13.7445 14.2353 Original input freqs 5.00000 10.0000 14.0000 The problem is that the wrong peaks are found, this time. With small resolution, fftest4 doesn’t step back far enough to find next smallest peak. DONE: Method to recover input frequencies from output peaks WORKS! DO: Need a better peak-finding algorithm, and some safeguards against these possible problems: highest frequency too close to Nyquist limit resolution not fine enough to distinguish between peaks resolution too fine, so peak-finder steps back onto shoulder of current peak Actually, while those problems can affect my tests, there is no way to guard against them in the data, since I don’t analytically pre-determine the input waveform in the data.