📄 ft_02.cc
字号:
// file: $isip/class/algo/FourierTransform/ft_02.cc// version: $Id: ft_02.cc,v 1.18 2002/07/08 00:14:39 picone Exp $//// isip include files//#include "FourierTransform.h"#include <Console.h>// method: diagnose//// arguments:// Integral::DEBUG level: (input) debug level for diagnostics.//// return: a boolean value indicating status//boolean FourierTransform::diagnose(Integral::DEBUG level_a) { // --------------------------------------------------------------------- // // 0. preliminaries // // --------------------------------------------------------------------- // output the class name // if (level_a > Integral::NONE) { String output(L"diagnosing class "); output.concat(CLASS_NAME); output.concat(L": "); Console::put(output); Console::increaseIndention(); } // -------------------------------------------------------------------- // // 1. required public methods // // -------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods...\n"); Console::increaseIndention(); } // test destructor/constructor(s) and memory management // FourierTransform ft0; ft0.setAlgorithm(FourierTransform::DFT); ft0.setImplementation(FourierTransform::CONVENTIONAL); ft0.setDirection(FourierTransform::FORWARD); FourierTransform ft1(ft0); if (!ft1.eq(ft0)) { return Error::handle(name(), L"copy constructor", Error::TEST, __FILE__, __LINE__); } // test large allocation construction and deletion // if (level_a == Integral::ALL) { Console::put(L"\ntesting large chunk memory allocation and deletion:\n"); // set the memory to a strange block size so we can hopefully catch any // frame overrun errors // FourierTransform::setGrowSize((long)500); FourierTransform* pft = new FourierTransform(); for (long j = 1; j <= 100; j++) { FourierTransform** pfts = new FourierTransform*[j * 100]; // create the objects // for (long i = 0; i < j * 100; i++) { pfts[i] = new FourierTransform(); } // delete objects // for (long i = (j * 100) - 1; i >= 0; i--) { delete pfts[i]; } delete [] pfts; } delete pft; } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 2. required public methods // i/o methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods: i/o methods...\n"); Console::increaseIndention(); } // test the i/o methods // FourierTransform ft2; ft0.set(DCT, TYPE_III, INVERSE, FULL, FIXED, 256); // we need binary and text sof files // String tmp_filename0; Integral::makeTemp(tmp_filename0); String tmp_filename1; Integral::makeTemp(tmp_filename1); // open files in write mode // Sof tmp_file0; tmp_file0.open(tmp_filename0, File::WRITE_ONLY, File::TEXT); Sof tmp_file1; tmp_file1.open(tmp_filename1, File::WRITE_ONLY, File::BINARY); ft0.write(tmp_file0, (long)0); ft0.write(tmp_file1, (long)0); // close the files // tmp_file0.close(); tmp_file1.close(); // open the files in read mode // tmp_file0.open(tmp_filename0); tmp_file1.open(tmp_filename1); // read the value back // if (!ft1.read(tmp_file0, (long)0) || (ft1.getAlgorithm() != ft0.getAlgorithm()) || (ft1.getImplementation() != ft0.getImplementation())) { return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__); } if (!ft2.read(tmp_file0, (long)0) || (ft2.getAlgorithm() != ft0.getAlgorithm()) || (ft2.getImplementation() != ft0.getImplementation())) { return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__); } // close and delete the temporary files // tmp_file0.close(); tmp_file1.close(); File::remove(tmp_filename0); File::remove(tmp_filename1); // test the conditional i/o methods // Sof tmp_file2; String tmp_filename2; Integral::makeTemp(tmp_filename2); tmp_file2.open(tmp_filename2, File::WRITE_ONLY); tmp_file2.put(CLASS_NAME, 5, -1); String line; line.assign(L"implementation = CONVENTIONAL;\n"); tmp_file2.puts(line); // close the file // tmp_file2.close(); // open the file in read mode // tmp_file2.open(tmp_filename2); ft0.read(tmp_file2, (long)5); if (ft0.getImplementation() != CONVENTIONAL) { return Error::handle(name(), L"readData", Error::TEST, __FILE__, __LINE__); } // close and delete the temporary files // tmp_file2.close(); File::remove(tmp_filename2); // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //--------------------------------------------------------------------------- // // 3. class-specific public methods: // set and get methods // //--------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: set and get methods...\n"); Console::increaseIndention(); } // establish an object // ft0.setAlgorithm(FourierTransform::FFT); ft0.setImplementation(FourierTransform::QF); ft0.setDirection(FourierTransform::INVERSE); ft0.setOutputType(FourierTransform::SYMMETRIC); ft0.setResolution(FourierTransform::FIXED); ft0.setNormalization(FourierTransform::UNIT_ENERGY); // check that the values were set // if (ft0.algorithm_d != FFT) { return Error::handle(name(), L"setAlgorithm", Error::TEST, __FILE__, __LINE__); } else if (ft0.implementation_d != QF) { return Error::handle(name(), L"setImplementation", Error::TEST, __FILE__, __LINE__); } else if (ft0.direction_d != INVERSE) { return Error::handle(name(), L"setDirection", Error::TEST, __FILE__, __LINE__); } else if (ft0.otype_d != SYMMETRIC) { return Error::handle(name(), L"setOutputType", Error::TEST, __FILE__, __LINE__); } else if (ft0.resolution_d != FIXED) { return Error::handle(name(), L"setResolution", Error::TEST, __FILE__, __LINE__); } else if (ft0.normalization_d != UNIT_ENERGY) { return Error::handle(name(), L"setNormalization", Error::TEST, __FILE__, __LINE__); } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 4. class-specific public methods: // computation methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods: computation methods...\n"); Console::increaseIndention(); } // setup variables for loop structure // ALGORITHM forward_algo[] = { DFT, DFT, FFT, FFT, FFT, FFT, FFT, FFT }; IMPLEMENTATION forward_impl[] = { CONVENTIONAL, TRIGONOMETRIC, SPLIT_RADIX, RADIX_2, RADIX_4, DITF, FAST_HARTLEY, QF }; ALGORITHM inverse_algo[] = { DFT, DFT, FFT, FFT, FFT, FFT, FFT, FFT }; IMPLEMENTATION inverse_impl[] = { CONVENTIONAL, TRIGONOMETRIC, SPLIT_RADIX, RADIX_2, RADIX_4, DITF, FAST_HARTLEY, QF }; long data_lengths[] = { 16, 64, 256, 1024, 16384 }; long desired_lengths[] = { 64, 16, 256, 16384, 1024 }; long num_impls = 8; long num_inverse_impls = 8; long num_lengths = 5; // if this is a brief debugging mode then only do the bare minimum testing // if (level_a <= Integral::BRIEF) { num_impls = 2; num_inverse_impls = 2; num_lengths = 3; data_lengths[0] = 64; data_lengths[1] = 1024; data_lengths[2] = 16384; desired_lengths[0] = 16384; desired_lengths[1] = 64; desired_lengths[2] = 1024; } // setup minimum dB precisions // double min_float_prec = 110.0; ft0.setAlgorithm(DFT); // check the assign and equality methods // FourierTransform ft4(ft0); ft1.assign(ft0); if (!(ft1.eq(ft0)) || (!ft4.eq(ft0))) { Error::handle(name(), L"eq", Error::TEST, __FILE__, __LINE__); } // loop where dft is used rather than zero-padding // if (level_a > Integral::BRIEF) { Console::put(L"\ntesting implementations. running randomized data through a"); Console::put(L"forward transform and then inverting. if the SNRs"); Console::put(L"between the input and inverse are less than 80dB for"); Console::put(L"floats then the test fails. the DFT is used for "); Console::put(L"transforms where the size is incompatible\n"); } // create a block for floats // // create a temporary FourierTransform object for computation // FourierTransform ft5; ft5.setResolution(FourierTransform::AUTO); // setup vectors for holding data // VectorFloat real_input_vector; real_input_vector.setCapacity(data_lengths[num_lengths - 1]); VectorComplexFloat complex_input_vector; complex_input_vector.setCapacity(data_lengths[num_lengths - 1]); VectorComplexFloat freq_vector; freq_vector.setCapacity(data_lengths[num_lengths - 1]); VectorComplexFloat inverse_vector; inverse_vector.setCapacity(data_lengths[num_lengths - 1]); VectorFloat real_inverse_vector; real_inverse_vector.setCapacity(data_lengths[num_lengths - 1]); VectorFloat real_diff_vector; real_diff_vector.setCapacity(data_lengths[num_lengths - 1]); VectorComplexFloat complex_diff_vector; complex_diff_vector.setCapacity(data_lengths[num_lengths - 1]); // loop over the different data lengths // for (long length_ind = 0; length_ind < num_lengths; length_ind++) { long curr_length = data_lengths[length_ind]; // clear all of the data arrays and start over // real_input_vector.setLength(curr_length, false); complex_input_vector.setLength(curr_length, false); // loop over zero, constant and random test data type // for (long test_data_type = 0; test_data_type < 3; test_data_type++) { // generate zero input data // if (test_data_type == 0) { real_input_vector.assign(curr_length, (float)0.0); ComplexFloat c_zero(0.0); complex_input_vector.assign(curr_length, c_zero); } // generate const input data // else if (test_data_type == 1) { real_input_vector.assign(curr_length, (float)1.0); ComplexFloat c_one(1.0); complex_input_vector.assign(curr_length, c_one); } // generate random input data // else if (test_data_type == 2) { real_input_vector.rand(); complex_input_vector.rand(); } // loop over the different implementation types for doing the forward // transform // for (long forward_ind = 0; forward_ind < num_impls; forward_ind++) { // set the forward transform algorithm and implementation // for this pass // ALGORITHM curr_forward_algo = forward_algo[forward_ind]; IMPLEMENTATION curr_forward_impl = forward_impl[forward_ind]; // loop over the different implementation types for doing // the inverse transform // for (long inverse_ind = 0; inverse_ind < num_inverse_impls; inverse_ind++) { // set the inverse transform algorithm and // implementation for this pass // ALGORITHM curr_inverse_algo = inverse_algo[inverse_ind]; IMPLEMENTATION curr_inverse_impl = inverse_impl[inverse_ind]; // setup the forward real transform // ft5.setAlgorithm(curr_forward_algo); ft5.setImplementation(curr_forward_impl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -