Skip to content

Commit 51f93c6

Browse files
authored
add FFT and tests (keon#847)
1 parent e24247f commit 51f93c6

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

algorithms/maths/fft.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Implementation of the Cooley-Tukey, which is the most common FFT algorithm.
3+
4+
Input: an array of complex values which has a size of N, where N is an integer power of 2
5+
Output: an array of complex values which is the discrete fourier transform of the input
6+
7+
Example 1
8+
Input: [2.0+2j, 1.0+3j, 3.0+1j, 2.0+2j]
9+
Output: [8+8j, 2j, 2-2j, -2+0j]
10+
11+
12+
Pseudocode: https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm
13+
"""
14+
from cmath import exp, pi
15+
16+
def fft(x):
17+
""" Recursive implementation of the Cooley-Tukey"""
18+
N = len(x)
19+
if N == 1:
20+
return x
21+
22+
# get the elements at even/odd indices
23+
even = fft(x[0::2])
24+
odd = fft(x[1::2])
25+
26+
y = [0 for i in range(N)]
27+
for k in range(N//2):
28+
q = exp(-2j*pi*k/N)*odd[k]
29+
y[k] = even[k] + q
30+
y[k + N//2] = even[k] - q
31+
32+
return y

tests/test_maths.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
diffie_hellman_key_exchange, krishnamurthy_number,
2727
num_perfect_squares,
2828
chinese_remainder_theorem,
29+
fft
2930
)
3031

3132
import unittest
@@ -556,5 +557,41 @@ def test_empty_lists(self):
556557
chinese_remainder_theorem.solve_chinese_remainder(num, rem)
557558

558559

560+
class TestFFT(unittest.TestCase):
561+
"""[summary]
562+
Test for the file fft.py
563+
564+
Arguments:
565+
unittest {[type]} -- [description]
566+
"""
567+
def test_real_numbers(self):
568+
x = [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
569+
y = [4.000, 2.613, 0.000, 1.082, 0.000, 1.082, 0.000, 2.613]
570+
# abs(complex) returns the magnitude
571+
result = [float("%.3f" % abs(f)) for f in fft.fft(x)]
572+
self.assertEqual(result, y)
573+
574+
def test_all_zero(self):
575+
x = [0.0, 0.0, 0.0, 0.0]
576+
y = [0.0, 0.0, 0.0, 0.0]
577+
result = [float("%.1f" % abs(f)) for f in fft.fft(x)]
578+
self.assertEqual(result, y)
579+
580+
def test_all_ones(self):
581+
x = [1.0, 1.0, 1.0, 1.0]
582+
y = [4.0, 0.0, 0.0, 0.0]
583+
result = [float("%.1f" % abs(f)) for f in fft.fft(x)]
584+
self.assertEqual(result, y)
585+
586+
def test_complex_numbers(self):
587+
x = [2.0+2j, 1.0+3j, 3.0+1j, 2.0+2j]
588+
real = [8.0, 0.0, 2.0, -2.0]
589+
imag = [8.0, 2.0, -2.0, 0.0]
590+
realResult = [float("%.1f" % f.real) for f in fft.fft(x)]
591+
imagResult = [float("%.1f" % f.imag) for f in fft.fft(x)]
592+
self.assertEqual(real, realResult)
593+
self.assertEqual(imag, imagResult)
594+
595+
559596
if __name__ == "__main__":
560597
unittest.main()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy