Skip to content

Commit f01916a

Browse files
authored
Merge pull request #29 from woodnx/skotsugi/chapter05
Add chapter05
2 parents 2bc1223 + 0a54ffc commit f01916a

File tree

15 files changed

+313
-0
lines changed

15 files changed

+313
-0
lines changed

skotsugi/chapter05/q01.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import numpy as np
2+
3+
4+
def linear_array_manifold_vector(d: float, M: int, theta: float, f: float):
5+
c = 334
6+
a = np.zeros(M, dtype=complex)
7+
u = np.array([np.sin(theta), np.cos(theta), 0])
8+
9+
for m in range(M):
10+
p = np.array([(m - (M - 1) / 2) * d, 0, 0])
11+
a[m] = np.exp(1j * 2 * np.pi * f / c * (u @ p))
12+
13+
return a
14+
15+
16+
if __name__ == "__main__":
17+
d = 0.05
18+
M = 3
19+
theta = np.pi / 4
20+
f = 1000
21+
print(linear_array_manifold_vector(d, M, theta, f))
22+
# [(0.7868536952034816-0.617139580925277j), (1+0j), (0.7868536952034816+0.617139580925277j)]

skotsugi/chapter05/q02.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import numpy as np
2+
3+
4+
def circular_array_manifold_vector(r: float, M: int, theta: float, f: float):
5+
c = 334
6+
a = np.zeros(M, dtype=complex)
7+
u = np.array([np.sin(theta), np.cos(theta), 0])
8+
9+
for m in range(M):
10+
phi = 2 * np.pi * m / M
11+
p = np.array([r * np.sin(phi), r * np.cos(phi), 0])
12+
a[m] = np.exp(1j * 2 * np.pi * f / c * (u @ p))
13+
14+
return a
15+
16+
17+
if __name__ == "__main__":
18+
r = 0.05
19+
M = 3
20+
theta = np.pi / 4
21+
f = 1000
22+
print(circular_array_manifold_vector(r, M, theta, f))
23+
# [0.7868537 +0.61713958j 0.97051349+0.2410468j 0.6148926 -0.78861086j]

skotsugi/chapter05/q03.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import numpy as np
2+
3+
4+
def array_manifold_vector(X: np.ndarray, theta: float, f: float):
5+
c = 334
6+
7+
M, _ = X.shape
8+
a = np.zeros(M, dtype=complex)
9+
u = np.array([np.sin(theta), np.cos(theta), 0])
10+
11+
for m in range(M):
12+
p = X[m]
13+
a[m] = np.exp(1j * 2 * np.pi * f / c * u @ p)
14+
15+
return a
16+
17+
18+
if __name__ == "__main__":
19+
theta = np.pi / 4
20+
r = 0.05
21+
f = 1000
22+
23+
X = np.array([[-r, 0, 0], [0, 0, 0], [r, 0, 0]])
24+
print(array_manifold_vector(X, theta, f))
25+
# [0.7868537-0.61713958j 1. +0.j 0.7868537+0.61713958j]
26+
27+
M = 3
28+
Y = np.zeros((M, 3))
29+
for m in range(M):
30+
phi = 2 * np.pi * m / M
31+
s = r * np.sin(phi)
32+
t = r * np.cos(phi)
33+
Y[m] = [s, t, 0]
34+
35+
print(array_manifold_vector(Y, theta, f))
36+
# [0.7868537 +0.61713958j 0.97051349+0.2410468j 0.6148926 -0.78861086j]

skotsugi/chapter05/q04.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import numpy as np
2+
3+
4+
def spatial_correlation_matrix(X_m: np.ndarray) -> np.ndarray:
5+
M, F, T = X_m.shape
6+
R = np.zeros((F, M, M), dtype=complex)
7+
8+
for f in range(F):
9+
sum_x = np.zeros((M, M), dtype=complex)
10+
for t in range(T):
11+
x_ft = np.array([X_m[:, f, t]]).T
12+
sum_x += x_ft @ np.conj(x_ft.T)
13+
14+
R[f] = sum_x / T
15+
16+
return np.array(R)
17+
18+
19+
if __name__ == "__main__":
20+
X = np.array(
21+
[
22+
[[1, -1j, -1, 1j], [2, -2j, -2, 2j], [3, -3j, -3, 3j]],
23+
[[4, -2j, 1, 0], [2, -1j, 0, 0], [1, -1j, 1, 0]],
24+
]
25+
)
26+
27+
print(spatial_correlation_matrix(X))
28+
# [[[1. +0.j 1.25+0.j]
29+
# [1.25+0.j 5.25+0.j]]
30+
31+
# [[4. +0.j 1.5 +0.j]
32+
# [1.5 +0.j 1.25+0.j]]
33+
34+
# [[9. +0.j 0.75+0.j]
35+
# [0.75+0.j 0.75+0.j]]]

skotsugi/chapter05/q05.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import numpy as np
2+
from scipy.signal import stft
3+
from q04 import spatial_correlation_matrix
4+
5+
fs = 16000
6+
sec = 5
7+
L = 512
8+
S = 256
9+
10+
np.random.seed(1)
11+
noise = np.random.normal(0, 1, size=(2, sec * fs))
12+
13+
f, t, X = stft(noise, fs, nperseg=L, noverlap=L - S)
14+
15+
R = spatial_correlation_matrix(X)
16+
17+
print(R[100].real)
18+
19+
# [[3.19811768e-03 7.08151469e-06]
20+
# [7.08151469e-06 3.29345106e-03]]

skotsugi/chapter05/q06.png

74.1 KB
Loading

skotsugi/chapter05/q06.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import numpy as np
2+
3+
fs = 16000
4+
sec = 1
5+
A = 1
6+
f = 440
7+
snr = 10
8+
9+
# make sin wave
10+
t = np.arange(fs * sec) / fs
11+
signal = A * np.sin(2 * np.pi * f * t)
12+
signal_length = len(signal)
13+
14+
# make noise
15+
signal_power = np.mean(signal**2)
16+
snr_linear: float = 10.0 ** (snr / 10.0)
17+
noise_power = signal_power / snr_linear
18+
noise = np.sqrt(noise_power) * np.random.normal(0, 1, size=signal_length)
19+
20+
# signalを2つ結合する,
21+
signal_twice = np.concatenate([signal, signal])
22+
23+
x = np.array(
24+
[
25+
signal + noise,
26+
signal_twice[10 : signal_length + 10] + noise,
27+
signal_twice[20 : signal_length + 20] + noise,
28+
]
29+
)
30+
31+
if __name__ == "__main__":
32+
import matplotlib.pyplot as plt
33+
34+
for x_i in x:
35+
plt.plot(t, x_i)
36+
37+
plt.xlim([0, 0.01])
38+
plt.savefig("./skotsugi/chapter05/q06.png")

skotsugi/chapter05/q07.png

39.5 KB
Loading

skotsugi/chapter05/q07.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import numpy as np
2+
from scipy.signal import stft, istft
3+
from q06 import x, fs
4+
5+
6+
L = 1024
7+
S = 512
8+
fbin, tbin, X = stft(x, fs, window="hann", nperseg=L, noverlap=L - S)
9+
10+
N, F, T = X.shape
11+
12+
Y = np.zeros((F, T), dtype=complex)
13+
tau = np.array([0, 10, 20]) / fs
14+
15+
for i in range(F):
16+
f = i * fs / 2 / (F - 1)
17+
w = np.exp(-1j * 2 * np.pi * f * tau) / 3
18+
19+
for t in range(T):
20+
Y[i, t] = np.conjugate(w) @ X[:, i, t]
21+
22+
t, y = istft(Y, fs, window="hann", nperseg=L, noverlap=L - S)
23+
24+
25+
if __name__ == "__main__":
26+
import matplotlib.pyplot as plt
27+
28+
plt.plot(t, y)
29+
30+
plt.xlim([0, 0.01])
31+
plt.savefig("./skotsugi/chapter05/q07.png")

skotsugi/chapter05/q08.png

67.5 KB
Loading

skotsugi/chapter05/q08.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import array_manifold_vector
4+
from q07 import F
5+
6+
7+
def beam_pattern(w: np.ndarray, p: np.ndarray, fs):
8+
F, M = w.shape
9+
10+
angle = np.arange(360)
11+
theta = angle * np.pi / 180.0
12+
freq = np.arange(F) * fs / 2 / (F - 1)
13+
14+
Phi = np.zeros((F, 360), dtype=complex)
15+
16+
for i, f in enumerate(freq):
17+
for j, th in enumerate(theta):
18+
a = array_manifold_vector(p, th, f)
19+
w_f = w[i]
20+
21+
Phi[i, j] = w_f.T @ a
22+
23+
A = 20 * np.log10(np.abs(Phi))
24+
return angle, freq, A
25+
26+
27+
if __name__ == "__main__":
28+
d = 0.05
29+
fs = 16000
30+
M = 3
31+
c = 334
32+
33+
# 直線状アレイ
34+
p = np.array([[-d, 0, 0], [0, 0, 0], [d, 0, 0]])
35+
36+
# ステアリングベクトル
37+
w = np.zeros((F, M), dtype=complex)
38+
for f in range(F):
39+
a_w = array_manifold_vector(p, 0, f)
40+
w[f, :] = np.conj(a_w) / M
41+
42+
plt.pcolormesh(*beam_pattern(w, p, fs))
43+
plt.savefig("./skotsugi/chapter05/q08.png")

skotsugi/chapter05/q09.png

128 KB
Loading

skotsugi/chapter05/q09.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import array_manifold_vector
4+
from q08 import beam_pattern, F
5+
6+
fs = 16000
7+
M = 3
8+
c = 334
9+
ds = [0.02, 0.05, 0.1]
10+
fig, ax = plt.subplots(1, 3)
11+
12+
for i, d in enumerate(ds):
13+
# ステアリングベクトル
14+
w = np.zeros((F, M), dtype=complex)
15+
for f in range(F):
16+
a_w = array_manifold_vector(p, 0, f)
17+
w[f, :] = np.conj(a_w) / M
18+
19+
# 直線状アレイ
20+
p = np.array([[-d, 0, 0], [0, 0, 0], [d, 0, 0]])
21+
22+
ax[i].pcolormesh(*beam_pattern(w, p, fs))
23+
24+
plt.tight_layout()
25+
plt.savefig("./skotsugi/chapter05/q09.png")

skotsugi/chapter05/q10.png

54.8 KB
Loading

skotsugi/chapter05/q10.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import numpy as np
2+
from scipy.signal import stft
3+
from q01 import linear_array_manifold_vector
4+
from q04 import spatial_correlation_matrix
5+
6+
7+
def spatial_spectrum(z: np.ndarray, f: float, fs: float):
8+
M, N = z.shape
9+
d = 0.05
10+
L = 1024
11+
S = 512
12+
13+
fbin, _, Z = stft(z, fs, window="hann", nperseg=L, noverlap=L - S)
14+
R = spatial_correlation_matrix(Z)
15+
16+
P = np.zeros(360, dtype=complex)
17+
18+
for deg in range(360):
19+
theta = deg * np.pi / 180.0
20+
a = np.array([linear_array_manifold_vector(d, M, theta, fbin[f])])
21+
w = a.T / M
22+
23+
P[deg] = (np.conj(w).T @ R[f] @ w).item()
24+
25+
return P
26+
27+
28+
if __name__ == "__main__":
29+
import matplotlib.pyplot as plt
30+
from q06 import x, fs
31+
32+
degs = np.arange(360)
33+
34+
for k in range(11):
35+
f = k + 20
36+
37+
P = spatial_spectrum(x, f, fs)
38+
plt.plot(degs, 20 * np.log10(np.abs(P)))
39+
40+
plt.savefig("./skotsugi/chapter05/q10.png")

0 commit comments

Comments
 (0)