home *** CD-ROM | disk | FTP | other *** search
- Path: wugate!wucs1!uunet!bbn.com!rsalz
- From: rsalz@uunet.uu.net (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v18i020: General Fast Fourier Transform package
- Message-ID: <1556@papaya.bbn.com>
- Date: 13 Mar 89 23:25:46 GMT
- Lines: 1043
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Peter Valkenburg <cs.vu.nl!valke>
- Posting-number: Volume 18, Issue 20
- Archive-name: fft
-
- The packages included below perform fast fourier transformations on an
- arbitrary number of real or complex samples. It uses a generalized version
- of the well-known Cooley-Tukey algorithm, meaning that it will also work
- for a number of samples that is not a power of 2.
-
- Since I didn't bother to squeeze out the very last machine cycle, you are
- not advised to use this in real-time applications. However, the recursive
- algorithm used is very neat.
-
- Enjoy.
-
- Peter Valkenburg (valke@cs.vu.nl).
- --------------------------------------------------------------------------------
- WARNING: This package shows serious deficiencies if used in SDI-systems or
- AEGIS-alikes. So all of you defense-people: HANDS-OFF!
- --------------------------------------------------------------------------------
-
- ----------cut here--------------------------------------------------------------
- #!/bin/sh
- : This is a shar archive. Extract with sh, not csh.
- : This archive ends with exit, so do not worry about trailing junk.
- : --------------------------- cut here --------------------------
- PATH=/bin:/usr/bin:/usr/ucb
- if test -f 'fft'
- then echo Removing 'fft'
- rm 'fft'
- fi
- if test -d 'fft'
- then :
- else echo Creating 'fft'
- mkdir 'fft'
- fi
- chmod 'u=rwx,g=rx,o=rx' 'fft'
- echo Extracting 'fft/README'
- sed 's/^X//' > 'fft/README' << '+ END-OF-FILE ''fft/README'
- XThis directory contains the packages realfft(3) and fft(3) that do Cooley-Tukey
- Xfast Fourier transform on an arbitrary number of real or complex samples,
- Xrespectively.
- X
- XThe package was tested on 4.[12] bsd & Sun Release 3.5, but it should work on
- Xany UNIX system featuring sin(3M) and malloc(3).
- X
- XContents:
- X complex.h - include file (for users of fft(3) routines).
- X fft - manual and source of fft(3).
- X realfft - manual and source of realfft(3).
- X example - example of how to use realfft(3).
- X
- XSee the README's in fft/, realfft/ and example/ to find out how to compile and
- Xuse things.
- + END-OF-FILE fft/README
- chmod 'u=rw,g=r,o=r' 'fft/README'
- set `wc -c 'fft/README'`
- count=$1
- case $count in
- 585) :;;
- *) echo 'Bad character count in ''fft/README' >&2
- echo 'Count should be 585' >&2
- esac
- if test -f 'fft/complex'
- then echo Removing 'fft/complex'
- rm 'fft/complex'
- fi
- if test -d 'fft/complex'
- then :
- else echo Creating 'fft/complex'
- mkdir 'fft/complex'
- fi
- chmod 'u=rwx,g=rx,o=rx' 'fft/complex'
- echo Extracting 'fft/complex/Makefile'
- sed 's/^X//' > 'fft/complex/Makefile' << '+ END-OF-FILE ''fft/complex/Makefile'
- XLTYPE=A18
- XTARGET=fft.a
- XCFLAGS=-O
- XPREFLAGS=
- XIDIRS=-I../
- XLLIBS=
- X
- XLINT=lint -uhbaxpc
- XCTAGS=ctags
- XPRINT=@pr -t
- X
- XCFILES=\
- X fourier.c\
- X ft.c\
- X w.c
- XHFILES=\
- X /usr/include/math.h\
- X ../complex.h\
- X w.h
- XOBJECTS=\
- X fourier.o\
- X ft.o\
- X w.o
- X
- X.SUFFIXES: .i
- X
- X$(TARGET): $(OBJECTS)
- X ar rv $@ $?
- X ranlib $@
- X
- Xlint:
- X $(LINT) $(PREFLAGS) $(IDIRS) $(CFILES) $(LLIBS) -lc
- X
- Xtags: $(HFILES) $(CFILES)
- X $(CTAGS) $(HFILES) $(CFILES)
- X
- Xprint: fft.man
- X $(PRINT) fft.man tech complex.h w.h $(CFILES)
- X
- Xfft.man: fft.3
- X @nroff -man fft.3 > fft.man
- X
- X.c.o:
- X $(CC) $(CFLAGS) -c $(IDIRS) $<
- X
- X.c.i:
- X $(CC) $(CFLAGS) -P $(IDIRS) $<
- X
- X.c.s:
- X $(CC) $(CFLAGS) -S $(IDIRS) $<
- X
- Xfourier.o:\
- X ../complex.h\
- X w.h
- X
- Xft.o:\
- X ../complex.h\
- X w.h
- X
- Xw.o:\
- X ../complex.h\
- X w.h\
- X /usr/include/math.h\
- + END-OF-FILE fft/complex/Makefile
- chmod 'u=rw,g=r,o=r' 'fft/complex/Makefile'
- set `wc -c 'fft/complex/Makefile'`
- count=$1
- case $count in
- 741) :;;
- *) echo 'Bad character count in ''fft/complex/Makefile' >&2
- echo 'Count should be 741' >&2
- esac
- echo Extracting 'fft/complex/README'
- sed 's/^X//' > 'fft/complex/README' << '+ END-OF-FILE ''fft/complex/README'
- XThis fft(3) package does Cooley-Tukey fast Fourier transform on an arbitrary
- Xnumber of complex samples.
- X
- XHow to make the stuff:
- X make - create library "fft.a"
- X make fft.man - nroff manual page "fft.3" into "fft.man"
- X make print - print source, "tech" and "fft.man"
- X
- XFile "tech" contains a short description of the functions and variables in the
- Ximplementation.
- X
- XPrograms using fft(3), should include "../complex.h" and be loaded (ld(1)) with
- Xlibraries "fft.a" and "/usr/lib/libm.a". The package also uses malloc(3) of
- Xthe standard C-library.
- + END-OF-FILE fft/complex/README
- chmod 'u=rw,g=r,o=r' 'fft/complex/README'
- set `wc -c 'fft/complex/README'`
- count=$1
- case $count in
- 544) :;;
- *) echo 'Bad character count in ''fft/complex/README' >&2
- echo 'Count should be 544' >&2
- esac
- echo Extracting 'fft/complex/fft.3'
- sed 's/^X//' > 'fft/complex/fft.3' << '+ END-OF-FILE ''fft/complex/fft.3'
- X.TH FFT 3
- X.SH NAME
- Xfft, rft \- forward and reverse complex fourier transform
- X.SH SYNOPSIS
- X.nf
- X#include "complex.h"
- X
- Xfft (in, n, out)
- XCOMPLEX *in;
- Xunsigned n;
- XCOMPLEX *out;
- X
- Xrft (in, n, out)
- XCOMPLEX *in;
- Xunsigned n;
- XCOMPLEX *out;
- X
- Xc_re (c)
- XCOMPLEX c;
- X
- Xc_im (c)
- XCOMPLEX c;
- X.fi
- X.SH DESCRIPTION
- X.I
- XFft
- Xand
- X.I rft
- Xperform, respectively, forward and reverse discrete
- Xfast fourier transform on the
- X.I n
- X(an arbitrary number) complex
- Xsamples of array
- X.IR in .
- XThe result is placed in
- X.IR out .
- X.br
- XThe functions are a recursive implementation of the Cooley-Tukey algorithm.
- XBoth use O
- X.RI ( n
- X*
- X.RI ( p1
- X+ .. +
- X.IR pk ))
- Xoperations, where
- X.I pi
- Xis the
- X.IR i -th
- Xfactor in the
- Xprime-decomposition of size
- X.I k
- Xof
- X.IR n .
- X.br
- XBoth functions compute a sine/cosine table internally.
- XThis table is not recomputed on successive calls with the same
- X.IR n .
- X
- X.I C_re
- Xand
- X.I c_im
- Xare C preprocessor defines that yield the real and imaginary
- Xparts of
- X.IR c ,
- Xrespectively.
- XThey are used to assign and inspect arrays
- X.I in
- Xand
- X.IR out .
- X.SH FILES
- Xfft.a \- library containing fft and rft.
- X.br
- X/usr/lib/libm.a \- library used by fft.a.
- X.SH DIAGNOSTICS
- X.I Fft
- Xand
- X.I rft
- Xreturn -1 if allocating space for the internal table fails, else 0.
- X.SH BUGS
- XThe original contents of
- X.I in
- Xare destroyed.
- X
- XThe transform isn't optimized for interesting special cases of
- X.IR n ,
- Xe.g.\&
- X.I n
- Xis a power of 2, although it will work in O
- X.RI ( n
- X* 2log
- X.RI ( n )).
- X
- XThe error for a forward-reverse sequence is about 10e-13 for
- X.I n
- X= 1024.
- X.SH AUTHOR
- XPeter Valkenburg (valke@cs.vu.nl).
- + END-OF-FILE fft/complex/fft.3
- chmod 'u=rw,g=r,o=r' 'fft/complex/fft.3'
- set `wc -c 'fft/complex/fft.3'`
- count=$1
- case $count in
- 1548) :;;
- *) echo 'Bad character count in ''fft/complex/fft.3' >&2
- echo 'Count should be 1548' >&2
- esac
- echo Extracting 'fft/complex/fourier.c'
- sed 's/^X//' > 'fft/complex/fourier.c' << '+ END-OF-FILE ''fft/complex/fourier.c'
- X/*
- X * "fourier.c", Pjotr '87.
- X */
- X
- X#include <complex.h>
- X#include "w.h"
- X
- X/*
- X * Recursive (reverse) complex fast Fourier transform on the n
- X * complex samples of array in, with the Cooley-Tukey method.
- X * The result is placed in out. The number of samples, n, is arbitrary.
- X * The algorithm costs O (n * (r1 + .. + rk)), where k is the number
- X * of factors in the prime-decomposition of n (also the maximum
- X * depth of the recursion), and ri is the i-th primefactor.
- X */
- XFourier (in, n, out)
- XCOMPLEX *in;
- Xunsigned n;
- XCOMPLEX *out;
- X{
- X unsigned r;
- X unsigned radix ();
- X
- X if ((r = radix (n)) < n)
- X split (in, r, n / r, out);
- X join (in, n / r, n, out);
- X}
- X
- X/*
- X * Give smallest possible radix for n samples.
- X * Determines (in a rude way) the smallest primefactor of n.
- X */
- Xstatic unsigned radix (n)
- Xunsigned n;
- X{
- X unsigned r;
- X
- X if (n < 2)
- X return 1;
- X
- X for (r = 2; r < n; r++)
- X if (n % r == 0)
- X break;
- X return r;
- X}
- X
- X/*
- X * Split array in of r * m samples in r parts of each m samples,
- X * such that in [i] goes to out [(i % r) * m + (i / r)].
- X * Then call for each part of out Fourier, so the r recursively
- X * transformed parts will go back to in.
- X */
- Xstatic split (in, r, m, out)
- XCOMPLEX *in;
- Xregister unsigned r, m;
- XCOMPLEX *out;
- X{
- X register unsigned k, s, i, j;
- X
- X for (k = 0, j = 0; k < r; k++)
- X for (s = 0, i = k; s < m; s++, i += r, j++)
- X out [j] = in [i];
- X
- X for (k = 0; k < r; k++, out += m, in += m)
- X Fourier (out, m, in);
- X}
- X
- X/*
- X * Sum the n / m parts of each m samples of in to n samples in out.
- X * r - 1
- X * Out [j] becomes sum in [j % m] * W (j * k). Here in is the k-th
- X * k = 0 k n k
- X * part of in (indices k * m ... (k + 1) * m - 1), and r is the radix.
- X * For k = 0, a complex multiplication with W (0) is avoided.
- X */
- Xstatic join (in, m, n, out)
- XCOMPLEX *in;
- Xregister unsigned m, n;
- XCOMPLEX *out;
- X{
- X register unsigned i, j, jk, s;
- X
- X for (s = 0; s < m; s++)
- X for (j = s; j < n; j += m) {
- X out [j] = in [s];
- X for (i = s + m, jk = j; i < n; i += m, jk += j)
- X c_add_mul (out [j], in [i], W (n, jk));
- X }
- X}
- + END-OF-FILE fft/complex/fourier.c
- chmod 'u=rw,g=r,o=r' 'fft/complex/fourier.c'
- set `wc -c 'fft/complex/fourier.c'`
- count=$1
- case $count in
- 2046) :;;
- *) echo 'Bad character count in ''fft/complex/fourier.c' >&2
- echo 'Count should be 2046' >&2
- esac
- echo Extracting 'fft/complex/ft.c'
- sed 's/^X//' > 'fft/complex/ft.c' << '+ END-OF-FILE ''fft/complex/ft.c'
- X/*
- X * "ft.c", Pjotr '87.
- X */
- X
- X#include <complex.h>
- X#include "w.h"
- X
- X/*
- X * Forward Fast Fourier Transform on the n samples of complex array in.
- X * The result is placed in out. The number of samples, n, is arbitrary.
- X * The W-factors are calculated in advance.
- X */
- Xint fft (in, n, out)
- XCOMPLEX *in;
- Xunsigned n;
- XCOMPLEX *out;
- X{
- X unsigned i;
- X
- X for (i = 0; i < n; i++)
- X c_conj (in [i]);
- X
- X if (W_init (n) == -1)
- X return -1;
- X
- X Fourier (in, n, out);
- X
- X for (i = 0; i < n; i++) {
- X c_conj (out [i]);
- X c_realdiv (out [i], n);
- X }
- X
- X return 0;
- X}
- X
- X/*
- X * Reverse Fast Fourier Transform on the n complex samples of array in.
- X * The result is placed in out. The number of samples, n, is arbitrary.
- X * The W-factors are calculated in advance.
- X */
- Xrft (in, n, out)
- XCOMPLEX *in;
- Xunsigned n;
- XCOMPLEX *out;
- X{
- X if (W_init (n) == -1)
- X return -1;
- X
- X Fourier (in, n, out);
- X
- X return 0;
- X}
- + END-OF-FILE fft/complex/ft.c
- chmod 'u=rw,g=r,o=r' 'fft/complex/ft.c'
- set `wc -c 'fft/complex/ft.c'`
- count=$1
- case $count in
- 865) :;;
- *) echo 'Bad character count in ''fft/complex/ft.c' >&2
- echo 'Count should be 865' >&2
- esac
- echo Extracting 'fft/complex/tech'
- sed 's/^X//' > 'fft/complex/tech' << '+ END-OF-FILE ''fft/complex/tech'
- X Short technical description of functions in the fft(3) package
- X
- X
- X"ft.c"
- XThe entry-points:
- X fft - Forward Complex Fast Fourier Transform
- X rft - Reverse Complex Fast Fourier Transform
- X
- X"fourier.c"
- XRecursive implementation of the Cooley-Tukey algorithm:
- X Fourier - top level call
- X radix - determine radix for a number of samples
- X split - split samples in groups, and recursively call Fourier
- X join - join (add) groups of samples into a new group
- X
- X"complex.h"
- XManipulation of complex numbers:
- X COMPLEX - type for complex numbers
- X c_re - real part of complex number
- X c_im - imaginary part of complex number
- X c_add_mul - multiply and add complex numbers
- X c_conj - convert a complex number into its conjugate
- X c_realdiv - divide a complex by a real number
- X
- X"w.h"
- XW-factors:
- X W - give previously calculated W-factor
- X
- X"w.c"
- XComputation of W-factors:
- X W_factors - array of W-factors
- X Nfactors - number of factors in W_factors
- X W_init - prepare W-factors array
- + END-OF-FILE fft/complex/tech
- chmod 'u=rw,g=r,o=r' 'fft/complex/tech'
- set `wc -c 'fft/complex/tech'`
- count=$1
- case $count in
- 951) :;;
- *) echo 'Bad character count in ''fft/complex/tech' >&2
- echo 'Count should be 951' >&2
- esac
- echo Extracting 'fft/complex/w.c'
- sed 's/^X//' > 'fft/complex/w.c' << '+ END-OF-FILE ''fft/complex/w.c'
- X/*
- X * "w.c", Pjotr '87.
- X */
- X
- X#include <complex.h>
- X#include "w.h"
- X#include <math.h>
- X
- XCOMPLEX *W_factors = 0; /* array of W-factors */
- Xunsigned Nfactors = 0; /* number of entries in W-factors */
- X
- X/*
- X * W_init puts Wn ^ k (= e ^ (2pi * i * k / n)) in W_factors [k], 0 <= k < n.
- X * If n is equal to Nfactors then nothing is done, so the same W_factors
- X * array can used for several transforms of the same number of samples.
- X * Notice the explicit calculation of sines and cosines, an iterative approach
- X * introduces substantial errors.
- X */
- Xint W_init (n)
- Xunsigned n;
- X{
- X char *malloc ();
- X# define pi 3.1415926535897932384626434
- X unsigned k;
- X
- X if (n == Nfactors)
- X return 0;
- X if (Nfactors != 0 && W_factors != 0)
- X free ((char *) W_factors);
- X if ((Nfactors = n) == 0)
- X return 0;
- X if ((W_factors = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
- X return -1;
- X
- X for (k = 0; k < n; k++) {
- X c_re (W_factors [k]) = cos (2 * pi * k / n);
- X c_im (W_factors [k]) = sin (2 * pi * k / n);
- X }
- X
- X return 0;
- X}
- + END-OF-FILE fft/complex/w.c
- chmod 'u=rw,g=r,o=r' 'fft/complex/w.c'
- set `wc -c 'fft/complex/w.c'`
- count=$1
- case $count in
- 996) :;;
- *) echo 'Bad character count in ''fft/complex/w.c' >&2
- echo 'Count should be 996' >&2
- esac
- echo Extracting 'fft/complex/w.h'
- sed 's/^X//' > 'fft/complex/w.h' << '+ END-OF-FILE ''fft/complex/w.h'
- X/*
- X * "w.h", Pjotr '87.
- X */
- X
- Xextern COMPLEX *W_factors;
- Xextern unsigned Nfactors;
- X
- X/*
- X * W gives the (already computed) Wn ^ k (= e ^ (2pi * i * k / n)).
- X * Notice that the powerseries of Wn has period Nfactors.
- X */
- X#define W(n, k) (W_factors [((k) * (Nfactors / (n))) % Nfactors])
- + END-OF-FILE fft/complex/w.h
- chmod 'u=rw,g=r,o=r' 'fft/complex/w.h'
- set `wc -c 'fft/complex/w.h'`
- count=$1
- case $count in
- 283) :;;
- *) echo 'Bad character count in ''fft/complex/w.h' >&2
- echo 'Count should be 283' >&2
- esac
- echo Extracting 'fft/complex.h'
- sed 's/^X//' > 'fft/complex.h' << '+ END-OF-FILE ''fft/complex.h'
- X/*
- X * "complex.h", Pjotr '87.
- X */
- X
- Xtypedef struct {
- X double re, im;
- X } COMPLEX;
- X#define c_re(c) ((c).re)
- X#define c_im(c) ((c).im)
- X
- X/*
- X * C_add_mul adds product of c1 and c2 to c.
- X */
- X#define c_add_mul(c, c1, c2) { COMPLEX C1, C2; C1 = (c1); C2 = (c2); \
- X c_re (c) += C1.re * C2.re - C1.im * C2.im; \
- X c_im (c) += C1.re * C2.im + C1.im * C2.re; }
- X
- X/*
- X * C_conj substitutes c by its complex conjugate.
- X */
- X#define c_conj(c) { c_im (c) = -c_im (c); }
- X
- X/*
- X * C_realdiv divides complex c by real.
- X */
- X#define c_realdiv(c, real) { c_re (c) /= (real); c_im (c) /= (real); }
- + END-OF-FILE fft/complex.h
- chmod 'u=rw,g=r,o=r' 'fft/complex.h'
- set `wc -c 'fft/complex.h'`
- count=$1
- case $count in
- 583) :;;
- *) echo 'Bad character count in ''fft/complex.h' >&2
- echo 'Count should be 583' >&2
- esac
- if test -f 'fft/example'
- then echo Removing 'fft/example'
- rm 'fft/example'
- fi
- if test -d 'fft/example'
- then :
- else echo Creating 'fft/example'
- mkdir 'fft/example'
- fi
- chmod 'u=rwx,g=rx,o=rx' 'fft/example'
- echo Extracting 'fft/example/README'
- sed 's/^X//' > 'fft/example/README' << '+ END-OF-FILE ''fft/example/README'
- XAn example of realfft(3) usage is in example.c. It contains two fourier
- Xtransforms on real data.
- X
- XCompile with:
- X cc example.c ../real/realfft.a ../complex/fft.a -lm
- + END-OF-FILE fft/example/README
- chmod 'u=rw,g=r,o=r' 'fft/example/README'
- set `wc -c 'fft/example/README'`
- count=$1
- case $count in
- 166) :;;
- *) echo 'Bad character count in ''fft/example/README' >&2
- echo 'Count should be 166' >&2
- esac
- echo Extracting 'fft/example/example.c'
- sed 's/^X//' > 'fft/example/example.c' << '+ END-OF-FILE ''fft/example/example.c'
- X/*
- X * Test for realfft(3).
- X */
- X
- X#define N 8
- X#define pi 3.1415926535897932384626434
- X
- Xdouble sin (), cos ();
- Xchar *malloc ();
- X
- Xmain ()
- X{
- X unsigned i, j;
- X
- X double in [N], out [N];
- X
- X printf ("Example #1:\n");
- X for (i = 0; i < N; i++)
- X in [i] = i;
- X printsamp (in, N);
- X
- X realfft (in, N, out);
- X printf ("After a fast fft\n");
- X printampl (out, N);
- X
- X /* check */
- X printf ("A reverse slow ft gives:\n");
- X srft (out, N, in);
- X printsamp (in, N);
- X
- X printf ("And the reverse fast ft yields:\n");
- X realrft (out, N, in);
- X printsamp (in, N);
- X
- X printf ("\n\nExample #2\n");
- X for (i = 0; i < N; i++) {
- X in [i] = 0;
- X for (j = 0; j <= N / 2; j++)
- X in [i] += cos (2 * pi * i * j / N) +
- X sin (2 * pi * i * j / N);
- X }
- X printsamp (in, N);
- X
- X realfft (in, N, out);
- X printf ("After a forward fast ft:\n");
- X printampl (out, N);
- X
- X /* check */
- X printf ("A reverse slow ft yields:\n");
- X srft (out, N, in);
- X printsamp (in, N);
- X
- X printf ("And a reverse fast ft gives:\n");
- X realrft (out, N, in);
- X printsamp (in, N);
- X}
- X
- Xprintampl (ampl, n)
- Xdouble *ampl;
- Xunsigned n;
- X{
- X unsigned i;
- X
- X printf ("Amplitudes\n");
- X
- X if (n == 0)
- X return;
- X
- X printf ("%f (dc)\n", ampl [0]);
- X for (i = 1; i < (n + 1) / 2; i++)
- X printf ("%f, %f (%u-th harmonic)\n", ampl [2 * i - 1],
- X ampl [2 * i], i);
- X if (n % 2 == 0)
- X printf ("%f (Nyquist)\n", ampl [n - 1]);
- X
- X printf ("\n");
- X}
- X
- Xprintsamp (samp, n)
- Xdouble *samp;
- Xunsigned n;
- X{
- X unsigned i;
- X printf ("Samples\n");
- X
- X for (i = 0; i < n; i++)
- X printf ("%f\n", samp [i]);
- X
- X printf ("\n");
- X}
- X
- X/*
- X * Slow reverse fourier transform. In [0] contains dc, in [n - 1] Nyquist.
- X * This is just a gimmick to compare with realfft(3).
- X */
- Xsrft (in, n, out)
- Xdouble *in;
- Xunsigned n;
- Xdouble *out;
- X{
- X unsigned i, j;
- X
- X for (i = 0; i < n; i++) {
- X out [i] = in [0]; /* dc */
- X for (j = 1; j < (n + 1) / 2; j++) /* j-th harmonic */
- X out [i] += in [2 * j - 1] * cos (2 * pi * i * j / n) +
- X in [2 * j] * sin (2 * pi * i * j / n);
- X if (n % 2 == 0) /* Nyquist */
- X out [i] += in [n - 1] * cos (2 * pi * i * j / n);
- X }
- X}
- + END-OF-FILE fft/example/example.c
- chmod 'u=rw,g=r,o=r' 'fft/example/example.c'
- set `wc -c 'fft/example/example.c'`
- count=$1
- case $count in
- 2026) :;;
- *) echo 'Bad character count in ''fft/example/example.c' >&2
- echo 'Count should be 2026' >&2
- esac
- if test -f 'fft/real'
- then echo Removing 'fft/real'
- rm 'fft/real'
- fi
- if test -d 'fft/real'
- then :
- else echo Creating 'fft/real'
- mkdir 'fft/real'
- fi
- chmod 'u=rwx,g=rx,o=rx' 'fft/real'
- echo Extracting 'fft/real/Makefile'
- sed 's/^X//' > 'fft/real/Makefile' << '+ END-OF-FILE ''fft/real/Makefile'
- XLTYPE=A18
- XTARGET=realfft.a
- XCFLAGS=-O
- XPREFLAGS=
- XIDIRS=-I../
- XLLIBS=
- X
- XLINT=lint -uhbaxc
- XCTAGS=ctags
- XPRINT=@pr -t
- X
- XCFILES=\
- X realfft.c
- XHFILES=\
- X ../complex.h
- XOBJECTS=\
- X realfft.o
- X
- X.SUFFIXES: .i
- X
- X$(TARGET): $(OBJECTS)
- X ar rv $@ $?
- X ranlib $@
- X
- Xlint:
- X $(LINT) $(PREFLAGS) $(IDIRS) $(CFILES) $(LLIBS) -lc
- X
- Xtags: $(HFILES) $(CFILES)
- X $(CTAGS) $(HFILES) $(CFILES)
- X
- Xprint: realfft.man
- X $(PRINT) realfft.man $(CFILES)
- X
- Xrealfft.man: realfft.3
- X @nroff -man realfft.3 > realfft.man
- X
- X.c.o:
- X $(CC) $(CFLAGS) -c $(IDIRS) $<
- X
- X.c.i:
- X $(CC) $(CFLAGS) -P $(IDIRS) $<
- X
- X.c.s:
- X $(CC) $(CFLAGS) -S $(IDIRS) $<
- X
- Xrealfft.o:\
- X ../complex.h
- + END-OF-FILE fft/real/Makefile
- chmod 'u=rw,g=r,o=r' 'fft/real/Makefile'
- set `wc -c 'fft/real/Makefile'`
- count=$1
- case $count in
- 611) :;;
- *) echo 'Bad character count in ''fft/real/Makefile' >&2
- echo 'Count should be 611' >&2
- esac
- echo Extracting 'fft/real/README'
- sed 's/^X//' > 'fft/real/README' << '+ END-OF-FILE ''fft/real/README'
- XThis realfft(3) package does Cooley-Tukey fast Fourier transform on an arbitrary
- Xnumber of real samples. It uses fft(3) for the actual complex transform.
- X
- XHow to make the stuff:
- X make - create library "realfft.a"
- X make fft.man - nroff manual page "realfft.3" into "realfft.man"
- X make print - print source and "realfft.man"
- X
- XPrograms using realfft(3), should be loaded (ld(1)) with libraries "realfft.a",
- X"../complex/fft.a" and "/usr/lib/libm.a". The package also uses malloc(3) of
- Xthe standard C-library.
- + END-OF-FILE fft/real/README
- chmod 'u=rw,g=r,o=r' 'fft/real/README'
- set `wc -c 'fft/real/README'`
- count=$1
- case $count in
- 508) :;;
- *) echo 'Bad character count in ''fft/real/README' >&2
- echo 'Count should be 508' >&2
- esac
- echo Extracting 'fft/real/realfft.3'
- sed 's/^X//' > 'fft/real/realfft.3' << '+ END-OF-FILE ''fft/real/realfft.3'
- X.TH REALFFT 3
- X.SH NAME
- Xrealfft, realrft \- forward and reverse real fourier transform
- X.SH SYNOPSIS
- X.nf
- Xrealfft (in, n, out)
- Xdouble *in;
- Xunsigned n;
- Xdouble *out;
- X
- Xrealrft (in, n, out)
- Xdouble *in;
- Xunsigned n;
- Xdouble *out;
- X.fi
- X.SH DESCRIPTION
- X.I Realfft
- Xand
- X.I realrft
- Xperform, respectively, forward and reverse discrete
- Xfast fourier transform on the
- X.I n
- X(an arbitrary number) reals
- Xof array
- X.IR in .
- XThe result (also
- X.I n
- Xreals) is placed in array
- X.IR out .
- XThe original contents of
- X.I in
- Xare not disturbed.
- X
- XThe format of the
- X.I out
- Xarray of
- X.I realfft
- Xand the
- X.I in
- Xarray of
- X.I realrft
- Xis as follows:
- XThe cosine component of the dc frequency is under index 0
- Xand the
- X.IR i -th
- Xharmonic's cosine and sine are under, respectively, index
- X2 *
- X.I i
- X- 1 and 2 *
- X.IR i .
- XIf
- X.I n
- Xis even then the cosine component of the
- XNyquist frequency is under index
- X.I n
- X- 1.
- XNote that the dc and Nyquist sine components need not be passed, since they
- Xare always 0.
- X
- XThe actual transform is done by
- X.IR fft (3)
- Xin complex space.
- X.SH "SEE ALSO"
- Xfft(3)
- X.SH FILES
- Xrealfft.a \- contains realfft and realrft.
- X.br
- Xfft.a \- library used by realfft.a.
- X.br
- X/usr/lib/libm.a \- library used by fft.a.
- X.SH DIAGNOSTICS
- X.I Realfft
- Xand
- X.I realrft
- Xreturn -1 if routines in
- X.IR fft (3)
- Xfail, else 0.
- X.SH BUGS
- XThe error for a forward-reverse sequence is about 1e-13 for
- X.I n
- X= 1024.
- X.SH AUTHOR
- XPeter Valkenburg (valke@cs.vu.nl)
- + END-OF-FILE fft/real/realfft.3
- chmod 'u=rw,g=r,o=r' 'fft/real/realfft.3'
- set `wc -c 'fft/real/realfft.3'`
- count=$1
- case $count in
- 1391) :;;
- *) echo 'Bad character count in ''fft/real/realfft.3' >&2
- echo 'Count should be 1391' >&2
- esac
- echo Extracting 'fft/real/realfft.c'
- sed 's/^X//' > 'fft/real/realfft.c' << '+ END-OF-FILE ''fft/real/realfft.c'
- X/*
- X * "realfft.c", Pjotr '87
- X */
- X
- X/*
- X * Bevat funkties realfft en realrft die resp. forward en reverse fast fourier
- X * transform op reele samples doen. Gebruikt pakket fft(3).
- X */
- X
- X#include <complex.h>
- X
- Xchar *malloc ();
- X
- X/*
- X * Reele forward fast fourier transform van n samples van in naar
- X * amplitudes van out.
- X * De cosinus komponent van de dc komt in out [0], dan volgen in
- X * out [2 * i - 1] en out [2 * i] steeds resp. de cosinus en sinus
- X * komponenten van de i-de harmonische. Bij een even aantal samples
- X * bevat out [n - 1] de cosinus komponent van de Nyquist frequentie.
- X * Extraatje: Na afloop is in onaangetast.
- X */
- Xrealfft (in, n, out)
- Xdouble *in;
- Xunsigned n;
- Xdouble *out;
- X{
- X COMPLEX *c_in, *c_out;
- X unsigned i;
- X
- X if (n == 0 ||
- X (c_in = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0 ||
- X (c_out = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
- X return;
- X
- X for (i = 0; i < n; i++) {
- X c_re (c_in [i]) = in [i];
- X c_im (c_in [i]) = 0;
- X }
- X
- X fft (c_in, n, c_out);
- X
- X out [0] = c_re (c_out [0]); /* cos van dc */
- X for (i = 1; i < (n + 1) / 2; i++) { /* cos/sin i-de harmonische */
- X out [2 * i - 1] = c_re (c_out [i]) * 2;
- X out [2 * i] = c_im (c_out [i]) * -2;
- X }
- X if (n % 2 == 0) /* cos van Nyquist */
- X out [n - 1] = c_re (c_out [n / 2]);
- X
- X free ((char *) c_in);
- X free ((char *) c_out);
- X}
- X
- X/*
- X * Reele reverse fast fourier transform van amplitudes van in naar
- X * n samples van out.
- X * De cosinus komponent van de dc staat in in [0], dan volgen in
- X * in [2 * i - 1] en in [2 * i] steeds resp. de cosinus en sinus
- X * komponenten van de i-de harmonische. Bij een even aantal samples
- X * bevat in [n - 1] de cosinus komponent van de Nyquist frequentie.
- X * Extraatje: Na afloop is in onaangetast.
- X */
- Xrealrft (in, n, out)
- Xdouble *in;
- Xunsigned n;
- Xdouble *out;
- X{
- X COMPLEX *c_in, *c_out;
- X unsigned i;
- X
- X if (n == 0 ||
- X (c_in = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0 ||
- X (c_out = (COMPLEX *) malloc (n * sizeof (COMPLEX))) == 0)
- X return;
- X
- X c_re (c_in [0]) = in [0]; /* dc */
- X c_im (c_in [0]) = 0;
- X for (i = 1; i < (n + 1) / 2; i++) { /* geconj. symm. harmonischen */
- X c_re (c_in [i]) = in [2 * i - 1] / 2;
- X c_im (c_in [i]) = in [2 * i] / -2;
- X c_re (c_in [n - i]) = in [2 * i - 1] / 2;
- X c_im (c_in [n - i]) = in [2 * i] / 2;
- X }
- X if (n % 2 == 0) { /* Nyquist */
- X c_re (c_in [n / 2]) = in [n - 1];
- X c_im (c_in [n / 2]) = 0;
- X }
- X
- X rft (c_in, n, c_out);
- X
- X for (i = 0; i < n; i++)
- X out [i] = c_re (c_out [i]);
- X
- X free ((char *) c_in);
- X free ((char *) c_out);
- X}
- + END-OF-FILE fft/real/realfft.c
- chmod 'u=rw,g=r,o=r' 'fft/real/realfft.c'
- set `wc -c 'fft/real/realfft.c'`
- count=$1
- case $count in
- 2503) :;;
- *) echo 'Bad character count in ''fft/real/realfft.c' >&2
- echo 'Count should be 2503' >&2
- esac
- exit 0
-
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
-