📄 ft_05.cc
字号:
// Implementation: FAST_HARLEY // else if (implementation_d == FAST_HARTLEY) { if (!fhComplex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: QF // for quick fourier transform implementation // else if (implementation_d == QF) { if (!qfComplex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DITF // for decimation in time frequency implementation // else if (implementation_d == DITF) { if (!ditfComplex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // else: not implemented yet // else { return Error::handle(name(), L"computeForward", Error::NOT_IMPLEM, __FILE__, __LINE__); } } // Algorithm: DCT // for discrete cosine transform algorithm // else if (algorithm_d == DCT) { // Implementation: DCT_I // if (implementation_d == TYPE_I) { if (!dct1Complex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_II // else if (implementation_d == TYPE_II) { if (!dct2Complex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_III // else if (implementation_d == TYPE_III) { if (!dct3Complex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_IV // else if (implementation_d == TYPE_IV) { if (!dct4Complex(tmp_output, tmp_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // else: not implemented yet // else { return Error::handle(name(), L"computeForward", Error::NOT_IMPLEM, __FILE__, __LINE__); } } // else: not implemented yet // else { return Error::handle(name(), L"computeForward", Error::NOT_IMPLEM, __FILE__, __LINE__); } if (algorithm_d == DCT) { // convert the temporary output vector to complex output vector // output_a.setLength(tmp_output.length()); for (long i = 0; i < tmp_output.length(); i++) { output_a(i).assign(complexfloat(tmp_output(i), 0)); } } else { // convert the temporary output vector to complex output vector // output_a.setLength(tmp_output.length() / 2); for (long i = 0, j = 0; i < output_a.length(); i++) { output_a(i).assign(complexfloat(tmp_output(j), tmp_output(j + 1))); j += 2; } } // provide some useful debugging information // if (debug_level_d > Integral::NONE) { if (debug_level_d >= Integral::ALL) { debug(PARAM_DBGL); } if (debug_level_d >= Integral::DETAILED) { input_a.debug(CLASS_NAME); } if (debug_level_d >= Integral::BRIEF) { output_a.debug(CLASS_NAME); } } // restore the implementation // implementation_d = backup_impl; // exit gracefully // return true;}// method: computeForward//// arguments:// VectorFloat& output: (output) output data vector// const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method calls only DCT forward algorithm since only DCT has real// signal input and real spectrum output.//boolean FourierTransform::computeForward(VectorFloat& output_a, const VectorFloat& input_a) { // only applied to DCT algorithm // if (algorithm_d != DCT) { return Error::handle(name(), L"computeForward", Error::NOT_IMPLEM, __FILE__, __LINE__); } // variables abour length // input data length: L // user specified input length: N // user specified output length: M // FFT order: order // long L = input_a.length(); long N = (ilen_d == DEF_LENGTH) ? L : (long)ilen_d; order_d = N; // create a vector for use when we have to truncate // VectorFloat tmp_input; // check the required order - when fixed order is not required, if // the required order is greater than the length of the input vector // then we need to zero-pad the input vector (with a trick). if it // is less than the length of the input vector then we need to // truncate, else use the given input vector // const VectorFloat* algo_input = &input_a; // if N < L, truncate input data to N length // if (N < L) { tmp_input.setLength(N); tmp_input.move(input_a, N, 0, 0); // set the pointer // algo_input = &tmp_input; } // if N > L, pad zeros to input data to order length // if (N > L) { tmp_input.assign(input_a); tmp_input.setLength(N, true); algo_input = &tmp_input; } // Implementation: DCT_I // if (implementation_d == TYPE_I) { if (!dct1Real(output_a, *algo_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_II // else if (implementation_d == TYPE_II) { if (!dct2Real(output_a, *algo_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_III // else if (implementation_d == TYPE_III) { if (!dct3Real(output_a, *algo_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // Implementation: DCT_IV // else if (implementation_d == TYPE_IV) { if (!dct4Real(output_a, *algo_input)) { return Error::handle(name(), L"computeForward", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // else: not implemented yet // else { return Error::handle(name(), L"computeForward", Error::NOT_IMPLEM, __FILE__, __LINE__); } // exit gracefully // return true;}// method: computeInverse//// arguments:// VectorComplexFloat& output: (output) output data vector// const VectorComplexFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method calls the fft algorithm chosen by the user in the// inverse algorithm. if the input data length is not compatible with// the chosen algorithm then the dft is used//boolean FourierTransform::computeInverse(VectorComplexFloat& output_a, const VectorComplexFloat& input_a) { // implementation DCT can not support inverse algorithm // if (algorithm_d == DCT) { return Error::handle(name(), L"computeInverse", ERR_UNKALG, __FILE__, __LINE__); } VectorComplexFloat temp_output; // for inverse transform, it's equivalent to run forward transform on // the circular shifted and scaled input vector // if (!computeForward(temp_output, input_a)) { return Error::handle(name(), L"computeInverse", Error::NOT_IMPLEM, __FILE__, __LINE__, Error::WARNING); } // initialize output vector // output_a.setLength(temp_output.length()); output_a(0) = temp_output(0); // circularly shift the data // for (long i = 1; i < order_d; i++) { output_a(i) = temp_output(order_d - i); } // scale the output vector // output_a.mult((float)(1.0 / order_d)); // exit gracefully // return true;}// method: computeInverse//// arguments:// VectorFloat& output: (output) output data vector// const VectorComplexFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method calls the fft algorithm chosen by the user in inverse// algorithm. if the input data length is not compatible with the// chosen algorithm then the dft is used//boolean FourierTransform::computeInverse(VectorFloat& output_a, const VectorComplexFloat& input_a) { // declare local variables // VectorComplexFloat temp_output; // for inverse transform, it's equivalent to run forward transform on // the circular shifted and scaled input vector // if (!computeForward(temp_output, input_a)) { return Error::handle(name(), L"computeInverse", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } // store the real part of temporary complex vector to the output real vector // temp_output.real(output_a); // exit gracefully // return true;}// method: computeInverse//// arguments:// VectorFloat& output: (output) output data vector// const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method calls only DCT inverse algorithm since only IDCT has real// spectrum input and real signal output.//boolean FourierTransform::computeInverse(VectorFloat& output_a, const VectorFloat& input_a) { // for inverse transform, it's equivalent to run forward transform // if (algorithm_d == DCT) { if (!computeForward(output_a, input_a)) { return Error::handle(name(), L"computeInverse", ERR_COMPF, __FILE__, __LINE__, Error::WARNING); } } // exit gracefully // return true;}// method: computeInverse//// arguments:// VectorComplexFloat& output: (output) output data vector// const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method calls the fft algorithm chosen by the user in the// inverse algorithm. if the input data length is not compatible with// the chosen algorithm then the dft is used//boolean FourierTransform::computeInverse(VectorComplexFloat& output_a, const VectorFloat& input_a) { // implementation DCT can not support inverse algorithm // if (algorithm_d == DCT) { return Error::handle(name(), L"computeInverse", ERR_UNKALG, __FILE__, __LINE__); } VectorComplexFloat temp_output; // for inverse transform, it's equivalent to run forward transform on // the circular shifted and scaled input vector // if (!computeForward(temp_output, input_a)) { return Error::handle(name(), L"computeInverse", Error::NOT_IMPLEM, __FILE__, __LINE__, Error::WARNING); } // initialize output vector // output_a.setLength(temp_output.length()); output_a(0) = temp_output(0); // circularly shift the data // for (long i = 1; i < order_d; i++) { output_a(i) = temp_output(order_d - i); } // scale the output vector // output_a.mult((float)(1.0 / order_d)); // exit gracefully // return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -