Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 7334
1
"""This file contains code used in "Think DSP",
2
by Allen B. Downey, available from greenteapress.com
3
4
Copyright 2014 Allen B. Downey
5
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
6
"""
7
8
from __future__ import print_function, division
9
10
import numpy as np
11
12
import thinkdsp
13
import thinkplot
14
15
PI2 = np.pi * 2
16
17
18
def synthesize1(amps, fs, ts):
19
"""Synthesize a mixture of cosines with given amps and fs.
20
21
amps: amplitudes
22
fs: frequencies in Hz
23
ts: times to evaluate the signal
24
25
returns: wave array
26
"""
27
components = [thinkdsp.CosSignal(freq, amp)
28
for amp, freq in zip(amps, fs)]
29
signal = thinkdsp.SumSignal(*components)
30
31
ys = signal.evaluate(ts)
32
return ys
33
34
35
def synthesize2(amps, fs, ts):
36
"""Synthesize a mixture of cosines with given amps and fs.
37
38
amps: amplitudes
39
fs: frequencies in Hz
40
ts: times to evaluate the signal
41
42
returns: wave array
43
"""
44
args = np.outer(ts, fs)
45
M = np.cos(PI2 * args)
46
ys = np.dot(M, amps)
47
return ys
48
49
50
def analyze1(ys, fs, ts):
51
"""Analyze a mixture of cosines and return amplitudes.
52
53
Works for the general case where M is not orthogonal.
54
55
ys: wave array
56
fs: frequencies in Hz
57
ts: times where the signal was evaluated
58
59
returns: vector of amplitudes
60
"""
61
args = np.outer(ts, fs)
62
M = np.cos(PI2 * args)
63
amps = np.linalg.solve(M, ys)
64
return amps
65
66
67
def analyze2(ys, fs, ts):
68
"""Analyze a mixture of cosines and return amplitudes.
69
70
Assumes that fs and ts are chosen so that M is orthogonal.
71
72
ys: wave array
73
fs: frequencies in Hz
74
ts: times where the signal was evaluated
75
76
returns: vector of amplitudes
77
"""
78
args = np.outer(ts, fs)
79
M = np.cos(PI2 * args)
80
amps = np.dot(M, ys) / 2
81
return amps
82
83
84
def dct_iv(ys):
85
"""Computes DCT-IV.
86
87
ys: wave array
88
89
returns: vector of amplitudes
90
"""
91
N = len(ys)
92
ts = (0.5 + np.arange(N)) / N
93
fs = (0.5 + np.arange(N)) / 2
94
args = np.outer(ts, fs)
95
M = np.cos(PI2 * args)
96
amps = np.dot(M, ys) / 2
97
return amps
98
99
100
def synthesize_example():
101
"""Synthesizes a sum of sinusoids and plays it.
102
"""
103
amps = np.array([0.6, 0.25, 0.1, 0.05])
104
fs = [100, 200, 300, 400]
105
106
framerate = 11025
107
ts = np.linspace(0, 1, 11025)
108
ys = synthesize2(amps, fs, ts)
109
wave = thinkdsp.Wave(ys, framerate)
110
wave.normalize()
111
wave.apodize()
112
wave.play()
113
114
n = len(fs)
115
amps2 = analyze1(ys[:n], fs, ts[:n])
116
print(amps)
117
print(amps2)
118
119
120
def test1():
121
amps = np.array([0.6, 0.25, 0.1, 0.05])
122
N = 4.0
123
time_unit = 0.001
124
ts = np.arange(N) / N * time_unit
125
max_freq = N / time_unit / 2
126
fs = np.arange(N) / N * max_freq
127
args = np.outer(ts, fs)
128
M = np.cos(PI2 * args)
129
return M
130
131
132
def test2():
133
"""
134
"""
135
amps = np.array([0.6, 0.25, 0.1, 0.05])
136
N = 4.0
137
ts = (0.5 + np.arange(N)) / N
138
fs = (0.5 + np.arange(N)) / 2
139
print('amps', amps)
140
print('ts', ts)
141
print('fs', fs)
142
ys = synthesize2(amps, fs, ts)
143
amps2 = analyze2(ys, fs, ts)
144
print('amps', amps)
145
print('amps2', amps2)
146
147
148
def test_dct():
149
"""
150
"""
151
amps = np.array([0.6, 0.25, 0.1, 0.05])
152
N = 4.0
153
ts = (0.5 + np.arange(N)) / N
154
fs = (0.5 + np.arange(N)) / 2
155
ys = synthesize2(amps, fs, ts)
156
157
amps2 = dct_iv(ys)
158
print('amps', amps)
159
print('amps2', amps2)
160
161
162
def dct_plot():
163
signal = thinkdsp.TriangleSignal(freq=400)
164
wave = signal.make_wave(duration=1.0, framerate=10000)
165
dct = wave.make_dct()
166
dct.plot()
167
thinkplot.config(xlabel='Frequency (Hz)', ylabel='DCT')
168
thinkplot.save(root='dct1',
169
formats=['pdf', 'eps'])
170
171
172
def main():
173
np.set_printoptions(precision=3, suppress=True)
174
175
test1()
176
test2()
177
dct_plot()
178
179
180
if __name__ == '__main__':
181
main()
182
183