Skip to content
Snippets Groups Projects
FFT.cc 3.89 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>> f,std::vector<std::complex<double>> returnVector,int n,double flag)
    int N = f.size();
    std::complex<double> my = std::exp(flag*2*PI*1i/static_cast<double> (N));
    // Mult. med F2
    if(N==2)
        for(int i=0;i<n;i++)
        {
            returnVector[i] = f[0]+std::pow(my,i)*f[1];
        }
    // Delar upp i udda/jämn
    else
        std::vector<std::complex<double>> a1;
        std::vector<std::complex<double>> b1;
        for(int i=0;i<N;i++)
                a1.push_back(f[i]);
                b1.push_back(f[i]);
        std::vector<std::complex<double>> a2 = fft(a1,returnVector,n,flag);
        std::vector<std::complex<double>> b2 = fft(b1,returnVector,n,flag);
        // I and D mult.
Kristoffer Tondel's avatar
Kristoffer Tondel committed
        for(int k=0;k<n/2;k++)
        {
            std::complex<double> c1;
            std::complex<double> c2;
            
Kristoffer Tondel's avatar
Kristoffer Tondel committed
            c1 = a2[k] + std::pow(my,k) * b2[k];
            c2 = a2[k] + std::pow(my,k+n/2) * b2[k];
Kristoffer Tondel's avatar
Kristoffer Tondel committed
            returnVector[k] = c1;
            returnVector[k+n/2] = c2;  
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    }
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    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"};
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    std::vector<std::complex<double>> inputVector = call.getInput(inFile,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);
    for(int i=0;i<n;i++)
    {
        invTransf[i]=invTransf[i]/static_cast<double>(n);
    }
Kristoffer Tondel's avatar
Kristoffer Tondel committed
    // ---------------------------------------------------------------------------
    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';