FFTtest4

advertisement
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.
Download