Tôi đang cố gắng sử dụng cái mông
Hàm thiết kế bộ lọc Butterworth mô phỏng (thực ra tôi đang chuyển một chương trình gọi hàm này từ MATLAB sang Python).
Thông số của tôi là:
Tần số băng thông (Fp) = 10 Hz, cho Wp = 2*pi*10 Hz
Tần số dải dừng (Fs) = 100 Hz, cho Ws = 2*pi*100 Hz
Suy hao/suy giảm băng thông và băng chặn (Rp, Rs) lần lượt là 3 và 80 dB.
Trong MATLAB tôi sử dụng mã này:
Wp = 2*pi*10
Ws = 2 * pi * 100
Rp = 3
R = 80
[N, Wn] = mông(Wp, Ws, Rp, Rs, 's')
điều này mang lại cho tôi N = 5
,Wn = 99,581776302
.
Trong SciPy tôi cố gắng làm điều tương tự:
từ số pi nhập numpy
từ tín hiệu nhập scipy
Wp = 2*pi*10
Ws = 2 * pi * 100
Rp = 3
R = 80
(N, Wn) = signal.buttord(Wp, Ws, Rp, Rs, analog=True)
tôi hiểu N = 5
Và Wn = 62.861698649592753
. Wn khác với giá trị do MATLAB đưa ra và gần với Wp một cách đáng ngạc nhiên. Vấn đề ở đây là gì?
Tìm hiểu sâu hơn về nguồn gốc và các vấn đề của SciPy, tôi thấy yêu cầu kéo nàyĐiều này có thể giải thích điều gì đó: hóa ra MATLAB và SciPy có các mục tiêu thiết kế khác nhau (MATLAB cố gắng khớp tối ưu các tần số băng tần dừng, trong khi SciPy cố gắng khớp tối ưu các tần số băng thông).
Nếu có vấn đề, tôi đang sử dụng MATLAB R2013a, Python 3.4.2 và SciPy 0.15.0.
(Tôi cũng đã đăng nội dung sau trên danh sách gửi thư scipy.)
Khi bạn sử dụng buttord để thiết kế bộ lọc Butterworth, sẽ không có đủ bậc tự do để đáp ứng đầy đủ mọi ràng buộc thiết kế. Vì vậy, vấn đề là phải chọn đầu nào của vùng chuyển tiếp đạt đến giới hạn và đầu nào được "thiết kế quá mức". Những thay đổi trong scipy 0.14.0 chuyển lựa chọn này từ các cạnh dải chặn sang các cạnh dải thông.
Một hình ảnh sẽ làm cho nó rõ ràng. Kịch bản dưới đây tạo ra cốt truyện sau. (Tôi đã thay đổi Rp từ 3 thành 1,5. -3 dB phù hợp với mức tăng ở Wn, đó là lý do tại sao Wn của bạn giống với Wp.) Các bộ lọc được tạo bằng cách sử dụng quy ước cũ hoặc quy ước mới đáp ứng các ràng buộc về thiết kế. Sử dụng quy ước mới, phản hồi chỉ chạm đến giới hạn ở cuối băng thông.
nhập numpy dưới dạng np
từ nhập khẩu scipy.signal buttord, bơ, tần số
nhập matplotlib.pyplot dưới dạng plt
# Kết quả thiết kế cho:
Wp = 2*np.pi*10
Ws = 2*np.pi*100
Rp = 1,5 # thay vì 3
R = 80
n_old = 5
wn_old = 99,581776302787929
n_new, wn_new = buttord(Wp, Ws, Rp, Rs, analog=True)
b_old, a_old = bơ(n_old, wn_old, analog=True)
w_old, h_old = tần số(b_old, a_old)
b_new, a_new = bơ(n_new, wn_new, analog=True)
w_new, h_new = freqs(b_new, a_new)
db_old = 20*np.log10(np.abs(h_old))
db_new = 20*np.log10(np.abs(h_new))
plt.semilogx(w_old, db_old, 'b--', label='old')
plt.axvline(wn_old, color='b', alpha=0,25)
plt.semilogx(w_new, db_new, 'g', label='new')
plt.axvline(wn_new, color='g', alpha=0,25)
plt.axhline(-3, color='k', ls=':', alpha=0.5, label='-3 dB')
plt.xlim(40, 1000)
plt.ylim(-100, 5)
xbounds = plt.xlim()
ybounds = plt.ylim()
trực tràng = plt.Rectangle((Wp, ybounds[0]), Ws - Wp, ybounds[1] - ybounds[0],
facecolor="#000000", edgecolor='none', alpha=0.1, Hatch='//')
plt.gca().add_patch(trực tràng)
trực tràng = plt.Rectangle((xbounds[0], -Rp), Wp - xbounds[0], 2*Rp,
facecolor="#FF0000", edgecolor='none', alpha=0,25)
plt.gca().add_patch(trực tràng)
trực tràng = plt.Rectangle((Ws, ybounds[0]), xbounds[1] - Ws, -Rs - ybounds[0],
facecolor="#FF0000", edgecolor='none', alpha=0,25)
plt.gca().add_patch(trực tràng)
plt.annotate("Đạt", (0,5*(xbounds[0] + Wp), Rp+0,5), ha='center')
plt.annotate("Dừng", (0,5*(Ws + xbounds[1]), -Rs+0,5), ha='center')
plt.annotate("Không quan tâm", (0,1*(8*Wp + 2*Ws), -Rs+10), ha='center')
plt.legend(loc='tốt nhất')
plt.xlabel('Tần số [rad/s]')
plt.ylabel('Tăng [dB]')
plt.show()
Tôi là một lập trình viên xuất sắc, rất giỏi!