home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 326.lha / KFFT_v1.1 / fft.doc.pp / fft.doc
Text File  |  1990-01-03  |  17KB  |  405 lines

  1.  
  2. KFFT.DOC               KFFT version 1.1               Jerry Kallaus
  3.                          14 Feb 1989
  4.  
  5. KFFT V1.1 (C)Copyright 1989, Jerry Kallaus.  All rights reserved. 
  6. May be freely redistributed for non-commercial use (FREEWARE).
  7.  
  8.    Jerry Kallaus
  9.    993-D Mangrove
  10.    Sunnyvale, Ca  94086
  11.  
  12. Feedback welcome.
  13.  
  14. ---------------------------------------------------------------------
  15.  
  16. KFFT -- Fast Fourier Transform
  17.  
  18.         CONTENTS
  19.  
  20. 1.      Introduction
  21. 2.      Files
  22. 3.      Words
  23. 4.      Stack Diagrams
  24. 5.      Conditional Compile Controls
  25. 6.      Run Time Controls and Global Variables
  26. 7.      Data Representation
  27. 8.      Performance
  28. 9.      Future Versions
  29. 10.     Miscellaneous
  30.  
  31.  
  32.  
  33.  
  34. 1.  INTRODUCTION
  35.  
  36. The following documents a Fast Fourier Transform (FFT) program
  37. which is written in JForth* for Commodore Amiga computers.  A
  38. common computationally intensive bottleneck in a wide variety of
  39. digital signal processing (DSP) applications is the transformation
  40. of data back and forth between the time and frequency domain using
  41. the FFT.  The original motivation for writing this program was to
  42. satisfy my curiosity as to how fast an FFT could be performed on a
  43. stock Commodore Amiga computer with a 7.14 MHz Motorola 68000
  44. microproccesor.  Another motivating factor was the idea that a
  45. good FFT program is probably the most massively useful thing to
  46. have lying around when doing DSP applications. 
  47.  
  48. One set of source code is used which conditionally compiles
  49. variations of the same basic algorithm, namely a radix-2
  50. Cooley-Tukey FFT.  A choice had to be made as to whether to have
  51. one set of source code cluttered with conditional compilation
  52. statements, or to maintain umpty-dozen sets of source code.  The
  53. former was chosen.  Some of the FFT variations achieve a speed
  54. which is probably within about twenty percent of what could
  55. ultimately be achieved by implementing the features described in
  56. the section on future versions.  Currently, times as good as 0.54
  57. seconds for a 1024 point complex fixed-point FFT, and 6.5 seconds
  58. for a 1024 point floating-point FFT have been achieved.  (see
  59. section on Performance). 
  60.  
  61. While JForth does a good job of supporting Forth standards, some
  62. "features" of JForth may have been used which may or may not make
  63. this code difficult to port to other Forths. 
  64.  
  65. The current FFT version works with JForth version 2.0 and 1.2.
  66. As part of cleaning up some of the clutter in future FFT versions,
  67. support for JForth v1.2 will probably be dropped altogether. 
  68.  
  69. The first few sections of this document consists of rather terse
  70. reference material, with more elaboration given in later sections. 
  71.  
  72.  
  73. * JForth is a product of 
  74.  
  75.    Delta Research
  76.    P.O. Box 1051
  77.    San Rafael, Ca 94915
  78.  
  79.  
  80.  
  81.  
  82. 2.  FILES
  83.  
  84.  
  85. The file KFFT1.ZOO contains the following files:
  86.  
  87. fft.doc      this file
  88. cmplx.doc    documentation for complex arithmetic support words
  89. fftasm.doc   documentation for assembly language support words
  90. fftinc       INCLUDEs for compile
  91. fftcontrols  Conditional compilation controls
  92. fft1         Forth FFT code for complex data
  93. fftrc        Forth FFT code for real data
  94. fftmisc      Forth miscellaneous support words
  95. cmplx        Complex arithmetic and data type Forth words
  96. fft.asm      FFT assembler support words
  97. wtable       cosine, sine table for FFT
  98. makewtable   utility for making wtable
  99. testfft      simple test code for fft
  100. fft1.for     Fortran source which concisely depicts algorithm.
  101.  
  102.  
  103.  
  104.  
  105. 3.  WORDS
  106.  
  107.  
  108. FFT               fft - complex data in, complex data out
  109. FFTRC             fft - real data in, complex data out
  110. IFFT              inverse fft - complex data in, complex data out
  111. IFFTCR            inverse fft - complex data in, real data out
  112. CHECK.INPUTS.FFT  sanity check of fft arguments
  113. BIT.REVERSAL      performs bit reversal reordering operation
  114. INIT.MAP.FFT      makes bit reversal map for quick-reversal
  115. QUICK.REVERSAL    internal faster bit reversal, used with init.map.fft
  116.  
  117. See also cmplx.doc and fftasm.doc
  118.  
  119.  
  120.  
  121. 4.  STACK DIAGRAMS
  122.  
  123. FFT               ( data-address  log2-fft-size  -- )
  124. FFTRC             ( data-address  log2-fft-size  -- )
  125. IFFT              ( data-address  log2-fft-size  -- )
  126. IFFTCR            ( data-address  log2-fft-size -- )
  127. CHECK.INPUTS.FFT  ( data-address  log2-fft-size -- )
  128. BIT.REVERSAL      ( data-address log2-fft-size  -- )
  129. INIT.MAP.FFT      ( reversal-map-address  log2-fft-size  -- )
  130. QUICK.REVERSAL    ( data-address  reversal-map-address -- )
  131.  
  132. Note that for FFTRC and IFFTCR, the argument log2-fft-size
  133. represents the number of data points in the real array.  Also, for
  134. 2N real data points, FFTRC computes a transform with N+1 real
  135. numbers, and N-1 imaginary numbers.  The first and Nth imaginary
  136. parts are zero; rather than working with odd ball array sizes,
  137. FFTRC puts the N+1 real part in the imaginary part of the first
  138. complex number of the transform.  Likewise, IFFTCR expects to find
  139. it there. 
  140.  
  141.  
  142. See also cmplx.doc and fftasm.doc
  143. For example usage, see file testfft; words tfftrc and tifftcr.
  144.  
  145.  
  146. 5.  FFT CONDITIONAL COMPILE CONTROLS
  147.  
  148.  
  149. The file fftcontrols contains the following flags which control
  150. the conditional compilation (* indicates default):
  151.  
  152. FLOAT_FFT?        true  => version for floating point data
  153.                 * false => version for fixed point data
  154. W_TABLE_FFT?    * true  => use table for cosine, sine values
  155.                   false => compute cosine, sine values as needed
  156. ASM_FFT?        * true  => use assembler code for some basic operations
  157.                   false => use JForth code for everything
  158. INNER_ASM_FFT?  * true  => use assembler code for inner loop of FFT
  159.                   false => don't use assembler for inner loop of FFT
  160. AUTO_SCALE_FFT? * true  => fixed pt version using block floating point
  161.                   falue => no auto scaling
  162.  
  163. Certain combinations of flags are not supported and logic is present
  164. which precludes those combinations.  Specifically,
  165.  
  166. if FLOAT-FFT? is false, then W_TABLE_FFT? will be forced to true
  167. if FLOAT-FFT? is true,  then INNER_ASM_FFT? will be forced to false
  168. if FLOAT-FFT? is true,  then AUTO_SCALE_FFT? will be forced to false
  169.  
  170. In other words, for a fixed point version, table trig values must
  171. be used; and there is no assembler code for the inner-loop or the
  172. auto-scale feature for the floating version.  The logic which
  173. forces the above flag conditions is provided primarily as a
  174. convenience which allows switching from a fixed-point version to a
  175. floating-point version or vice versa by simply changing FLOAT_FFT?
  176. and not bothering with the other flags. 
  177.  
  178.  
  179.  
  180. 6.  RUN TIME CONTROLS AND GLOBAL VARIABLES
  181.  
  182.  
  183. The following global variables provide run time controls and fft
  184. output scaling control and information.  Use of any of these is
  185. optional, and except for REVERSAL-FFT, all are applicable only to
  186. fixed-point versions. 
  187.  
  188.  
  189. REVERSAL-FFT    addr => pre-formed reversal map address
  190. EVENS-FFT       true => divide by 2 on even fft stages
  191. ODDS-FFT        true => divide by 2 on odd  fft stages
  192. INSHIFT-FFT     value specifying right shift of input to first stage
  193. OUTBITS-FFT     value specifying number of significant output bits
  194. SHIFTS-FFT      value returned specifying number of shifts done on data
  195. BLK-EXP-FFT     adjusted block floating point exponent
  196.  
  197. Explanation:
  198.  
  199. Part of the FFT computation involves reordering the data by a
  200. process called bit-reversal, so called because pairs of elements
  201. are exchanged whose indices are the bit-reversal of each other. 
  202. The FFT algorithms provided here will by default perform this
  203. bit-reversal logic each time an FFT is computed using a word named
  204. BIT.REVERSAL.  However, the word INIT.MAP.FFT may optionally be
  205. used to eliminate most of this.  As an example, suppose the user
  206. wishes to compute many 1024 point FFT's, then the following code
  207. could be used,
  208.  
  209. 512 ZARRAY mymap           ( note only need half as many elements )
  210. 0 mymap  10 INIT.MAP.FFT   ( 2**10 = 1024, 0 mymap is mymap begin addr )
  211.  
  212. The word INIT.MAP.FFT will compute and store into mymap a
  213. bit-reversal map consisting of index swap pairs and a zero
  214. terminator at the end of the list.  A little less than the 512
  215. elements are actually used.  The address of mymap is stored in the
  216. global variable REVERSAL-FFT.  Later, when the FFT algorithms are
  217. used, the non-zero value in REVERSAL-FFT will indicate that a
  218. bit-reversal map exists and where it is located; and instead of
  219. using the normal BIT.REVERSAL word, a word named QUICK.REVERSAL
  220. will be used.  The FFT of any data set of the same size may be
  221. taken using the same map and the user simply uses the FFT
  222. algorithms as normal.  If different sizes of FFT's are desired,
  223. simply use INIT.MAP.FFT for each FFT size, providing a different
  224. array for each size.  Only now, just before each use of the FFT
  225. algorthms, stuff the appropriate map array address into the
  226. variable REVERSAL-FFT. 
  227.  
  228. The following applies to the scaling of output data from the
  229. various FFT algorithms.  For floating FFT's, scaling the output is
  230. left to the user.  For fixed-point non-auto-scaled FFT's, the
  231. scaling of the output data is left to the user, but the use of the
  232. variables INSHIFT-FFT, EVENS-FFT, and ODDS-FFT will affect the
  233. scaling.  For auto-scaled FFT's, the code uses a block floating
  234. point concept to maintain maximum accuracy without overflows
  235. throughout the computation.  For auto-scaled FFT's, the variables
  236. INSHIFT-FFT, SHIFTS-FFT, BLK-EXP-FFT, and OUTBITS-FFT are used to
  237. control and inform the user of the the scaling of the output data. 
  238. Also, a number of independent functions are provided for
  239. determining and changing the scaling of arrays of fixed point
  240. data. 
  241.  
  242. The casual reader may wish to skip to the last paragraph of this
  243. section, as the following tends to go on ad nauseum about scaling
  244. considerations when doing fixed point fft's. 
  245.  
  246. A radix-2 fft computes the FFT in log2 n stages; for example, a
  247. 1024 point FFT takes 10 stages.  The root mean square magnitude of
  248. the complex elements of the FFT increase by the square root of two
  249. on each stage, and specific elements may double (note that the RMS
  250. value doubles for every two stages).  This isn't really a problem
  251. with a floating point FFT; however, for a fixed point FFT, this
  252. can create arithmetic overflow problems. 
  253.  
  254. For a FFT fixed point version which does NOT use auto-scale, the
  255. following is applicable.  The flags EVENS-FFT and ODDS-FFT can be
  256. set to scale-down (shift) the data by a factor of two on even or
  257. odd stages or both.  For this purpose, the stages are counted zero
  258. through M-1, where M is the number of stages.  The scale-down
  259. occurs on the input of the stage.  The default is for scale-down
  260. on odd stages.  When taking forward or inverse FFT's, if it is
  261. known or suspected that the data is impulsive in nature in the
  262. domain being transformed to, scale-down on both even and odd
  263. stages should probably be used to avoid arithmetic overflows. 
  264.  
  265. Unfortunately, when taking large fft's, the preceding capability
  266. has serious shortcomings.  If a shift is done on every stage,
  267. compete loss of significance can occur.  If a shift is done on
  268. every other stage, overflows can occur.  Both situations are
  269. unacceptable.  The auto-scale feature now described addresses that
  270. problem. 
  271.  
  272. The basic operation done on each element on each stage is of the form
  273.  
  274. An+1(i) = An(i) + W * An(j),
  275.  
  276. where n refers to the old stage, n+1 refers to the new stage, i
  277. and j are array indices, and A and W are complex numbers.  W is
  278. the cosine and sine of some angle, and complex multiplication by W
  279. represents a rotation about the origin in the complex plane. 
  280. Assume that a fixed-point representation is used with an implied
  281. binary point such that the magnitude of each An is less than one,
  282. then the maximum magnitude of each An+1 will be less than two.  So
  283. it would be possible to compute the magnitude of each An+1, pick
  284. the maximum of these, and if it is greater than one, right shift
  285. all the data by one on input to the next stage, which would ensure
  286. that all values remain less than one.  Unfortunately, the
  287. additional multiplies, adds, compares, etc., required would nearly
  288. double the fft time. 
  289.  
  290. A much more efficient solution is as follows.  If the magnitude of
  291. each real and imaginary part of each An is limited to be less than
  292. one, then the maximum magnitude that the real or imaginary part of
  293. any An+1 can be is 1+sqrt(1+1), or approximately 2.414, and would
  294. occur when W corresponds to a 45 degree rotation.  The
  295. implementation of this is as follows.  The absolute value of the
  296. real and imaginary parts of all the An are bitwise logically OR'd
  297. together in a register.  If the resultant value is less than one,
  298. no shift is done on the input to the next stage.  If the value is
  299. between one and two, the next stage input is right shifted by one. 
  300. If the value is greater than two, the next stage input is right
  301. shifted by two.  This algorithm only adds about ten percent to the
  302. fft time. 
  303.  
  304. It should be mentioned here that on machines which have the same
  305. word length for everything, say 16-bits, the implementaion of this
  306. algorithm would lose one bit of significance relative to the
  307. algorithm which tracks the complex magnitudes.  This happens
  308. because the real and imaginary parts would have to be kept smaller
  309. than one-half to prevent overflows.  However, on the M68000
  310. microprocessor, even though fixed point multipliers and
  311. multiplicands are limited to 16-bits, everything else may be
  312. 32-bits.  Thus, it is permissable for the operation to overflow by
  313. two bits between stages, and there is no loss in significance. 
  314.  
  315.  
  316. The variable:
  317.  
  318. INSHIFT-FFT   may be used to specify a right shift ammount
  319.               for the data going into the first stage of the fft.
  320. OUTBITS-FFT   may be used to specify the number of significant bits
  321.               to use for the output of the fft.  
  322. SHIFTS-FFT    an output value specifying the total number of shifts
  323.               performed on the data.
  324. BLK-EXP-FFT   input and output value which represents the block
  325.               floating point exponent of the data.  It is updated
  326.               by the FFT code simply by adding shifts-fft to the
  327.               input value.
  328.  
  329.  
  330.  
  331. 7.  DATA REPRESENTATION
  332.  
  333.  
  334. Each value uses one cell (long word, 4-bytes, 32-bits).  For
  335. complex numbers, the following conventions apply.  On the stack,
  336. the imaginary part is on top with the real part under it.  In
  337. memory, the real part is at the lower memory address with the
  338. imaginary part at the adjacent higher memory cell address. 
  339.  
  340. For fixed point data, the following applies.  Although 32-bits are
  341. used to hold each value, the signed value must be contained within
  342. the low-order 16-bits, with the high-order 16-bits being the sign
  343. extension of the low-order 16-bits.  The variable INSHIFT-FFT is
  344. primarily provided for handling data with more than 16-bits
  345. significance, including sign bit.  The functions OR.ABS.ARRAY and
  346. NSBITS may be used for rapidly determining the magnitude of an
  347. array of fixed point data. 
  348.  
  349.  
  350.  
  351. 8.  PERFORMANCE
  352.  
  353. Times in seconds for 1024 point fft for complex (FFT, IFFT) and
  354. real (FTRC,IFFCR) data.  The run-time quick-reversal option was
  355. used in all cases.  Add one-tenth of a second for the time without
  356. this option. 
  357.  
  358.  
  359.  complex  real     float  asm-fft  w-table  inner-asm  auto-scale
  360.  
  361.   6.92    3.72       T       F        F         F         F
  362.   3.92    2.00       F       F        F         F         F
  363.   1.24     .60       F       T        T         F         F
  364.    .54     .34       F       T        T         T         F
  365.    .62     .38       F       T        T         T         T
  366.  
  367.  
  368.  
  369.  
  370.  
  371. 9.  FUTURE VERSIONS
  372.  
  373. The following are only possibilities, and will be probably only be
  374. developed if and when the need arises.  The timing performance
  375. improvements are very rough guestimates. 
  376.  
  377. Add option to use table for all trig values, as opposed to their
  378. recursive computation.  (5-10 percent)
  379.  
  380. Provide additional inner-loops which eliminate multiplies by one's
  381. and zero's, and possibly combine multiplies by sqrt(2).  (5-10
  382. percent)
  383.  
  384. Probably will not develop radix-4 fft algorithm (10-20 percent) or
  385. other/mixed radix algorithms. 
  386.  
  387. Provide some commonly used windowing functions. 
  388.  
  389. Change to algrithm(s) which do the bit-reversal after the
  390. transform, rather than prior to the transform.  This would be
  391. preferable for high speed convolution (filtering) and correlation
  392. applications which do not necessarily require any bit-reversal. 
  393.  
  394.  
  395.  
  396.  
  397. 10.  MISCELLANEOUS
  398.  
  399.  
  400. A discussion or derivation of the fast fourier transform is beyond
  401. the scope of this document.  Numerous texts on digital signal
  402. processing are available for this purpose.  I would particularly
  403. recommend "Digital Signal Processing " edited by Lawrence R. 
  404. Rabiner and Charles M.  Radar, IEEE Press. 
  405.