Skip to content
Snippets Groups Projects
FFT.cc 3.8 KiB
Newer Older
#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;
Kristoffer Tondel's avatar
Kristoffer Tondel committed
// PI
const double PI{std::acos(-1)};
Kristoffer Tondel's avatar
Kristoffer Tondel committed
// 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++)
    {
Kristoffer Tondel's avatar
Kristoffer Tondel committed
        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)
    {
Kristoffer Tondel's avatar
Kristoffer Tondel committed
        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)
            {
Kristoffer Tondel's avatar
Kristoffer Tondel committed
                s = s + returnVector[j] + std::pow(my[m],m) * returnVector[j+2];
Kristoffer Tondel's avatar
Kristoffer Tondel committed
                s = s + returnVector[j] + std::pow(my[m],m) * returnVector[j+2];
Kristoffer Tondel's avatar
Kristoffer Tondel committed
         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();
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    return inputVector;
}
Kristoffer Tondel's avatar
Kristoffer Tondel committed
void FFT::printToFile(std::vector<std::complex<double>> printVector, std::string fileName, int n)
{
  // Skriver ut inversFuncTransf till en fil
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    resultFile.open(fileName);
    // Sätter önskad antal decimaler
    resultFile << std::fixed << std::setprecision(10);
    for (int i=0;i<n;i++)
    {
Kristoffer Tondel's avatar
Kristoffer Tondel committed
      resultFile << printVector[i].real() << "," << printVector[i].imag() << '\n';