#include <complex> #include <cmath> #include <iomanip> #include "Header files/FFT.h" #include <iostream> #include <fstream> #include <string> #include <bits/stdc++.h> using namespace std::complex_literals; // PI const double PI{std::acos(-1)}; // Alg start---------------------------------------------------------------------------------------------------- std::vector<std::complex<double>> fft(std::vector<std::complex<double>> inputVector,std::vector<std::complex<double>> returnVector,int n,double flag) { std::complex<double> my[n]; for(int i=0;i<n;i++) { my[i]=std::exp(flag*1i*2.0*PI*static_cast<double> (i)/static_cast<double> (n)); } // "Bitreversal" std::stable_partition(std::begin(inputVector), std::end(inputVector), [&inputVector](std::complex<double> const& a){return 0==((&a-&inputVector[0])%2);}); // F2 mult. for(int i=0;i<n;i+=2) { returnVector[i]=inputVector[i]+inputVector[i+1]; returnVector[i+1]=inputVector[i]-inputVector[i+1]; } // I and D mult. for(int m=0;m<n;m++) { std::complex<double> s = 0; if(m % 2 == 0) { for(int j=0;j<n;j+=4) { s = s + returnVector[j] + std::pow(my[m],m) * returnVector[j+2]; } } else { for(int j=1;j<n;j+=4) { s = s + returnVector[j] + std::pow(my[m],m) * returnVector[j+2]; } } returnVector[m]= s / static_cast<double> (std::sqrt(n)); } return returnVector; } // Alg slut---------------------------------------------------------------------------------------------------- int main() { FFT call; int const n{16}; // inFile innehåller uHatt data och outFile är resulterande filen std::string inFile{"sinus.txt"}; std::string outFile{"inversSinusFFT.txt"}; std::vector<std::complex<double>> inputVector = call.getInput(inFile,n); std::complex<double> funcTransf[n]; // Skapar två vektorer av storlek n med nollor i sig std::vector<std::complex<double>> returnVector1; std::vector<std::complex<double>> returnVector2; for(int i=0;i<n;i++) { returnVector1.push_back(0); returnVector2.push_back(0); } // Anroppar alg ------------------------------------------------------------- std::vector<std::complex<double>> transf = fft(inputVector,returnVector1,n,-1); std::vector<std::complex<double>> invTransf = fft(transf,returnVector2,n,1); // --------------------------------------------------------------------------- call.printToFile(invTransf,outFile,n); std::cout << "FFT done"<<'\n'; return 0; } // Skriva/läsa----------------------------------------------------------------------------- std::vector<std::complex<double>> FFT::getInput(std::string inFile, int n) { std::vector<std::complex<double>> inputVector; // Hämtar data och sätter den på en vector int loop = 0; std::string dataLine; std::ifstream functionData (inFile); std::complex<double> element; if (functionData.is_open()) { while ((std::getline (functionData,dataLine)) && (loop < n) ) { std::istringstream is(dataLine); is >> element; inputVector.push_back(element); loop++; } functionData.close(); } return inputVector; } void FFT::printToFile(std::vector<std::complex<double>> printVector, std::string fileName, int n) { // Skriver ut inversFuncTransf till en fil std::ofstream resultFile; resultFile.open(fileName); // Sätter önskad antal decimaler resultFile << std::fixed << std::setprecision(10); for (int i=0;i<n;i++) { resultFile << printVector[i].real() << "," << printVector[i].imag() << '\n'; } resultFile.close(); }