/*============================================================================= | | NAME | | testFFT.cpp | | DESCRIPTION | | Test program for fft.cpp | | AUTHOR | | Sean O'Connor | | LEGAL | | FFT Version 1.2 - An FFT utility in C++. | Copyright (C) 2005-2008 by Sean Erik O'Connor. All Rights Reserved. | | This program is free software; you can redistribute it and/or | modify it under the terms of the GNU General Public License | as published by the Free Software Foundation; version 2 | of the License. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with this program; if not, write to the Free Software | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | | The author's address is artifex@seanerikoconnor.freeservers.com. | +============================================================================*/ /*------------------------------------------------------------------------------ | Include Files | ------------------------------------------------------------------------------*/ #include // Basic stream I/O. #include // Basic math functions. #include // Complex data type and operations. #include // STL vector class. #include // File stream I/O. #include // Iterators. #include // STL string class. #include // Exceptions. using namespace std ; // Let us omit the std:: prefix for every STL class. #include "fft.h" // Our own FFT stuff. string legalNotice ( "\n" "FFT Version 1.2 - An FFT utility in C++.\n" "Copyright (C) 2005-2008 by Sean Erik O'Connor. All Rights Reserved.\n" "\n" "FFT comes with ABSOLUTELY NO WARRANTY; for details see the\n" "GNU General Public License. This is free software, and you are welcome\n" "to redistribute it under certain conditions; see the GNU General Public License\n" "for details.\n\n" ) ; /*============================================================================= | | NAME | | main | | DESCRIPTION | | This program tests the FFT implementation by performing forward and | inverse transforms on the data and testing error conditions. | | INPUT | | File containing | | - Number of complex points in the transform. | - The data points (complex numbers). | | OUTPUT | | - DFT of the input. | - inverse DFT of the first DFT. | | EXAMPLE | | From the command line, call | | $ FastFourierTransform fftIn.txt fftOut.txt | | where the input file fftIn.txt contains | | 4 | (1, 1) | (2, 2) | (3, 3) | (4, 4) | | and the output file fftOut.txt contains | | num_points = 4 | Point num. 0= (1,1) | Point num. 1= (2,2) | Point num. 2= (3,3) | Point num. 3= (4,4) | The transform of the input data is . . . | | Point num. 0 = (5,5) | Point num. 1 = (-2,-1.11022e-016) | Point num. 2 = (-1,-1) | Point num. 3 = (0,-2) | The inverse transform of the transform above is . . . | | Point num. 0 = (1,1) | Point num. 1 = (2,2) | Point num. 2 = (3,3) | Point num. 3 = (4,4) | Point num. 0 = (1,1) | Point num. 1 = (2,2) | Point num. 2 = (3,3) | Point num. 3 = (4,4) | | Calling FFT with too many points. | FFT has too many points for its sin/cos table | +============================================================================*/ int main( int argc, char * argv[] ) { cout << legalNotice ; int num_points = 0 ; // Number of points in the transform. int i = 0 ; // Open file streams for input and output getting file names // from the command line. if (argc != 3) { cout << "Error: Missing the names of the input and output " "files or too many files on the command line." ; return 1 ; } char * inputFileName = argv[ 1 ] ; char * outputFileName = argv[ 2 ] ; fstream fin ( inputFileName, ios::in ) ; fstream fout( outputFileName, ios::out ) ; if (!(fin.is_open() && fout.is_open())) { cout << "Error: Problem opening the input or output files. " "Check the file names and permissions." ; return 1 ; } try { // Create our DFT object. FastFourierTransform dft ; // Read lines until end of file. while (!fin.eof()) { // Clear the fft object. dft.clear() ; // Read the number of points in the transform. fin >> num_points ; // Check to see that the number of points in the FFT is valid. if (num_points <= 0) throw FastFourierTransformException( "The number of points is out of range.\n" ) ; // Read in the complex data points from file into the vector. for (i = 0 ; i < num_points ; ++i) { complex c ; fin >> c ; dft.push_back( c ) ; } // Print out the points just read in. fout << "\n\n\nNumber of points = " << num_points << endl ; for (i = 0 ; i <= num_points - 1 ; ++i) fout << "Point num. " << i << "= " << dft[ i ] << endl ; // Try a forward FFT. dft.fft( true ) ; // Print the transform results. fout << "The discrete Fourier transform of the input data is . . . \n\n" ; for (i = 0 ; i <= num_points - 1 ; ++i) fout << "Point num. " << i << " = " << dft[ i ] << endl ; // Try an inverse transform to get the input data back, with roundoff error. dft.fft( false ) ; // Print the inverse transform. fout << "The inverse transform of the transform above is . . .\n\n" ; for (i = 0 ; i <= num_points - 1 ; ++i) fout << "Point num. " << i << " = " << dft[ i ] << endl ; // Check out a copy constructor. fout << "\n\nTest the copy constructor" << endl ; FastFourierTransform copy_of_dft( dft ) ; for (i = 0 ; i <= num_points - 1 ; ++i) fout << "Point num. " << i << " = " << copy_of_dft[ i ] << endl ; // Make sure we get all the data to file, when we're debugging. fout << flush ; } // Test error conditions. Only the first will execute due to // the throw, so comment out and recompile to test them all. // Number of points is less than 2. fout << "\n\nCalling FFT with 1 point.\n" ; FastFourierTransform dft2 ; dft.push_back( complex(1.0, 2.0) ) ; dft2.fft( true ) ; } // Catch exceptions and print their text explanations. // Clean up resources. catch( FastFourierTransformException & e ) { fout << "FFT exception: " << e.what() << endl ; fin.close() ; fout.close() ; return 1 ; } catch( runtime_error & e ) { fout << "Unexpected runtime exception: Please email the author." << e.what() << endl ; return 1 ; } catch( ... ) { fout << "Unexpected exception: Please email the author." << endl ; return 1 ; } // Clean up resources. fin.close() ; fout.close() ; return 0 ; } /* ====================== end of function main ============================ */