diff --git a/homework3/.gitignore b/homework3/.gitignore index da825a4..cf28b91 100644 --- a/homework3/.gitignore +++ b/homework3/.gitignore @@ -1,7 +1,8 @@ # Folder: # cmake-build-debug/ googletest/ html/ # Files: # -.idea/ \ No newline at end of file +.idea/ +CMakeLists.txt \ No newline at end of file diff --git a/homework3/src/fft.hh b/homework3/src/fft.hh index 1a7605e..9267f45 100644 --- a/homework3/src/fft.hh +++ b/homework3/src/fft.hh @@ -1,78 +1,79 @@ #ifndef FFT_HH #define FFT_HH /* ------------------------------------------------------ */ #include "matrix.hh" #include "my_types.hh" #include /* ------------------------------------------------------ */ struct FFT { static Matrix transform(Matrix& m); static Matrix itransform(Matrix& m); static Matrix> computeFrequencies(int size); }; /* ------------------------------------------------------ */ inline Matrix FFT::transform(Matrix& m_in) { // changing the type from Matrix to fftw_complex but handling the memory with pointers auto in = (fftw_complex *)m_in.data(); // create a empty output object of type matrix Matrix m_out(m_in.size()); // changing the type from Matrix to fftw_complex auto out = (fftw_complex *)m_out.data(); // creating the plan fftw_plan p; // apply the plan p = fftw_plan_dft_2d(m_in.rows(),m_in.cols(), in, out, FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute(p); /* repeat as needed */ fftw_destroy_plan(p); return m_out;} /* ------------------------------------------------------ */ inline Matrix FFT::itransform(Matrix& m_in) { // changing the type from Matrix to fftw_complex but handling the memory with pointers auto in = (fftw_complex *)m_in.data(); // create a empty output object of type matrix Matrix m_out(m_in.size()); // changing the type from Matrix to fftw_complex auto out = (fftw_complex *)m_out.data(); // creating the plan fftw_plan p; // apply the plan p = fftw_plan_dft_2d(m_in.rows(),m_in.cols(), in, out, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_execute(p); /* repeat as needed */ fftw_destroy_plan(p); return m_out; } /* ------------------------------------------------------ */ /* ------------------------------------------------------ */ inline Matrix> FFT::computeFrequencies(int size) { + // using even numbers } #endif // FFT_HH diff --git a/homework3/src/test_fft.cc b/homework3/src/test_fft.cc index 3858490..58a3c17 100644 --- a/homework3/src/test_fft.cc +++ b/homework3/src/test_fft.cc @@ -1,65 +1,67 @@ #include "my_types.hh" #include "fft.hh" #include /*****************************************************************/ TEST(FFT, transform) { + // using even numbers UInt N = 512; Matrix m(N); Real k = 2 * M_PI / N; for (auto&& entry : index(m)) { int i = std::get<0>(entry); int j = std::get<1>(entry); auto& val = std::get<2>(entry); val = cos(k * i); } Matrix res = FFT::transform(m); //note the missing 1/N^2 factor in the discrete FFT for (auto&& entry : index(res)) { int i = std::get<0>(entry); int j = std::get<1>(entry); auto& val = std::get<2>(entry); if (std::abs(val) > 1e-10) std::cout << i << "," << j << " = " << val << std::endl; if (i == 1 && j == 0) ASSERT_NEAR(std::abs(val), N * N / 2, 1e-10); else if (i == N - 1 && j == 0) ASSERT_NEAR(std::abs(val), N * N / 2, 1e-10); else ASSERT_NEAR(std::abs(val), 0, 1e-10); } } /*****************************************************************/ TEST(FFT, inverse_transform) { + // using even numbers UInt N = 512; Matrix m(N); for (auto&& entry : index(m)) { int i = std::get<0>(entry); int j = std::get<1>(entry); auto& val = std::get<2>(entry); if (i == 1 && j == 0) val = N * N / 2; else if (i == N - 1 && j == 0) val = N * N / 2; else val = 0; } Matrix res = FFT::itransform(m); //note the missing 1/N^2 factor in the discrete FFT Real k = 2 * M_PI / N; for (auto&& entry : index(res)) { int i = std::get<0>(entry); int j = std::get<1>(entry); auto& val = std::get<2>(entry); ASSERT_NEAR(val.real() / (N * N), cos(k * i), 1e-10); ASSERT_NEAR(val.imag() / (N * N), 0., 1e-10); } } /*****************************************************************/