home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume18 / fft < prev    next >
Encoding:
Internet Message Format  |  1989-03-14  |  24.3 KB

  1. Path: wugate!wucs1!uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v18i020:  General Fast Fourier Transform package
  5. Message-ID: <1556@papaya.bbn.com>
  6. Date: 13 Mar 89 23:25:46 GMT
  7. Lines: 1043
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: Peter Valkenburg <cs.vu.nl!valke>
  11. Posting-number: Volume 18, Issue 20
  12. Archive-name: fft
  13.  
  14. The packages included below perform fast fourier transformations on an
  15. arbitrary number of real or complex samples.  It uses a generalized version
  16. of the well-known Cooley-Tukey algorithm, meaning that it will also work
  17. for a number of samples that is not a power of 2.
  18.  
  19. Since I didn't bother to squeeze out the very last machine cycle, you are
  20. not advised to use this in real-time applications.  However, the recursive
  21. algorithm used is very neat.
  22.  
  23. Enjoy.
  24.  
  25.             Peter Valkenburg (valke@cs.vu.nl).
  26. --------------------------------------------------------------------------------
  27. WARNING:  This package shows serious deficiencies if used in SDI-systems or
  28. AEGIS-alikes.  So all of you defense-people: HANDS-OFF!
  29. --------------------------------------------------------------------------------
  30.  
  31. ----------cut here--------------------------------------------------------------
  32. #!/bin/sh
  33. : This is a shar archive.  Extract with sh, not csh.
  34. : This archive ends with exit, so do not worry about trailing junk.
  35. : --------------------------- cut here --------------------------
  36. PATH=/bin:/usr/bin:/usr/ucb
  37. if test -f 'fft'
  38. then    echo Removing   'fft'
  39.     rm 'fft'
  40. fi
  41. if test -d 'fft'
  42. then    :
  43. else    echo Creating   'fft'
  44.     mkdir 'fft'
  45. fi
  46. chmod 'u=rwx,g=rx,o=rx' 'fft'
  47. echo Extracting 'fft/README'
  48. sed 's/^X//' > 'fft/README' << '+ END-OF-FILE ''fft/README'
  49. XThis directory contains the packages realfft(3) and fft(3) that do Cooley-Tukey
  50. Xfast Fourier transform on an arbitrary number of real or complex samples,
  51. Xrespectively.
  52. X
  53. XThe package was tested on 4.[12] bsd & Sun Release 3.5, but it should work on
  54. Xany UNIX system featuring sin(3M) and malloc(3).
  55. X
  56. XContents:
  57. X    complex.h    - include file (for users of fft(3) routines).
  58. X    fft        - manual and source of fft(3).
  59. X    realfft        - manual and source of realfft(3).
  60. X    example        - example of how to use realfft(3).
  61. X
  62. XSee the README's in fft/, realfft/ and example/ to find out how to compile and
  63. Xuse things.
  64. + END-OF-FILE fft/README
  65. chmod 'u=rw,g=r,o=r' 'fft/README'
  66. set `wc -c 'fft/README'`
  67. count=$1
  68. case $count in
  69. 585)    :;;
  70. *)    echo 'Bad character count in ''fft/README' >&2
  71.         echo 'Count should be 585' >&2
  72. esac
  73. if test -f 'fft/complex'
  74. then    echo Removing   'fft/complex'
  75.     rm 'fft/complex'
  76. fi
  77. if test -d 'fft/complex'
  78. then    :
  79. else    echo Creating   'fft/complex'
  80.     mkdir 'fft/complex'
  81. fi
  82. chmod 'u=rwx,g=rx,o=rx' 'fft/complex'
  83. echo Extracting 'fft/complex/Makefile'
  84. sed 's/^X//' > 'fft/complex/Makefile' << '+ END-OF-FILE ''fft/complex/Makefile'
  85. XLTYPE=A18
  86. XTARGET=fft.a
  87. XCFLAGS=-O
  88. XPREFLAGS=
  89. XIDIRS=-I../
  90. XLLIBS=
  91. X
  92. XLINT=lint -uhbaxpc
  93. XCTAGS=ctags
  94. XPRINT=@pr -t
  95. X
  96. XCFILES=\
  97. X    fourier.c\
  98. X    ft.c\
  99. X    w.c
  100. XHFILES=\
  101. X    /usr/include/math.h\
  102. X    ../complex.h\
  103. X    w.h
  104. XOBJECTS=\
  105. X    fourier.o\
  106. X    ft.o\
  107. X    w.o
  108. X
  109. X.SUFFIXES: .i
  110. X
  111. X$(TARGET):    $(OBJECTS)
  112. X    ar rv $@ $?
  113. X    ranlib $@
  114. X
  115. Xlint:
  116. X    $(LINT) $(PREFLAGS) $(IDIRS) $(CFILES) $(LLIBS) -lc
  117. X
  118. Xtags:    $(HFILES) $(CFILES)
  119. X    $(CTAGS) $(HFILES) $(CFILES)
  120. X
  121. Xprint:    fft.man
  122. X    $(PRINT) fft.man tech complex.h w.h $(CFILES)
  123. X
  124. Xfft.man:    fft.3
  125. X    @nroff -man fft.3 > fft.man
  126. X
  127. X.c.o:
  128. X    $(CC) $(CFLAGS) -c $(IDIRS) $<
  129. X
  130. X.c.i:
  131. X    $(CC) $(CFLAGS) -P $(IDIRS) $<
  132. X
  133. X.c.s:
  134. X    $(CC) $(CFLAGS) -S $(IDIRS) $<
  135. X
  136. Xfourier.o:\
  137. X    ../complex.h\
  138. X    w.h
  139. X
  140. Xft.o:\
  141. X    ../complex.h\
  142. X    w.h
  143. X
  144. Xw.o:\
  145. X    ../complex.h\
  146. X    w.h\
  147. X    /usr/include/math.h\
  148. + END-OF-FILE fft/complex/Makefile
  149. chmod 'u=rw,g=r,o=r' 'fft/complex/Makefile'
  150. set `wc -c 'fft/complex/Makefile'`
  151. count=$1
  152. case $count in
  153. 741)    :;;
  154. *)    echo 'Bad character count in ''fft/complex/Makefile' >&2
  155.         echo 'Count should be 741' >&2
  156. esac
  157. echo Extracting 'fft/complex/README'
  158. sed 's/^X//' > 'fft/complex/README' << '+ END-OF-FILE ''fft/complex/README'
  159. XThis fft(3) package does Cooley-Tukey fast Fourier transform on an arbitrary
  160. Xnumber of complex samples.
  161. X
  162. XHow to make the stuff:
  163. X    make        - create library "fft.a"
  164. X    make fft.man    - nroff manual page "fft.3" into "fft.man"
  165. X    make print    - print source, "tech" and "fft.man"
  166. X
  167. XFile "tech" contains a short description of the functions and variables in the
  168. Ximplementation.
  169. X
  170. XPrograms using fft(3), should include "../complex.h" and be loaded (ld(1)) with
  171. Xlibraries "fft.a" and "/usr/lib/libm.a".  The package also uses malloc(3) of
  172. Xthe standard C-library.
  173. + END-OF-FILE fft/complex/README
  174. chmod 'u=rw,g=r,o=r' 'fft/complex/README'
  175. set `wc -c 'fft/complex/README'`
  176. count=$1
  177. case $count in
  178. 544)    :;;
  179. *)    echo 'Bad character count in ''fft/complex/README' >&2
  180.         echo 'Count should be 544' >&2
  181. esac
  182. echo Extracting 'fft/complex/fft.3'
  183. sed 's/^X//' > 'fft/complex/fft.3' << '+ END-OF-FILE ''fft/complex/fft.3'
  184. X.TH FFT 3
  185. X.SH NAME
  186. Xfft, rft \- forward and reverse complex fourier transform
  187. X.SH SYNOPSIS
  188. X.nf
  189. X#include "complex.h"
  190. X
  191. Xfft (in, n, out)
  192. XCOMPLEX *in;
  193. Xunsigned n;
  194. XCOMPLEX *out;
  195. X
  196. Xrft (in, n, out)
  197. XCOMPLEX *in;
  198. Xunsigned n;
  199. XCOMPLEX *out;
  200. X
  201. Xc_re (c)
  202. XCOMPLEX c;
  203. X
  204. Xc_im (c)
  205. XCOMPLEX c;
  206. X.fi
  207. X.SH DESCRIPTION
  208. X.I
  209. XFft
  210. Xand
  211. X.I rft
  212. Xperform, respectively, forward and reverse discrete
  213. Xfast fourier transform on the
  214. X.I n
  215. X(an arbitrary number) complex
  216. Xsamples of array
  217. X.IR in .
  218. XThe result is placed in
  219. X.IR out .
  220. X.br
  221. XThe functions are a recursive implementation of the Cooley-Tukey algorithm.
  222. XBoth use O
  223. X.RI ( n
  224. X*
  225. X.RI ( p1
  226. X+ .. +
  227. X.IR pk ))
  228. Xoperations, where
  229. X.I pi
  230. Xis the
  231. X.IR i -th
  232. Xfactor in the
  233. Xprime-decomposition of size
  234. X.I k
  235. Xof
  236. X.IR n .
  237. X.br
  238. XBoth functions compute a sine/cosine table internally.
  239. XThis table is not recomputed on successive calls with the same
  240. X.IR n .
  241. X
  242. X.I C_re
  243. Xand
  244. X.I c_im
  245. Xare C preprocessor defines that yield the real and imaginary
  246. Xparts of
  247. X.IR c ,
  248. Xrespectively.
  249. XThey are used to assign and inspect arrays
  250. X.I in
  251. Xand
  252. X.IR out .
  253. X.SH FILES
  254. Xfft.a \- library containing fft and rft.
  255. X.br
  256. X/usr/lib/libm.a \- library used by fft.a.
  257. X.SH DIAGNOSTICS
  258. X.I Fft
  259. Xand
  260. X.I rft
  261. Xreturn -1 if allocating space for the internal table fails, else 0.
  262. X.SH BUGS
  263. XThe original contents of
  264. X.I in
  265. Xare destroyed.
  266. X
  267. XThe transform isn't optimized for interesting special cases of
  268. X.IR n ,
  269. Xe.g.\&
  270. X.I n
  271. Xis a power of 2, although it will work in O
  272. X.RI ( n
  273. X* 2log
  274. X.RI ( n )).
  275. X
  276. XThe error for a forward-reverse sequence is about 10e-13 for
  277. X.I n
  278. X= 1024.
  279. X.SH AUTHOR
  280. XPeter Valkenburg (valke@cs.vu.nl).
  281. + END-OF-FILE fft/complex/fft.3
  282. chmod 'u=rw,g=r,o=r' 'fft/complex/fft.3'
  283. set `wc -c 'fft/complex/fft.3'`
  284. count=$1
  285. case $count in
  286. 1548)    :;;
  287. *)    echo 'Bad character count in ''fft/complex/fft.3' >&2
  288.         echo 'Count should be 1548' >&2
  289. esac
  290. echo Extracting 'fft/complex/fourier.c'
  291. sed 's/^X//' > 'fft/complex/fourier.c' << '+ END-OF-FILE ''fft/complex/fourier.c'
  292. X/*
  293. X * "fourier.c", Pjotr '87.
  294. X */
  295. X
  296. X#include    <complex.h>
  297. X#include    "w.h"
  298. X
  299. X/*
  300. X * Recursive (reverse) complex fast Fourier transform on the n
  301. X * complex samples of array in, with the Cooley-Tukey method.
  302. X * The result is placed in out.  The number of samples, n, is arbitrary.
  303. X * The algorithm costs O (n * (r1 + .. + rk)), where k is the number
  304. X * of factors in the prime-decomposition of n (also the maximum
  305. X * depth of the recursion), and ri is the i-th primefactor.
  306. X */
  307. XFourier (in, n, out)
  308. XCOMPLEX *in;
  309. Xunsigned n;
  310. XCOMPLEX *out;
  311. X{
  312. X    unsigned r;
  313. X    unsigned radix ();
  314. X
  315. X    if ((r = radix (n)) < n)
  316. X        split (in, r, n / r, out);
  317. X    join (in, n / r, n, out);
  318. X}
  319. X
  320. X/*
  321. X * Give smallest possible radix for n samples.
  322. X * Determines (in a rude way) the smallest primefactor of n.
  323. X */
  324. Xstatic unsigned radix (n)
  325. Xunsigned n;
  326. X{
  327. X    unsigned r;
  328. X
  329. X    if (n < 2)
  330. X        return 1;
  331. X
  332. X    for (r = 2; r < n; r++)
  333. X        if (n % r == 0)
  334. X            break;
  335. X    return r;
  336. X}
  337. X
  338. X/*
  339. X * Split array in of r * m samples in r parts of each m samples,
  340. X * such that in [i] goes to out [(i % r) * m + (i / r)].
  341. X * Then call for each part of out Fourier, so the r recursively
  342. X * transformed parts will go back to in.
  343. X */
  344. Xstatic split (in, r, m, out)
  345. XCOMPLEX *in;
  346. Xregister unsigned r, m;
  347. XCOMPLEX *out;
  348. X{
  349. X    register unsigned k, s, i, j;
  350. X
  351. X    for (k = 0, j = 0; k < r; k++)
  352. X        for (s = 0, i = k; s < m; s++, i += r, j++)
  353. X            out [j] = in [i];
  354. X
  355. X    for (k = 0; k < r; k++, out += m, in += m)
  356. X        Fourier (out, m, in);
  357. X}
  358. X
  359. X/*
  360. X * Sum the n / m parts of each m samples of in to n samples in out.
  361. X *            r - 1
  362. X * Out [j] becomes  sum  in [j % m] * W (j * k).  Here in is the k-th
  363. X *            k = 0   k           n         k
  364. X * part of in (indices k * m ... (k + 1) * m - 1), and r is the radix.
  365. X * For k = 0, a complex multiplication with W (0) is avoided.
  366. X */
  367. Xstatic join (in, m, n, out)
  368. XCOMPLEX *in;
  369. Xregister unsigned m, n;
  370. XCOMPLEX *out;
  371. X{
  372. X    register unsigned i, j, jk, s;
  373. X
  374. X    for (s = 0; s < m; s++)
  375. X        for (j = s; j < n; j += m) {
  376. X            out [j] = in [s];
  377. X            for (i = s + m, jk = j; i < n; i += m, jk += j)
  378. X                c_add_mul (out [j], in [i], W (n, jk));
  379. X        }
  380. X}
  381. + END-OF-FILE fft/complex/fourier.c
  382. chmod 'u=rw,g=r,o=r' 'fft/complex/fourier.c'
  383. set `wc -c 'fft/complex/fourier.c'`
  384. count=$1
  385. case $count in
  386. 2046)    :;;
  387. *)    echo 'Bad character count in ''fft/complex/fourier.c' >&2
  388.         echo 'Count should be 2046' >&2
  389. esac
  390. echo Extracting 'fft/complex/ft.c'
  391. sed 's/^X//' > 'fft/complex/ft.c' << '+ END-OF-FILE ''fft/complex/ft.c'
  392. X/*
  393. X * "ft.c", Pjotr '87.
  394. X */
  395. X
  396. X#include    <complex.h>
  397. X#include    "w.h"
  398. X
  399. X/*
  400. X * Forward Fast Fourier Transform on the n samples of complex array in.
  401. X * The result is placed in out.  The number of samples, n, is arbitrary.
  402. X * The W-factors are calculated in advance.
  403. X */
  404. Xint fft (in, n, out)
  405. XCOMPLEX *in;
  406. Xunsigned n;
  407. XCOMPLEX *out;
  408. X{
  409. X    unsigned i;
  410. X
  411. X    for (i = 0; i < n; i++)
  412. X        c_conj (in [i]);
  413. X    
  414. X    if (W_init (n) == -1)
  415. X        return -1;
  416. X
  417. X    Fourier (in, n, out);
  418. X
  419. X    for (i = 0; i < n; i++) {
  420. X        c_conj (out [i]);
  421. X        c_realdiv (out [i], n);
  422. X    }
  423. X
  424. X    return 0;
  425. X}
  426. X
  427. X/*
  428. X * Reverse Fast Fourier Transform on the n complex samples of array in.
  429. X * The result is placed in out.  The number of samples, n, is arbitrary.
  430. X * The W-factors are calculated in advance.
  431. X */
  432. Xrft (in, n, out)
  433. XCOMPLEX *in;
  434. Xunsigned n;
  435. XCOMPLEX *out;
  436. X{
  437. X    if (W_init (n) == -1)
  438. X        return -1;
  439. X
  440. X    Fourier (in, n, out);
  441. X
  442. X    return 0;
  443. X}
  444. + END-OF-FILE fft/complex/ft.c
  445. chmod 'u=rw,g=r,o=r' 'fft/complex/ft.c'
  446. set `wc -c 'fft/complex/ft.c'`
  447. count=$1
  448. case $count in
  449. 865)    :;;
  450. *)    echo 'Bad character count in ''fft/complex/ft.c' >&2
  451.         echo 'Count should be 865' >&2
  452. esac
  453. echo Extracting 'fft/complex/tech'
  454. sed 's/^X//' > 'fft/complex/tech' << '+ END-OF-FILE ''fft/complex/tech'
  455. X    Short technical description of functions in the fft(3) package
  456. X
  457. X
  458. X"ft.c"
  459. XThe entry-points:
  460. X    fft    - Forward Complex Fast Fourier Transform
  461. X    rft    - Reverse Complex Fast Fourier Transform
  462. X
  463. X"fourier.c"
  464. XRecursive implementation of the Cooley-Tukey algorithm:
  465. X    Fourier    - top level call
  466. X    radix    - determine radix for a number of samples
  467. X    split    - split samples in groups, and recursively call Fourier
  468. X    join    - join (add) groups of samples into a new group
  469. X
  470. X"complex.h"
  471. XManipulation of complex numbers:
  472. X    COMPLEX    - type for complex numbers
  473. X    c_re    - real part of complex number
  474. X    c_im    - imaginary part of complex number
  475. X    c_add_mul - multiply and add complex numbers
  476. X    c_conj    - convert a complex number into its conjugate
  477. X    c_realdiv - divide a complex by a real number
  478. X
  479. X"w.h"
  480. XW-factors:
  481. X    W    - give previously calculated W-factor
  482. X
  483. X"w.c"
  484. XComputation of W-factors:
  485. X    W_factors - array of W-factors
  486. X    Nfactors - number of factors in W_factors
  487. X    W_init    - prepare W-factors array
  488. + END-OF-FILE fft/complex/tech
  489. chmod 'u=rw,g=r,o=r' 'fft/complex/tech'
  490. set `wc -c 'fft/complex/tech'`
  491. count=$1
  492. case $count in
  493. 951)    :;;
  494. *)    echo 'Bad character count in ''fft/complex/tech' >&2
  495.         echo 'Count should be 951' >&2
  496. esac
  497. echo Extracting 'fft/complex/w.c'
  498. sed 's/^X//' > 'fft/complex/w.c' << '+ END-OF-FILE ''fft/complex/w.c'
  499. X/*
  500. X * "w.c", Pjotr '87.
  501. X */
  502. X
  503. X#include    <complex.h>
  504. X#include    "w.h"
  505. X#include    <math.h>
  506. X
  507. XCOMPLEX *W_factors = 0;        /* array of W-factors */
  508. Xunsigned Nfactors = 0;        /* number of entries in W-factors */
  509. X
  510. X/*
  511. X * W_init puts Wn ^ k (= e ^ (2pi * i * k / n)) in W_factors [k], 0 <= k < n.
  512. X * If n is equal to Nfactors then nothing is done, so the same W_factors
  513. X * array can used for several transforms of the same number of samples.
  514. X * Notice the explicit calculation of sines and cosines, an iterative approach
  515. X * introduces substantial errors.
  516. X */
  517. Xint W_init (n)
  518. Xunsigned n;
  519. X{
  520. X    char *malloc ();
  521. X#    define pi    3.1415926535897932384626434
  522. X    unsigned k;
  523. X
  524. X    if (n == Nfactors)
  525. X        return 0;
  526. X    if (Nfactors != 0 && W_factors != 0)
  527. X        free ((char *) W_factors);
  528. X    if ((Nfactors = n) == 0)
  529. X        return 0;
  530. X    if ((W_factors = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
  531. X        return -1;
  532. X
  533. X    for (k = 0; k < n; k++) {
  534. X        c_re (W_factors [k]) = cos (2 * pi * k / n);
  535. X        c_im (W_factors [k]) = sin (2 * pi * k / n);
  536. X    }
  537. X
  538. X    return 0;
  539. X}
  540. + END-OF-FILE fft/complex/w.c
  541. chmod 'u=rw,g=r,o=r' 'fft/complex/w.c'
  542. set `wc -c 'fft/complex/w.c'`
  543. count=$1
  544. case $count in
  545. 996)    :;;
  546. *)    echo 'Bad character count in ''fft/complex/w.c' >&2
  547.         echo 'Count should be 996' >&2
  548. esac
  549. echo Extracting 'fft/complex/w.h'
  550. sed 's/^X//' > 'fft/complex/w.h' << '+ END-OF-FILE ''fft/complex/w.h'
  551. X/*
  552. X * "w.h", Pjotr '87.
  553. X */
  554. X
  555. Xextern COMPLEX *W_factors;
  556. Xextern unsigned Nfactors;
  557. X
  558. X/*
  559. X * W gives the (already computed) Wn ^ k (= e ^ (2pi * i * k / n)).
  560. X * Notice that the powerseries of Wn has period Nfactors.
  561. X */
  562. X#define    W(n, k)        (W_factors [((k) * (Nfactors / (n))) % Nfactors])
  563. + END-OF-FILE fft/complex/w.h
  564. chmod 'u=rw,g=r,o=r' 'fft/complex/w.h'
  565. set `wc -c 'fft/complex/w.h'`
  566. count=$1
  567. case $count in
  568. 283)    :;;
  569. *)    echo 'Bad character count in ''fft/complex/w.h' >&2
  570.         echo 'Count should be 283' >&2
  571. esac
  572. echo Extracting 'fft/complex.h'
  573. sed 's/^X//' > 'fft/complex.h' << '+ END-OF-FILE ''fft/complex.h'
  574. X/*
  575. X * "complex.h", Pjotr '87.
  576. X */
  577. X
  578. Xtypedef struct {
  579. X        double re, im;
  580. X    } COMPLEX;
  581. X#define        c_re(c)        ((c).re)
  582. X#define        c_im(c)        ((c).im)
  583. X
  584. X/*
  585. X * C_add_mul adds product of c1 and c2 to c.
  586. X */
  587. X#define    c_add_mul(c, c1, c2)    { COMPLEX C1, C2; C1 = (c1); C2 = (c2); \
  588. X                  c_re (c) += C1.re * C2.re - C1.im * C2.im; \
  589. X                  c_im (c) += C1.re * C2.im + C1.im * C2.re; }
  590. X
  591. X/*
  592. X * C_conj substitutes c by its complex conjugate.
  593. X */
  594. X#define c_conj(c)        { c_im (c) = -c_im (c); }
  595. X
  596. X/*
  597. X * C_realdiv divides complex c by real.
  598. X */
  599. X#define    c_realdiv(c, real)    { c_re (c) /= (real); c_im (c) /= (real); }
  600. + END-OF-FILE fft/complex.h
  601. chmod 'u=rw,g=r,o=r' 'fft/complex.h'
  602. set `wc -c 'fft/complex.h'`
  603. count=$1
  604. case $count in
  605. 583)    :;;
  606. *)    echo 'Bad character count in ''fft/complex.h' >&2
  607.         echo 'Count should be 583' >&2
  608. esac
  609. if test -f 'fft/example'
  610. then    echo Removing   'fft/example'
  611.     rm 'fft/example'
  612. fi
  613. if test -d 'fft/example'
  614. then    :
  615. else    echo Creating   'fft/example'
  616.     mkdir 'fft/example'
  617. fi
  618. chmod 'u=rwx,g=rx,o=rx' 'fft/example'
  619. echo Extracting 'fft/example/README'
  620. sed 's/^X//' > 'fft/example/README' << '+ END-OF-FILE ''fft/example/README'
  621. XAn example of realfft(3) usage is in example.c.  It contains two fourier
  622. Xtransforms on real data.
  623. X
  624. XCompile with:
  625. X    cc example.c ../real/realfft.a ../complex/fft.a -lm
  626. + END-OF-FILE fft/example/README
  627. chmod 'u=rw,g=r,o=r' 'fft/example/README'
  628. set `wc -c 'fft/example/README'`
  629. count=$1
  630. case $count in
  631. 166)    :;;
  632. *)    echo 'Bad character count in ''fft/example/README' >&2
  633.         echo 'Count should be 166' >&2
  634. esac
  635. echo Extracting 'fft/example/example.c'
  636. sed 's/^X//' > 'fft/example/example.c' << '+ END-OF-FILE ''fft/example/example.c'
  637. X/*
  638. X * Test for realfft(3).
  639. X */
  640. X
  641. X#define        N    8
  642. X#define     pi    3.1415926535897932384626434
  643. X
  644. Xdouble sin (), cos ();
  645. Xchar *malloc ();
  646. X
  647. Xmain ()
  648. X{
  649. X    unsigned i, j;
  650. X
  651. X    double in [N], out [N];
  652. X
  653. X    printf ("Example #1:\n");
  654. X    for (i = 0; i < N; i++)
  655. X        in [i] = i;
  656. X    printsamp (in, N);
  657. X
  658. X    realfft (in, N, out);
  659. X    printf ("After a fast fft\n");
  660. X    printampl (out, N);
  661. X
  662. X    /* check */
  663. X    printf ("A reverse slow ft gives:\n");
  664. X    srft (out, N, in);
  665. X    printsamp (in, N);
  666. X
  667. X    printf ("And the reverse fast ft yields:\n");
  668. X    realrft (out, N, in);
  669. X    printsamp (in, N);
  670. X
  671. X    printf ("\n\nExample #2\n");
  672. X    for (i = 0; i < N; i++) {
  673. X        in [i] = 0;
  674. X        for (j = 0; j <= N / 2; j++)
  675. X            in [i] += cos (2 * pi * i * j / N) +
  676. X                  sin (2 * pi * i * j / N);
  677. X    }
  678. X    printsamp (in, N);
  679. X
  680. X    realfft (in, N, out);
  681. X    printf ("After a forward fast ft:\n");
  682. X    printampl (out, N);
  683. X
  684. X    /* check */
  685. X    printf ("A reverse slow ft yields:\n");
  686. X    srft (out, N, in);
  687. X    printsamp (in, N);
  688. X
  689. X    printf ("And a reverse fast ft gives:\n");
  690. X    realrft (out, N, in);
  691. X    printsamp (in, N);
  692. X}
  693. X
  694. Xprintampl (ampl, n)
  695. Xdouble *ampl;
  696. Xunsigned n;
  697. X{
  698. X    unsigned i;
  699. X
  700. X    printf ("Amplitudes\n");
  701. X
  702. X    if (n == 0)
  703. X        return;
  704. X
  705. X    printf ("%f (dc)\n", ampl [0]);
  706. X    for (i = 1; i < (n + 1) / 2; i++)
  707. X        printf ("%f, %f (%u-th harmonic)\n", ampl [2 * i - 1],
  708. X                             ampl [2 * i], i);
  709. X    if (n % 2 == 0)
  710. X        printf ("%f (Nyquist)\n", ampl [n - 1]);
  711. X
  712. X    printf ("\n");
  713. X}
  714. X
  715. Xprintsamp (samp, n)
  716. Xdouble *samp;
  717. Xunsigned n;
  718. X{
  719. X    unsigned i;
  720. X    printf ("Samples\n");
  721. X
  722. X    for (i = 0; i < n; i++)
  723. X        printf ("%f\n", samp [i]);
  724. X    
  725. X    printf ("\n");
  726. X}
  727. X
  728. X/*
  729. X * Slow reverse fourier transform.  In [0] contains dc, in [n - 1] Nyquist.
  730. X * This is just a gimmick to compare with realfft(3).
  731. X */
  732. Xsrft (in, n, out)
  733. Xdouble *in;
  734. Xunsigned n;
  735. Xdouble *out;
  736. X{
  737. X    unsigned i, j;
  738. X
  739. X    for (i = 0; i < n; i++) {
  740. X        out [i] = in [0];            /* dc */
  741. X        for (j = 1; j < (n + 1) / 2; j++)    /* j-th harmonic */
  742. X            out [i] += in [2 * j - 1] * cos (2 * pi * i * j / n) +
  743. X                   in [2 * j] * sin (2 * pi * i * j / n);
  744. X        if (n % 2 == 0)                /* Nyquist */
  745. X            out [i] += in [n - 1] * cos (2 * pi * i * j / n);
  746. X    }
  747. X}
  748. + END-OF-FILE fft/example/example.c
  749. chmod 'u=rw,g=r,o=r' 'fft/example/example.c'
  750. set `wc -c 'fft/example/example.c'`
  751. count=$1
  752. case $count in
  753. 2026)    :;;
  754. *)    echo 'Bad character count in ''fft/example/example.c' >&2
  755.         echo 'Count should be 2026' >&2
  756. esac
  757. if test -f 'fft/real'
  758. then    echo Removing   'fft/real'
  759.     rm 'fft/real'
  760. fi
  761. if test -d 'fft/real'
  762. then    :
  763. else    echo Creating   'fft/real'
  764.     mkdir 'fft/real'
  765. fi
  766. chmod 'u=rwx,g=rx,o=rx' 'fft/real'
  767. echo Extracting 'fft/real/Makefile'
  768. sed 's/^X//' > 'fft/real/Makefile' << '+ END-OF-FILE ''fft/real/Makefile'
  769. XLTYPE=A18
  770. XTARGET=realfft.a
  771. XCFLAGS=-O
  772. XPREFLAGS=
  773. XIDIRS=-I../
  774. XLLIBS=
  775. X
  776. XLINT=lint -uhbaxc
  777. XCTAGS=ctags
  778. XPRINT=@pr -t
  779. X
  780. XCFILES=\
  781. X    realfft.c
  782. XHFILES=\
  783. X    ../complex.h
  784. XOBJECTS=\
  785. X    realfft.o
  786. X
  787. X.SUFFIXES: .i
  788. X
  789. X$(TARGET):    $(OBJECTS)
  790. X    ar rv $@ $?
  791. X    ranlib $@
  792. X
  793. Xlint:
  794. X    $(LINT) $(PREFLAGS) $(IDIRS) $(CFILES) $(LLIBS) -lc
  795. X
  796. Xtags:    $(HFILES) $(CFILES)
  797. X    $(CTAGS) $(HFILES) $(CFILES)
  798. X
  799. Xprint:    realfft.man
  800. X    $(PRINT) realfft.man $(CFILES)
  801. X
  802. Xrealfft.man:    realfft.3
  803. X    @nroff -man realfft.3 > realfft.man
  804. X
  805. X.c.o:
  806. X    $(CC) $(CFLAGS) -c $(IDIRS) $<
  807. X
  808. X.c.i:
  809. X    $(CC) $(CFLAGS) -P $(IDIRS) $<
  810. X
  811. X.c.s:
  812. X    $(CC) $(CFLAGS) -S $(IDIRS) $<
  813. X
  814. Xrealfft.o:\
  815. X    ../complex.h
  816. + END-OF-FILE fft/real/Makefile
  817. chmod 'u=rw,g=r,o=r' 'fft/real/Makefile'
  818. set `wc -c 'fft/real/Makefile'`
  819. count=$1
  820. case $count in
  821. 611)    :;;
  822. *)    echo 'Bad character count in ''fft/real/Makefile' >&2
  823.         echo 'Count should be 611' >&2
  824. esac
  825. echo Extracting 'fft/real/README'
  826. sed 's/^X//' > 'fft/real/README' << '+ END-OF-FILE ''fft/real/README'
  827. XThis realfft(3) package does Cooley-Tukey fast Fourier transform on an arbitrary
  828. Xnumber of real samples.  It uses fft(3) for the actual complex transform.
  829. X
  830. XHow to make the stuff:
  831. X    make        - create library "realfft.a"
  832. X    make fft.man    - nroff manual page "realfft.3" into "realfft.man"
  833. X    make print    - print source and "realfft.man"
  834. X
  835. XPrograms using realfft(3), should be loaded (ld(1)) with libraries "realfft.a",
  836. X"../complex/fft.a" and "/usr/lib/libm.a".  The package also uses malloc(3) of
  837. Xthe standard C-library.
  838. + END-OF-FILE fft/real/README
  839. chmod 'u=rw,g=r,o=r' 'fft/real/README'
  840. set `wc -c 'fft/real/README'`
  841. count=$1
  842. case $count in
  843. 508)    :;;
  844. *)    echo 'Bad character count in ''fft/real/README' >&2
  845.         echo 'Count should be 508' >&2
  846. esac
  847. echo Extracting 'fft/real/realfft.3'
  848. sed 's/^X//' > 'fft/real/realfft.3' << '+ END-OF-FILE ''fft/real/realfft.3'
  849. X.TH REALFFT 3
  850. X.SH NAME
  851. Xrealfft, realrft \- forward and reverse real fourier transform
  852. X.SH SYNOPSIS
  853. X.nf
  854. Xrealfft (in, n, out)
  855. Xdouble *in;
  856. Xunsigned n;
  857. Xdouble *out;
  858. X
  859. Xrealrft (in, n, out)
  860. Xdouble *in;
  861. Xunsigned n;
  862. Xdouble *out;
  863. X.fi
  864. X.SH DESCRIPTION
  865. X.I Realfft
  866. Xand
  867. X.I realrft
  868. Xperform, respectively, forward and reverse discrete
  869. Xfast fourier transform on the
  870. X.I n
  871. X(an arbitrary number) reals
  872. Xof array
  873. X.IR in .
  874. XThe result (also
  875. X.I n
  876. Xreals) is placed in array
  877. X.IR out .
  878. XThe original contents of
  879. X.I in
  880. Xare not disturbed.
  881. X
  882. XThe format of the
  883. X.I out
  884. Xarray of
  885. X.I realfft
  886. Xand the
  887. X.I in
  888. Xarray of
  889. X.I realrft
  890. Xis as follows:
  891. XThe cosine component of the dc frequency is under index 0
  892. Xand the
  893. X.IR i -th
  894. Xharmonic's cosine and sine are under, respectively, index
  895. X2 *
  896. X.I i
  897. X- 1 and 2 *
  898. X.IR i .
  899. XIf
  900. X.I n
  901. Xis even then the cosine component of the
  902. XNyquist frequency is under index
  903. X.I n
  904. X- 1.
  905. XNote that the dc and Nyquist sine components need not be passed, since they
  906. Xare always 0.
  907. X
  908. XThe actual transform is done by
  909. X.IR fft (3)
  910. Xin complex space.
  911. X.SH "SEE ALSO"
  912. Xfft(3)
  913. X.SH FILES
  914. Xrealfft.a \- contains realfft and realrft.
  915. X.br
  916. Xfft.a \- library used by realfft.a.
  917. X.br
  918. X/usr/lib/libm.a \- library used by fft.a.
  919. X.SH DIAGNOSTICS
  920. X.I Realfft
  921. Xand
  922. X.I realrft
  923. Xreturn -1 if routines in
  924. X.IR fft (3)
  925. Xfail, else 0.
  926. X.SH BUGS
  927. XThe error for a forward-reverse sequence is about 1e-13 for
  928. X.I n
  929. X= 1024.
  930. X.SH AUTHOR
  931. XPeter Valkenburg (valke@cs.vu.nl)
  932. + END-OF-FILE fft/real/realfft.3
  933. chmod 'u=rw,g=r,o=r' 'fft/real/realfft.3'
  934. set `wc -c 'fft/real/realfft.3'`
  935. count=$1
  936. case $count in
  937. 1391)    :;;
  938. *)    echo 'Bad character count in ''fft/real/realfft.3' >&2
  939.         echo 'Count should be 1391' >&2
  940. esac
  941. echo Extracting 'fft/real/realfft.c'
  942. sed 's/^X//' > 'fft/real/realfft.c' << '+ END-OF-FILE ''fft/real/realfft.c'
  943. X/*
  944. X * "realfft.c", Pjotr '87
  945. X */
  946. X
  947. X/*
  948. X * Bevat funkties realfft en realrft die resp. forward en reverse fast fourier
  949. X * transform op reele samples doen.  Gebruikt pakket fft(3).
  950. X */
  951. X
  952. X#include    <complex.h>
  953. X
  954. Xchar *malloc ();
  955. X
  956. X/*
  957. X * Reele forward fast fourier transform van n samples van in naar
  958. X * amplitudes van out.
  959. X * De cosinus komponent van de dc komt in out [0], dan volgen in
  960. X * out [2 * i - 1] en out [2 * i] steeds resp. de cosinus en sinus
  961. X * komponenten van de i-de harmonische.  Bij een even aantal samples
  962. X * bevat out [n - 1] de cosinus komponent van de Nyquist frequentie. 
  963. X * Extraatje: Na afloop is in onaangetast.
  964. X */
  965. Xrealfft (in, n, out)
  966. Xdouble *in;
  967. Xunsigned n;
  968. Xdouble *out;
  969. X{
  970. X    COMPLEX *c_in, *c_out;
  971. X    unsigned i;
  972. X
  973. X    if (n == 0 ||
  974. X        (c_in = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0 ||
  975. X        (c_out = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
  976. X        return;
  977. X    
  978. X    for (i = 0; i < n; i++) {
  979. X        c_re (c_in [i]) = in [i];
  980. X        c_im (c_in [i]) = 0;
  981. X    }
  982. X
  983. X    fft (c_in, n, c_out);
  984. X
  985. X    out [0] = c_re (c_out [0]);        /* cos van dc */
  986. X    for (i = 1; i < (n + 1) / 2; i++) {    /* cos/sin i-de harmonische */
  987. X        out [2 * i - 1] = c_re (c_out [i]) * 2;
  988. X        out [2 * i] = c_im (c_out [i]) * -2;
  989. X    }
  990. X    if (n % 2 == 0)                /* cos van Nyquist */
  991. X        out [n - 1] = c_re (c_out [n / 2]);
  992. X
  993. X    free ((char *) c_in);
  994. X    free ((char *) c_out);
  995. X}
  996. X
  997. X/*
  998. X * Reele reverse fast fourier transform van amplitudes van in naar
  999. X * n samples van out.
  1000. X * De cosinus komponent van de dc staat in in [0], dan volgen in
  1001. X * in [2 * i - 1] en in [2 * i] steeds resp. de cosinus en sinus
  1002. X * komponenten van de i-de harmonische.  Bij een even aantal samples
  1003. X * bevat in [n - 1] de cosinus komponent van de Nyquist frequentie. 
  1004. X * Extraatje: Na afloop is in onaangetast.
  1005. X */
  1006. Xrealrft (in, n, out)
  1007. Xdouble *in;
  1008. Xunsigned n;
  1009. Xdouble *out;
  1010. X{
  1011. X    COMPLEX *c_in, *c_out;
  1012. X    unsigned i;
  1013. X
  1014. X    if (n == 0 ||
  1015. X        (c_in = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0 ||
  1016. X        (c_out = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
  1017. X        return;
  1018. X    
  1019. X    c_re (c_in [0]) = in [0];        /* dc */
  1020. X    c_im (c_in [0]) = 0;
  1021. X    for (i = 1; i < (n + 1) / 2; i++) {    /* geconj. symm. harmonischen */
  1022. X        c_re (c_in [i]) = in [2 * i - 1] / 2;
  1023. X        c_im (c_in [i]) = in [2 * i] / -2;
  1024. X        c_re (c_in [n - i]) = in [2 * i - 1] / 2;
  1025. X        c_im (c_in [n - i]) = in [2 * i] / 2;
  1026. X    }
  1027. X    if (n % 2 == 0) {            /* Nyquist */
  1028. X        c_re (c_in [n / 2]) = in [n - 1];
  1029. X        c_im (c_in [n / 2]) = 0;
  1030. X    }
  1031. X
  1032. X    rft (c_in, n, c_out);
  1033. X
  1034. X    for (i = 0; i < n; i++)
  1035. X        out [i] = c_re (c_out [i]);
  1036. X
  1037. X    free ((char *) c_in);
  1038. X    free ((char *) c_out);
  1039. X}
  1040. + END-OF-FILE fft/real/realfft.c
  1041. chmod 'u=rw,g=r,o=r' 'fft/real/realfft.c'
  1042. set `wc -c 'fft/real/realfft.c'`
  1043. count=$1
  1044. case $count in
  1045. 2503)    :;;
  1046. *)    echo 'Bad character count in ''fft/real/realfft.c' >&2
  1047.         echo 'Count should be 2503' >&2
  1048. esac
  1049. exit 0
  1050.  
  1051. -- 
  1052. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1053.