home *** CD-ROM | disk | FTP | other *** search
- program FFTPrograms;
-
- {----------------------------------------------------------------------------}
- {- -}
- {- Turbo Pascal Numerical Methods Toolbox -}
- {- Copyright (c) 1986, 87 by Borland International, Inc. -}
- {- -}
- {- Purpose: This procedure provides I/O routines for using the -}
- {- fast Fourier transform, convolution and correlation -}
- {- routines. -}
- {- -}
- {- Unit : FFT????.TPU procedure MakeSinCosTable -}
- {- BitInvert -}
- {- FFT -}
- {- procedure RealFFT -}
- {- procedure RealConvolution -}
- {- procedure RealCorrelation -}
- {- procedure ComplexFFT -}
- {- procedure ComplexConvolution -}
- {- procedure ComplexCorrelation -}
- {- -}
- {----------------------------------------------------------------------------}
-
- {$I-} { Disable I/O error trapping }
-
- uses
- FFTB2, Dos, Crt, Common;
-
- type
- Analyses = (RF, RN, RC, RA, CF, CN, CC, CA);
-
- var
- WhichAnalysis : Analyses; { Indicates which application }
- { will be run }
- NumPoints : integer; { Number of points }
- XReal, XImag : TNvectorPtr; { One set of complex data points }
- HReal, HImag : TNvectorPtr; { Another set of complex data points }
- Inverse : boolean; { False ==> forward Fourier transform }
- { True ===> inverse Fourier transform }
- Auto : boolean; { False ==> crosscorrelation }
- { True ===> autocorrelation }
- Error : byte; { Flags if something went wrong }
-
- procedure Initialize(var NumPoints : integer;
- var XReal : TNvectorPtr;
- var XImag : TNvectorPtr;
- var HReal : TNvectorPtr;
- var HImag : TNvectorPtr;
- var Error : byte);
-
- {----------------------------------------------------------}
- {- Output: NumPoints, XReal, XImag, HReal, HImag, Error -}
- {- -}
- {- This procedure initializes the above variables to zero -}
- {----------------------------------------------------------}
-
- begin
- NumPoints := 0;
- New(XReal);
- New(XImag);
- New(HReal);
- New(HImag);
- FillChar(XReal^, SizeOf(XReal^), 0);
- FillChar(XImag^, SizeOf(XImag^), 0);
- FillChar(HReal^, SizeOf(HReal^), 0);
- FillChar(HImag^, SizeOf(HImag^), 0);
- Error := 0;
- end; { procedure Initialize }
-
- procedure GetData(var NumPoints : integer;
- var WhichAnalysis : Analyses;
- var Auto : boolean;
- var XReal : TNvectorPtr;
- var XImag : TNvectorPtr;
- var HReal : TNvectorPtr;
- var HImag : TNvectorPtr);
-
- {--------------------------------------------------------------}
- {- Output: NumPoints, WhichAnalysis, Auto, XReal, XImag, -}
- {- HReal, HImag -}
- {- -}
- {- This procedure reads in data from either the keyboard -}
- {- or a data file. -}
- {--------------------------------------------------------------}
-
- var
- Ch : char;
- NumPoints1 : integer;
- NumPoints2 : integer;
-
- function TestForPowersOfTwo(NumPoints : integer) : boolean;
-
- {---------------------------------------------------------}
- {- Input: NumPoints -}
- {- Output: TestForPowersOfTwo -}
- {- -}
- {- This procedure checks if NumPoints is a power of two. -}
- {- It returns True if it is, False if it isn't. -}
- {---------------------------------------------------------}
-
- type
- ShortArray = array[1..13] of integer;
-
- const
- PowersOfTwo : ShortArray = (2, 4, 8, 16, 32, 64, 128, 256,
- 512, 1024, 2048, 4096, 8192);
-
- var
- Term : integer;
- Test : boolean;
-
- begin
- Test := false; { Assume NumPoints not a power of two }
- Term := 1;
- while (Term <= 13) and (not Test) do
- begin
- if NumPoints = PowersOfTwo[Term] then
- Test := true; { NumPoints is a power of two }
- Term := Succ(Term);
- end;
- TestForPowersOfTwo := Test;
- end; { function TestForPowersOfTwo }
-
- procedure GetRealVectorFromFile(var NumPoints : integer;
- var XReal : TNvectorPtr);
-
- {-----------------------------------------------}
- {- Output: NumPoints, X -}
- {- -}
- {- This procedure reads in a real vector of -}
- {- data points from a data file. -}
- {-----------------------------------------------}
-
- var
- FileName : string[255];
- InFile : text;
-
- begin
- Writeln;
- repeat
- Write('File name? ');
- Readln(FileName);
- Assign(InFile, FileName);
- Reset(InFile);
- IOCheck;
- until not IOerr ;
- NumPoints := 0;
- while not EOF(InFile) do
- begin
- Readln(InFile, XReal^[NumPoints]);
- NumPoints := Succ(NumPoints);
- IOCheck;
- end;
- Close(InFile);
- end; { procedure GetRealVectorFromFile }
-
- procedure GetComplexVectorFromFile(var NumPoints : integer;
- var XReal : TNvectorPtr;
- var XImag : TNvectorPtr);
-
- {-----------------------------------------------}
- {- Output: NumPoints, XReal, XImag -}
- {- -}
- {- This procedure reads in a complex vector -}
- {- of data points from a data file. -}
- {-----------------------------------------------}
-
- var
- FileName : string[255];
- InFile : text;
-
- begin
- Writeln;
- repeat
- Write('File name? ');
- Readln(FileName);
- Assign(InFile, FileName);
- Reset(InFile);
- IOCheck;
- until not IOerr;
- NumPoints := 0;
- while not EOF(InFile) do
- begin
- Readln(InFile, XReal^[NumPoints], XImag^[NumPoints]);
- NumPoints := Succ(NumPoints);
- IOCheck;
- end;
- Close(InFile);
- end; { procedure GetComplexVectorFromFile }
-
- procedure GetRealVectorFromKeyboard(var NumPoints : integer;
- var XReal : TNvectorPtr);
-
- {----------------------------------------------}
- {- Output: NumPoints, X -}
- {- -}
- {- This procedure reads in a real vector of -}
- {- data points from the keyboard. -}
- {----------------------------------------------}
-
- var
- Term : integer;
-
- begin
- NumPoints := 0;
- Writeln;
- repeat
- Write('Number of points (a power of two between 2-', TNArraySize + 1,')? ');
- Readln(NumPoints);
- IOCheck;
- IOerr := not TestForPowersOfTwo(NumPoints);
- until (NumPoints >= 2) and (NumPoints <= TNArraySize + 1) and not IOerr;
- Writeln;
- Writeln('Type in the X values:');
- for Term := 0 to NumPoints - 1 do
- repeat
- Write('Real(X[', Term, ']): ');
- Readln(XReal^[Term]);
- IOCheck;
- until not IOerr;
- end; { procedure GetRealVectorFromKeyboard }
-
- procedure GetComplexVectorFromKeyboard(var NumPoints : integer;
- var XReal : TNvectorPtr;
- var XImag : TNvectorPtr);
-
- {-----------------------------------------------}
- {- Output: NumPoints, XReal, XImag -}
- {- -}
- {- This procedure reads in a complex vector of -}
- {- data points from the keyboard. -}
- {-----------------------------------------------}
-
- var
- Term : integer;
-
- begin
- NumPoints := 0;
- repeat
- Write('Number of points (a power of two between 2-', TNArraySize + 1,')? ');
- Readln(NumPoints);
- IOCheck;
- IOerr := not TestForPowersOfTwo(NumPoints);
- until (NumPoints >= 2) and (NumPoints <= TNArraySize + 1) and not IOerr;
- Writeln;
- Writeln('Type in the X values:');
- for Term := 0 to NumPoints - 1 do
- begin
- repeat
- Write('Real(X[', Term, ']): ');
- Readln(XReal^[Term]);
- IOCheck;
- until not IOerr;
- repeat
- Write('Imaginary(X[', Term, ']): ');
- Readln(XImag^[Term]);
- IOCheck;
- until not IOerr;
- end;
- end; { procedure GetComplexVectorFromKeyboard }
-
- procedure GetInverse(var Inverse : boolean);
-
- var
- Ch : char;
-
- begin
- Writeln;
- Write('(F)orward or (I)nverse transform? ');
- repeat
- Ch := UpCase(ReadKey);
- until Ch in ['F', 'I'];
- Writeln(Ch);
- if Ch = 'F' then
- Inverse := false { Forward transform }
- else
- Inverse := true; { Inverse transform }
- end; { procedure GetInverse }
-
- begin { procedure GetData }
- Writeln(' 1) Real Fast Fourier Transform');
- Writeln(' 2) Real Convolution');
- Writeln(' 3) Real Autocorrelation');
- Writeln(' 4) Real Crosscorrelation');
- Writeln(' 5) Complex Fast Fourier Transform');
- Writeln(' 6) Complex Convolution');
- Writeln(' 7) Complex Autocorrelation');
- Writeln(' 8) Complex Crosscorrelation');
- Writeln;
- Write(' Select a number (1-8): ');
- repeat
- Ch := ReadKey;
- until Ch in ['1'..'8'];
-
- Writeln;
- case Ch of
- '1' : begin
- Writeln('********* Real fast Fourier transform *********');
- GetInverse(Inverse);
- WhichAnalysis := RF;
- end;
-
- '2' : begin
- Writeln('********* Real Convolution *********');
- WhichAnalysis := RN;
- end;
-
- '3' : begin
- Writeln('********* Real Autocorrelation *********');
- Auto := true; { Autocorrelation }
- WhichAnalysis := RA;
- end;
-
- '4' : begin
- Writeln('********* Real Crosscorrelation *********');
- Auto := false; { Crosscorrelation }
- WhichAnalysis := RC;
- end;
-
- '5' : begin
- Writeln('********* Complex fast Fourier transform *********');
- GetInverse(Inverse);
- WhichAnalysis := CF;
- end;
-
- '6' : begin
- Writeln('********* Complex Convolution *********');
- WhichAnalysis := CN;
- end;
-
- '7' : begin
- Writeln('********* Complex Autocorrelation *********');
- Auto := true; { Autocorrelation }
- WhichAnalysis := CA;
- end;
-
- '8' : begin
- Writeln('********* Complex Crosscorrelation *********');
- Auto := false; { Crosscorrelation }
- WhichAnalysis := CC;
- end;
- end; { case }
-
- Writeln;
- Ch := InputChannel('Input Data From');
- if Ch = 'K' then
- repeat { Until NumPoints1 := NumPoints2 }
- NumPoints1 := NumPoints2;
- case WhichAnalysis of
- RF, RA : GetRealVectorFromKeyboard(NumPoints, XReal);
-
- RN, RC : begin
- Writeln;
- Writeln('The first function:');
- GetRealVectorFromKeyboard(NumPoints1, XReal);
- Writeln;
- Writeln('The 2nd function:');
- GetRealVectorFromKeyboard(NumPoints2, HReal);
- if NumPoints1 <> NumPoints2 then
- begin
- Writeln;
- Write('The number of points in these two files');
- Writeln(' are different.');
- end;
- NumPoints := NumPoints1;
- end;
-
- CF, CA : GetComplexVectorFromKeyboard(NumPoints, XReal, XImag);
-
- CN, CC : begin
- Writeln;
- Writeln('The first function:');
- GetComplexVectorFromKeyboard(NumPoints1, XReal, XImag);
- Writeln;
- Writeln('The 2nd function:');
- GetComplexVectorFromKeyboard(NumPoints2, HReal, HImag);
- if NumPoints1 <> NumPoints2 then
- begin
- Writeln;
- Write('The number of points in these two files');
- Writeln(' are different.');
- end;
- NumPoints := NumPoints1;
- end;
- end { case }
- until NumPoints1 = NumPoints2
- else { Ch = 'F' }
- repeat
- NumPoints2 := NumPoints1;
- case WhichAnalysis of
- RF, RA : GetRealVectorFromFile(NumPoints, XReal);
-
- RN, RC : begin
- Writeln;
- Writeln('The first function:');
- GetRealVectorFromFile(NumPoints1, XReal);
- Writeln;
- Writeln('The 2nd function:');
- GetRealVectorFromFile(NumPoints2, HReal);
- if NumPoints1 <> NumPoints2 then
- begin
- Writeln;
- Write('The number of points in these two files');
- Writeln(' are different.');
- end;
- NumPoints := NumPoints1;
- end;
-
- CF, CA : GetComplexVectorFromFile(NumPoints, XReal, XImag);
-
- CN, CC : begin
- Writeln;
- Writeln('The first function:');
- GetComplexVectorFromFile(NumPoints1, XReal, XImag);
- Writeln;
- Writeln('The 2nd function:');
- GetComplexVectorFromFile(NumPoints2, HReal, HImag);
- if NumPoints1 <> NumPoints2 then
- begin
- Writeln;
- Write('The number of points in these two files');
- Writeln(' are different.');
- end;
- NumPoints := NumPoints1;
- end;
- end; { case }
- until NumPoints1 = NumPoints2;
- GetOutputFile(OutFile);
- end; { procedure GetData }
-
- procedure Results(NumPoints : integer;
- WhichAnalysis : Analyses;
- var XReal : TNvectorPtr;
- var XImag : TNvectorPtr;
- Error : byte);
-
- {------------------------------------------------------------}
- {- This procedure outputs the results to the device OutFile -}
- {------------------------------------------------------------}
-
- var
- Index : integer;
-
- begin
- Writeln(OutFile);
- Writeln(OutFile);
- if Error >= 1 then
- DisplayError;
-
- case Error of
- 0 : begin
- case WhichAnalysis of
- RF : Writeln(OutFile, 'Results of real Fourier transform:');
- RN : Writeln(OutFile, 'Results of real convolution:');
- RC : Writeln(OutFile, 'Results of real crosscorrelation:');
- RA : Writeln(OutFile, 'Results of real autocorrelation:');
- CF : Writeln(OutFile, 'Results of complex Fourier transform:');
- CN : Writeln(OutFile, 'Results of complex convolution:');
- CC : Writeln(OutFile, 'Results of complex crosscorrelation:');
- CA : Writeln(OutFile, 'Results of complex autocorrelation:');
- end; { case }
-
- for Index := 0 to NumPoints - 1 do
- Writeln(OutFile, XReal^[Index], ' ', XImag^[Index]);
- Writeln;
- end;
-
- 1 : begin
- Writeln(OutFile, 'The number of data points: ', NumPoints);
- Writeln(OutFile, 'There are too few data points.');
- end;
-
- 2 : begin
- Writeln(OutFile, 'The number of data points: ', NumPoints);
- Writeln(OutFile,
- 'The number of data points must be a power of two for a');
- Writeln(OutFile,
- 'radix-2 transform or a power of four for a radix-4 transform.');
- end;
- end; { case }
- end; { procedure Results }
-
- begin { program FFTPrograms }
- ClrScr;
- Initialize(NumPoints, XReal, XImag, HReal, HImag, Error);
- GetData(NumPoints, WhichAnalysis, Auto, XReal, XImag, HReal, HImag);
-
- case WhichAnalysis of
- RF : RealFFT(NumPoints, Inverse, XReal, XImag, Error);
- RN : RealConvolution(NumPoints, XReal, XImag, HReal, Error);
- RC : RealCorrelation(NumPoints, Auto, XReal, XImag, HReal, Error);
- RA : RealCorrelation(NumPoints, Auto, XReal, XImag, XReal, Error);
- CF : ComplexFFT(NumPoints, Inverse, XReal, XImag, Error);
- CN : ComplexConvolution(NumPoints, XReal, XImag, HReal, HImag, Error);
- CC : ComplexCorrelation(NumPoints, Auto, XReal, XImag,
- HReal, HImag, Error);
- CA : ComplexCorrelation(NumPoints, Auto, XReal, XImag,
- XReal, XImag, Error);
- end; { case }
-
- Results(NumPoints, WhichAnalysis, XReal, XImag, Error);
- Close(OutFile);
- Dispose(XReal);
- Dispose(XImag);
- Dispose(HReal);
- Dispose(HImag);
- end. { program FFTPrograms }