forked from peterhinch/micropython-fourier
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdfttest.py
121 lines (101 loc) · 3.4 KB
/
dfttest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# dfttest.py Test DFT with synthetic data
# Author: Peter Hinch
# 5th Feb 2018
import math
from dftclass import DFT, FORWARD, REVERSE, POLAR, DB
# *********************** Pretty print **********************
def print_tests():
st = '''Synthetic data tests for dftclass.
Available tests:
forward() Forward transform. Output in bins 0, 4.
test() Forward polar transform. Output in bins 0, 4.
dbtest() dB conversion of above.
dbhann() Test of hanning (hann) window.
trev() Test reverse transform. Single cosine cycle.
bench() Benchmark: time a 1K forward transform.
'''
print('\x1b[32m')
print(st)
print('\x1b[39m')
print_tests()
def printexp(exp):
print('Expected output:')
print('\x1b[32m')
print(exp)
print('\x1b[39m')
def cartesian_print(objDFT):
print("Bin real imaginary")
fstr = "{:6d}{:8.2f}{:8.2f}j"
for x in range(objDFT.length):
print(fstr.format(x, objDFT.re[x], objDFT.im[x]))
def polarprint(objDFT):
print("Polar: mag phase (degs)")
fstr = "{:6d}{:8.2f} {:8.2f}"
for x in range(objDFT.length//2): # Only the first half is valid
print(fstr.format(x, objDFT.re[x], int(math.degrees(objDFT.im[x]))))
# ******************** Support functions ********************
# The hann (hanning) window has a -6dB coherent gain. So the function is
# here multiplied by 2 to offset this
def hann(x, length):
return 1 - math.cos(2*math.pi*x/(length - 1))
# Data acquisition functions.
# For forward transforms only the real array is populated.
# Populate with computed sinewave for forward transform (bin 4)
def acqu_test(objDFT):
for x in range(objDFT.length):
objDFT.re[x] = 1 + 2*math.sin(8*math.pi*x/objDFT.length)
# Populate with computed sinewave for forward transform (bin 40)
def acqu_test40(objDFT):
for x in range(objDFT.length):
objDFT.re[x] = 1 + 2*math.sin(80*math.pi*x/objDFT.length)
# Populate with frequency domain data for reverse transform
def revtest(objDFT):
for x in range(objDFT.length):
objDFT.re[x] = 0
objDFT.im[x] = 0
objDFT.re[1] = 10
objDFT.re[objDFT.length -1] = 10
# ************************** TESTS **************************
# Forward transform
def forward():
printexp('''Bin 0 real 1.00 imag 0.00j
Bin 4 real 0.00 imag -1.00j.''')
mydft = DFT(128, acqu_test)
mydft.run(FORWARD)
cartesian_print(mydft)
# Forward polar transform
def test():
printexp('''Bin 0 magnitude 1.00 phase 0.00.
Bin 4 magnitude 1.00 phase -89.00''')
mydft = DFT(128, acqu_test)
mydft.run(POLAR)
polarprint(mydft)
# Forward polar decibel transform
def dbtest():
printexp('''Bin 0 0dB phase 0.
Bin 4 magnitude 0dB phase -89.''')
mydft = DFT(128, acqu_test)
mydft.run(DB)
polarprint(mydft)
# Forward polar decibel transform (hann window, 0dB coherent power gain)
def dbhann():
printexp('''Bin 39 -5.99dB phase 88.
Bin 40 magnitude -0.07dB phase -89.
Bin 41 magnitude -5.99dB phase 91''')
mydft = DFT(128, acqu_test40, hann)
mydft.run(DB)
polarprint(mydft)
# Reverse transform
def trev():
printexp('Single cosine wave amplitude 20.')
mydft = DFT(128, revtest)
mydft.run(REVERSE)
cartesian_print(mydft)
# 1K point benchmark
def bench():
printexp('''Bin 0 real 1.00 imag 0.00j
Bin 4 real 0.00 imag -1.00j.''')
mydft = DFT(1024, acqu_test)
t = mydft.run(FORWARD)
cartesian_print(mydft)
print('Time for 1K DFT = {}μs'.format(t))