/**************************************************************** **** **** This file belongs with the course **** Introduction to Scientific Programming in C++/Fortran2003 **** copyright 2016-2023 Victor Eijkhout eijkhout@tacc.utexas.edu **** **** fft.cxx : FFT code **** ****************************************************************/ #include using std::cin; using std::cout; #include using std::setprecision; #include using std::stringstream; #include #include using std::vector; #include #include static constexpr double pi = 3.141592653589793238462643383279502884; namespace fft { template class vector { private: std::vector signal; public: vector(int n) : signal( std::vector(n) ) {}; // element access int samples() const { return signal.size(); }; int size() const { return signal.size(); }; auto &at(int i) { return signal.at(i); }; const auto &at(int i) const { return signal.at(i); }; // actual trig stuff void set_wave(int n=1) { int N = samples(); for (int i=0; isize()==N ); if (naive) { for (int frequency=1; frequency<=N; ++frequency) { T s{0}; for (int loc=0; loc( std::sin( pi*frequency*back_loc/N ) ); } float scale = N/2; s /= scale; coefficients.at(frequency-1) = s; } } else { } }; // diagnostics auto stringed() { stringstream s; for ( auto c : signal ) s << setprecision(3) << c << " "; return s; }; }; } int main() { #define N 32 { cout << "%%%%%%%%%%%%%%%% Double %%%%%%%%%%%%%%%%\n"; fft::vector sine(N),sine2(N); sine.set_wave(); cout << sine.stringed().str() << '\n'; sine2.set_wave(2); auto ortho = sine*sine2; cout << "product 1x2: " << ortho << '\n'; auto norm = sine2*sine2; cout << "product 2x2: " << norm << '\n'; fft::vector coefficients(N); sine.transform(coefficients); cout << "Sine transform: " << coefficients.stringed().str() << '\n'; sine2.transform(coefficients); cout << "Sine2 transform: " << coefficients.stringed().str() << '\n'; } { cout << "\n%%%%%%%%%%%%%%%% Complex %%%%%%%%%%%%%%%%\n"; fft::vector> sine(N),sine2(N); sine.set_wave(); cout << sine.stringed().str() << '\n'; sine2.set_wave(2); auto ortho = sine*sine2; cout << "product 1x2: " << ortho << '\n'; auto norm = sine2*sine2; cout << "product 2x2: " << norm << '\n'; fft::vector> coefficients(N); sine.transform(coefficients); cout << "Sine transform: " << coefficients.stringed().str() << '\n'; sine2.transform(coefficients); cout << "Sine2 transform: " << coefficients.stringed().str() << '\n'; } return 0; }