1C -------------------------------------------------------------------------
2C | File name: fft.for Sean O'Connor 9-23-87 |
3C -------------------------------------------------------------------------
4
5C -------------------------------------------------------------------------
6C | VAX 11/785 VMS 4.5 VAX EXTENDED FORTRAN 77 |
7C -------------------------------------------------------------------------
8
9C
10C ****************************************************************************
11C * *
12C * FFT *
13C * *
14C ****************************************************************************
15C
16C
17C DESCRIPTION
18C
19C This program does an in-place one dimensional complex discrete Fourier
20C transform. It uses an FFT algorithm for a number of input points which
21C is a power of two.
22C
23C
24C INPUT
25C
26C N, The number of complex points to be transformed.
27C N is a power of 2. N must be at least 2; it
28C must not exceed the dimension of array X, or the
29C maximum size of the sine and cosine table. (See
30C below).
31C
32C X, The array holding the complex data X( k )
33C for k = 0, 1, . . ., N - 1 which is to be
34C transformed. It is dimensioned in the calling
35C program. Only the array address is passed to
36C this subroutine.
37C
38C D, The direction of the FFT. D is 1 for a
39C forward transform and -1 for an inverse
40C transform.
41C
42C
43C OUTPUT
44C
45C X, On output, X holds the complex Fourier coefficients
46C ^
47C X( k ) for k = 0, 1, . . ., N - 1.
48C
49C Warning messages to the terminal under these conditions:
50C
51C (1) D is not 1 or -1
52C (2) N is less than 2.
53C (3) N is greater than the sine table can handle.
54C (4) N is not a power of 2.
55C
56C
57C CALLING SEQUENCE
58C
59C CALL FFT ( N, X, D )
60C
61C
62C EXAMPLE
63C
64C DIMENSION X( 0 : 3 ) ! 4 point FFT
65C
66C N = 4 ! 4 point FFT
67C D = 1 ! Forward transform
68C
69C CALL FFT( N, X, D ) ! Do the FFT
70C
71C D = -1 ! Do an inverse FFT
72C
73C CALL FFT( N, X, D )
74C
75C Suppose X contains the data
76C
77C X ( 0 ) = 1 + i
78C X ( 1 ) = 2 + 2 i
79C X ( 2 ) = 3 + 3 i
80C X ( 3 ) = 4 + 4 i
81C
82C then the forward FFT returns
83C
84C X ( 0 ) = 5 + 5 i
85C X ( 1 ) = -2
86C X ( 2 ) = -1 - i
87C X ( 3 ) = - 2 i
88C
89C and the inverse FFT returns the original data.
90C
91C
92C METHOD
93C ^
94C The Fourier coefficients X( k ) are defined for k = 0, . . ., N - 1
95C by the formula
96C
97C N - 1 2 Pi i
98C ^ 1 ____ - ------ j k
99C X( k ) = --------- \ N
100C ----- / X( j ) e
101C \ / N ----
102C v j = 0
103C
104C where e is 2.1718 . . ., Pi = 3.14159. . . and i is the square root
105C of -1.
106C
107C This is the formula for the forward transform. The inverse transform
108C is the same, except that the minus sign in the exponent above is a
109C plus sign instead.
110C ---
111C The normalizing factor 1 / \/ N in front was picked so that the
112C forward and inverse transforms look the same.
113C
114C
115C The particular type of FFT algorithm we use is a
116C
117C complex,
118C two to the N,
119C decimation in frequency,
120C input in order, output bit reversed
121C
122C type of FFT. It is described in the book
123C
124C THE FAST FOURIER TRANSFORM,
125C F. Oran Brigham, Prentice Hall, 1974
126C
127C
128C BUGS
129C
130C The bit-reversal routine could be made faster by using the
131C VAX FORTRAN 77 library routines for testing, setting, clearing and
132C shifting bits: BTEST, IBSET, IBCLR, ISHFT.
133C
134C You might want to use double precision complex numbers to get more
135C accuracy.
136C
137C ****************************************************************************
138C * *
139C ****************************************************************************
140
141
142 SUBROUTINE FFT( N, X, D )
143
144 IMPLICIT NONE ! Force declaration of all variables.
145
146
147C -------------------------------------------------------------------------
148C | MACRO DEFINITIONS |
149C -------------------------------------------------------------------------
150
151 INTEGER MAX_TABLE_SIZE
152 REAL PI
153
154 PARAMETER ( PI = 3.1415926535897932385 )
155
156C We must set the size of the sine and cosine table used in the FFT.
157C The table is called starting_multiplier.
158C
159C Suppose MAX is the largest FFT we would ever want
160C to perform. Then
161C
162C MAX_TABLE_SIZE = LOG ( MAX ) - 1
163C 2
164C
165C is the size of the table. This table can be used by the
166C FFT for any number of points from 2 up to MAX.
167C
168C For example, if MAX_TABLE_SIZE = 14, then we can transform
169C anywhere from 2 to 2 ** 15 = 32,768 points, using the same
170C sine and cosine table.
171C
172
173 PARAMETER ( MAX_TABLE_SIZE = 20 )
174
175
176C -------------------------------------------------------------------------
177C | CALLING ARGUMENTS |
178C -------------------------------------------------------------------------
179
180 INTEGER N ! Number of points in transform
181
182 COMPLEX X( 0 : * ) ! Complex data to be transformed
183
184C Array X is dimensioned in the calling program. Only its starting
185C address is passed into this subroutine.
186
187 INTEGER D ! Transform direction: 1 for a forward
188 ! transform, -1 for an inverse transform.
189
190
191C -------------------------------------------------------------------------
192C | LOCAL VARIABLES |
193C -------------------------------------------------------------------------
194
195C A column refers to a column of the FFT signal flow graph. A group is
196C a collection of butterflies which have the same multiplier W^p. A
197C butterfly is the basic computational unit of the FFT.
198
199 INTEGER log_of_n, ! Log base 2 of the number of points, N.
200 $ column, ! Current column.
201 $ number_of_groups, ! Number of groups in a column.
202 $ group, ! Current group number.
203 $ start_of_group, ! Array index of first butterfly in group.
204 $ end_of_group, ! Array index of last butterfly in group.
205 $ butterfly_height, ! Height of a butterfly.
206 $ offset, ! Lower branch of a butterfly.
207 $ i, ! Loop counter. Upper branch of butterfly.
208 $ rev_i, ! Bit-reversed array index i.
209 $ REVERSE_BITS ! Bit reversal function.
210
211
212 COMPLEX product, ! Temporary storage in a butterfly calculation.
213 $ temp, ! Same as above.
214 $ increment, ! Difference between current multiplier and next.
215 $ multiplier ! The multiplier W^p for a group of butterflies.
216
217 COMPLEX starting_multiplier( 0 : MAX_TABLE_SIZE ) ! Table of sines
218 ! and cosines.
219
220 REAL normalizer, ! 1/\/N normalizing factor.
221 $ angle ! Current angle in sine and cosine table.
222
223
224 LOGICAL called_already ! .TRUE. if this is the second call or
225 ! later call to this subroutine.
226
227
228C -------------------------------------------------------------------------
229C | SUBROUTINE CODE |
230C -------------------------------------------------------------------------
231
232C
233C Initialize the variable called_already to .FALSE. at compile time.
234C Change it to .TRUE. after the first call to this subroutine.
235C Save the value so it does not get destroyed after returning from
236C this subroutine.
237C
238 SAVE called_already
239 DATA called_already /.FALSE./
240
241
242C
243C Compute log base 2 of N. Perturb slightly to avoid roundoff error.
244C For example, INT( 4.99999999999 ) = 4 (wrong!), but
245C INT( 4.999999999 + .01 ) = 5 (correct!)
246C
247 log_of_n = INT( ALOG( FLOAT( N ) ) / ( ALOG( 2.0 ) ) + .01 )
248
249
250
251C
252C Error checking. Print a message to the terminal if any one of these
253C conditions is true:
254C
255C (1) D is not 1 or -1.
256C (2) N < 2.
257C (3) log2( N ) > MAX_TABLE_SIZE + 1.
258C (4) N is not a power of 2.
259C
260
261 IF ((D .NE. 1) .AND. (D .NE. -1)) THEN
262
263 PRINT *, ' ERROR --- D is not 1 or -1'
264 RETURN
265
266 ELSE IF (N .LT. 2) THEN
267
268 PRINT *, ' ERROR --- N is less than 2. '
269 RETURN
270
271 ELSE IF ( (log_of_n - 1) .GT. MAX_TABLE_SIZE) THEN
272
273 PRINT *, ' ERROR --- N is larger than the sine table can'
274 PRINT *, ' handle. Increase the parameter MAX_TABLE_SIZE'
275 PRINT *, ' in this subroutine and recompile.'
276
277 RETURN
278
279 ELSE IF ( (2 ** log_of_n) .NE. N ) THEN
280
281 PRINT *, ' ERROR --- N is not a power of 2.'
282 RETURN
283
284 END IF
285
286
287C
288C If called_already is false, generate the sine and cosine table for
289C the first time, then set called_already to .TRUE. Now later calls to
290C the subroutine don't recreate the sine and cosine table.
291C
292
293 IF (.NOT. called_already) THEN
294
295 DO i = 0, MAX_TABLE_SIZE - 1
296
297 angle = - PI / ( 2 ** i )
298 starting_multiplier( i ) = CEXP( CMPLX(0.0 , angle) )
299
300 END DO
301
302 called_already = .TRUE.
303
304 END IF
305
306
307
308C
309C Compute the FFT according to its signal flow graph with
310C computations arranged into butterflies, groups of butterflies
311C with the same multiplier, and columns.
312C
313 butterfly_height = N / 2
314 number_of_groups = 1
315
316
317 DO column = 1, log_of_n
318
319 multiplier = starting_multiplier( column - 1 )
320
321C
322C Modify starting multiplier W^p when computing the inverse transform.
323C
324 IF ( D .EQ. -1 ) THEN
325
326 multiplier = CONJG( multiplier )
327
328 END IF
329
330 increment = multiplier
331
332
333C
334C Compute the first group.
335C
336 DO i = 0, butterfly_height - 1
337
338 offset = i + butterfly_height
339
340 temp = X( i ) + X( offset )
341 X( offset ) = X( i ) - X( offset )
342 X( i ) = temp
343
344 END DO ! i
345
346
347C
348C Now do the remaining groups.
349C
350 DO group = 2, number_of_groups
351
352 start_of_group = REVERSE_BITS( group - 1, log_of_n )
353 end_of_group = start_of_group +
354 $ butterfly_height - 1
355
356
357C Compute all butterflies in a group.
358
359 DO i = start_of_group, end_of_group
360
361 offset = i + butterfly_height
362 product = x( offset ) * multiplier
363
364 temp = X( i ) + product
365 X( offset ) = X( i ) - product
366 X( i ) = temp
367
368 END DO ! i
369
370 multiplier = multiplier * increment
371
372 END DO ! group
373
374 butterfly_height = butterfly_height / 2
375 number_of_groups = number_of_groups * 2
376
377 END DO ! column
378
379
380C
381C Normalize the results and permute them into order, two at a time.
382C
383 normalizer = 1 / SQRT( FLOAT( N ) )
384
385
386 DO i = 0, N - 1
387
388 rev_i = REVERSE_BITS( i, log_of_n )
389
390 IF ( rev_i .GT. i ) THEN ! exchange not yet done.
391
392 temp = X( i )
393 X( i ) = X( rev_i ) * normalizer
394 X( rev_i ) = temp * normalizer
395
396 ELSE IF ( rev_i .EQ. i ) THEN ! exchange with itself.
397
398 X( i ) = X( i ) * normalizer
399
400 END IF
401
402 END DO ! i
403
404
405 RETURN
406 END ! subroutine FFT
407
408
409
410C ****************************************************************************
411C * *
412C * REVERSE_BITS *
413C * *
414C ****************************************************************************
415C
416C DESCRIPTION
417C
418C This function reverses the order of the bits in a number.
419C
420C
421C INPUT
422C
423C n The number whose bits are to be reversed.
424C
425C num_bits The number of bits in N, counting leading zeros.
426C
427C
428C OUTPUT
429C
430C REVERSE_BITS The number N with all its num_bits bits reversed.
431C
432C
433C EXAMPLE
434C
435C REVERSE_BITS( (10) , 2 ) = (01) = 1, but
436C 2 2
437C
438C REVERSE_BITS( (10) , 3 ) = REVERSE_BITS( (010) , 3 ) = (010) = (10)
439C 2 2 2 2
440C
441C = 10
442C
443C
444C METHOD
445C
446C The algorithm works by a method similar to base conversion.
447C As the low order bits are broken off, one by one, they are
448C multiplied by 2 and accumulated to generate the bit-reversed
449C number.
450C
451C
452C BUGS
453C
454C The bit-reversal routine could be made faster by using the
455C VAX FORTRAN 77 library routines for testing, setting, clearing and
456C shifting bits: BTEST, IBSET, IBCLR, ISHFT.
457C
458C
459C ****************************************************************************
460C * *
461C ****************************************************************************
462
463 INTEGER FUNCTION REVERSE_BITS( n, num_bits )
464
465 IMPLICIT NONE
466
467
468C -------------------------------------------------------------------------
469C | CALLING ARGUMENTS |
470C -------------------------------------------------------------------------
471
472 INTEGER n, num_bits
473
474
475C -------------------------------------------------------------------------
476C | LOCAL VARIABLES |
477C -------------------------------------------------------------------------
478
479 INTEGER bit_num, ! Current bit number.
480 $ remainder, ! Bits remaining to be reversed.
481 $ reversed_n, ! Bit-reversed value of n.
482 $ bit, ! The current least significant bit.
483 $ MOD, INT ! Function return types.
484
485
486C -------------------------------------------------------------------------
487C | SUBROUTINE CODE |
488C -------------------------------------------------------------------------
489
490 remainder = n ! Load n.
491 reversed_n = 0 ! Clear buffer for bit-reversed n.
492
493 DO bit_num = 1, num_bits
494
495 bit = MOD( remainder, 2 ) ! Next least significant bit.
496 reversed_n = bit + 2 * reversed_n ! Shift left and add to buffer.
497 remainder = INT( remainder / 2 ) ! Remaining bits.
498
499 END DO
500
501 REVERSE_BITS = reversed_n
502
503 RETURN
504 END ! subroutine REVERSE_BITS