2021-10-07 22:46:31 +08:00
/**
* @ fast_fourier_transform . cpp
* @ brief A fast Fourier transform ( FFT ) is an algorithm that computes the
2021-10-18 01:42:52 +08:00
* discrete Fourier transform ( DFT ) of a sequence , or its inverse ( IDFT ) , this algorithm
* has application in use case scenario where a user wants to find points of a function
* in short period time by just using the coefficents of the polynomial function .
2021-10-07 22:46:31 +08:00
* @ details
* https : //medium.com/@aiswaryamathur/understanding-fast-fourier-transform-from-scratch-to
- solve - polynomial - multiplication - 8018 d511162f
* @ author [ Ameya Chawla ] ( https : //github.com/ameyachawlaggsipu)
*/
2021-10-18 01:30:58 +08:00
# include<iostream> ///Standard Library for input and output
# include<cmath> ///For sine,cosine functions
# include<complex> ///For storing points and coefficents
# include <cassert> ///For Assertions
2021-10-07 22:46:31 +08:00
# define pi 3.14159265358979323846
/**
* @ brief FastFourierTransform is a recursive function which returns list of complex numbers
* @ param p List of Coefficents in form of complex numbers
* @ param n Count of elements in list p
* @ returns p if n = = 1
* @ returns y if n ! = 1
*/
2021-10-18 01:51:23 +08:00
std : : complex < double > * FastFourierTransform ( std : : complex < double > * p , int n )
2021-10-07 22:46:31 +08:00
{
if ( n = = 1 ) return p ; ///Base Case To return
2021-10-18 01:51:23 +08:00
std : : complex < double > om = std : : complex < double > ( cos ( 2 * pi / n ) , sin ( 2 * pi / n ) ) ; ///Calculating value of omega
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > * pe = new std : : complex < double > [ n / 2 ] ; /// Coefficents of even power
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > * po = new std : : complex < double > [ n / 2 ] ; ///Coefficents of odd power
2021-10-07 22:46:31 +08:00
int k1 = 0 , k2 = 0 ;
for ( int j = 0 ; j < n ; j + + )
{
if ( j % 2 = = 0 ) {
pe [ k1 + + ] = p [ j ] ; ///Assigning values of even coefficents
}
else po [ k2 + + ] = p [ j ] ; ///Assigning value of odd coefficents
}
2021-10-18 01:51:23 +08:00
std : : complex < double > * ye = FastFourierTransform ( pe , n / 2 ) ; ///Recursive Call
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > * yo = FastFourierTransform ( po , n / 2 ) ; ///Recursive Call
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > * y = new std : : complex < double > [ n ] ; ///Final value representation list
2021-10-07 22:46:31 +08:00
for ( int i = 0 ; i < n / 2 ; i + + )
{
2021-10-07 22:48:08 +08:00
y [ i ] = ye [ i ] + pow ( om , i ) * yo [ i ] ; ///Updating the first n/2 elements
y [ i + n / 2 ] = ye [ i ] - pow ( om , i ) * yo [ i ] ; ///Updating the last n/2 elements
2021-10-07 22:46:31 +08:00
}
return y ; ///Return the list
}
/**
* @ brief Self - test implementations
2021-10-18 01:42:52 +08:00
* declaring two test cases and checking for the error
* in predicted and true value is less than 0.000000000001 .
2021-10-07 22:46:31 +08:00
* @ returns void
*/
static void test ( ) {
/* descriptions of the following test */
2021-10-18 01:51:23 +08:00
std : : complex < double > t1 [ 2 ] = { 1 , 2 } ; ///Test case 1
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > t2 [ 4 ] = { 1 , 2 , 3 , 4 } ; ///Test case 2
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
int n1 = sizeof ( t1 ) / sizeof ( std : : complex < double > ) ;
int n2 = sizeof ( t2 ) / sizeof ( std : : complex < double > ) ;
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > r1 [ 2 ] = { { 3 , 0 } , { - 1 , 0 } } ; ///True Answer for test case 1
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > r2 [ 4 ] = { { 10 , 0 } , { - 2 , - 2 } , { - 2 , 0 } , { - 2 , 2 } } ; ///True Answer for test case 2
2021-10-07 22:46:31 +08:00
2021-10-18 01:51:23 +08:00
std : : complex < double > * o1 = FastFourierTransform ( t1 , n1 ) ;
std : : complex < double > * o2 = FastFourierTransform ( t2 , n2 ) ;
2021-10-07 22:46:31 +08:00
for ( int i = 0 ; i < n1 ; i + + )
{
2021-10-18 01:42:52 +08:00
assert ( r1 [ i ] . real ( ) - o1 - > real ( ) < 0.000000000001 and r1 [ i ] . imag ( ) - o1 - > imag ( ) < 0.000000000001 ) ; /// Comparing for both real and imaginary values for test case 1
2021-10-07 22:46:31 +08:00
o1 + + ;
}
for ( int i = 0 ; i < n2 ; i + + )
{
2021-10-18 01:42:52 +08:00
assert ( r2 [ i ] . real ( ) - o2 - > real ( ) < 0.000000000001 and r2 [ i ] . imag ( ) - o2 - > imag ( ) < 0.000000000001 ) ; /// Comparing for both real and imaginary values for test case 2
2021-10-07 22:46:31 +08:00
o2 + + ;
}
}
/**
* @ brief Main function
* @ param argc commandline argument count ( ignored )
* @ param argv commandline array of arguments ( ignored )
2021-10-18 01:42:52 +08:00
* calls automated test function to test the working of fast fourier transform .
2021-10-07 22:46:31 +08:00
* @ returns 0 on exit
*/
int main ( int argc , char const * argv [ ] )
{
test ( ) ;
2021-10-18 01:42:52 +08:00
return 0 ;
2021-10-07 22:48:08 +08:00
}