Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions DFTAlgorithm/dft.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
This is an algorithm for the implementation of the Discrete Fourier Transform
or DFT. It is widely used in many signal and data processing applications and is mathematically
defined as a change of basis from the time domain to the frequency domain. It was first implemented
simply, as the Fourier Transform, by Joseph Fourier during his studies of the heat equation.
This was made on the observation that an oscillatory measurement can be defined as a linear
combinations of simple sinusoids at different frequencies. Below is the implementation for the
DFT:

The DFT is defined as the inner product of a signal to the complex plane C of intervals proportional to the
number of samples taken in the signal.

given a signal x(n) we can convert to the frequency X(k)

X(k) = SUM(x(n) * e^(i*theta)) with theta = (-j * 2pi * k * n) / N
on the interval n = 0 to n = N - 1 for every value of k = 0 to k = N - 1

*/
#ifndef DFT_H
#define DFT_H

#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

//Since the we know e^i * theta can be represented as euler's equation:
// e ^ i * theta = cos(theta) + i * sin(theta)
//The DFT must return two valued pairs as coordinates on the unit circle
//With the cos representing the Re or horizontal axis and sin representing
//the imaginary or veritcal axis
vector<pair<float,float>> DFT(vector<float> timeDomain)
{
vector<pair<float, float>> frequencyDomain;

//holds the position of the current DFT coefficient
for(int i = 0; i < timeDomain.size(); i++)
{

//initialize two values to store the real and imaginary portion of
//DFT coefficient
float DFT_real = 0.0f;
float DFT_imaginary = 0.0f;

//Iterates over each value in the time domain signal
//and takes the sum of the products of the time domain value with
//the complex exponential
for(int j = 0; j < timeDomain.size(); j++)
{
//each value of splits the real and imaginary part
DFT_real += timeDomain.at(j) * (cos((2*M_PI*i*j)/timeDomain.size()));
DFT_imaginary += -1 * timeDomain.at(j) * sin((2*M_PI*i*j)/timeDomain.size());
}

//push next DFT coefficient to the vector
frequencyDomain.push_back(make_pair(DFT_real, DFT_imaginary));
}

//return frequency representation of a signal
return frequencyDomain;

}

#endif

39 changes: 39 additions & 0 deletions DFTAlgorithm/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include<iostream>
#include "dft.h"

int main()
{
vector<float> timeDomain;
vector<pair<float, float>> frequencyDomain;

//Here we define a simple function to implement
//This can be visualized as a sawtooth wave form
//if you want to extend the length to represent
//a much more realistic sampling margin you can extend with Karplus-Strong Algorithm
//stay tuned for this implementation
for(float i = 0; i < 1.02; i += 0.02)
{
timeDomain.push_back(i - 0.5);
}

//Here we call the DFT implementation can be found in dft.h
frequencyDomain = DFT(timeDomain);

//print time domain coefficients
for(int i = 0; i < timeDomain.size(); i++)
{
cout << timeDomain.at(i) << " ";
}

//place space between the output
cout << endl;

//print out absolute value or magnitude of complex DFT coefficients
//here |a + bi| = sqrt(a^2 + b^2)
for(int i = 0; i < timeDomain.size(); i++)
{
cout << sqrt(pow(frequencyDomain.at(i).first, 2) + pow(frequencyDomain.at(i).second, 2)) << " ";
}

return 0;
}