在 scipy.signal 中为模拟贝塞尔模型设置 Wn
Setting Wn for analog Bessel model in scipy.signal
我一直在尝试使用 scipy.signal 实现截止频率为 2kHz 的模拟贝塞尔滤波器,但我对要设置的 Wn 值感到困惑,因为文档指出 Wn(对于模拟滤波器)应该设置为 angular 频率(约 12000 rad/s)。但是,如果我将此应用于我的 1 秒虚拟数据,并以 500 000 Hz 采样半秒脉冲,我会得到一串 0 和 nans。我缺少什么?
import numpy as np
import scipy
import matplotlib.pyplot as plt
import scipy.signal
def make_signal(pulse_length, rate = 500000):
new_x = np.zeros(rate)
end_signal = 250000+pulse_length
new_x[250000:end_signal] = 1
data = new_x
print (np.shape(data))
# pad on both sides
data=np.concatenate((np.zeros(rate),data,np.zeros(rate)))
return data
def conv_time(t):
pulse_length = t * 500000
pulse_length = int(pulse_length)
return pulse_length
def make_data(ti): #give time in seconds
pulse_length=conv_time(ti)
print (pulse_length)
data = make_signal(pulse_length)
return data
time_scale = np.linspace(0,1,500000)
data = make_data(0.5)
[b,a] = scipy.signal.bessel(4, 12566.37, btype='low', analog=True, output='ba', norm='phase', fs=None)
output_signal = scipy.signal.filtfilt(b, a, data)
plt.plot(data[600000:800000])
plt.plot(output_signal[600000:800000])
当使用频率绘制响应时,对我来说似乎还不错;我哪里弄错了?
您正在将模拟滤波器传递给需要数字(即离散时间)滤波器的函数 scipy.signal.filtfilt
。如果您要使用 filtfilt
或 lfilter
,过滤器必须是数字的。
要使用连续时间系统,请查看函数
scipy.signal.impulse
(scipy.signal.impulse2
)
scipy.signal.step
(scipy.signal.step2
)
scipy.signal.lsim
(scipy.signal.lsim2
)
(2
版本解决了与没有 2
的版本相同的数学问题,但使用了不同的方法。在大多数情况下,没有 2
的版本很好并且是 比 2
版本快很多。)
其他相关函数和 类 列在 SciPy 文档的 Continuous-Time Linear Systems 部分。
例如,这是一个绘制贝塞尔滤波器脉冲响应和阶跃响应的脚本:
import numpy as np
from scipy.signal import bessel, step, impulse
import matplotlib.pyplot as plt
order = 4
Wn = 2*np.pi * 2000
b, a = bessel(order, Wn, btype='low', analog=True, output='ba', norm='phase')
# Note: the upper limit for t was chosen after some experimentation.
# If you don't give a T argument to impulse or step, it will choose a
# a "pretty good" time span.
t = np.linspace(0, 0.00125, 2500, endpoint=False)
timp, yimp = impulse((b, a), T=t)
tstep, ystep = step((b, a), T=t)
plt.subplot(2, 1, 1)
plt.plot(timp, yimp, label='impulse response')
plt.legend(loc='upper right', framealpha=1, shadow=True)
plt.grid(alpha=0.25)
plt.title('Impulse and step response of the Bessel filter')
plt.subplot(2, 1, 2)
plt.plot(tstep, ystep, label='step response')
plt.legend(loc='lower right', framealpha=1, shadow=True)
plt.grid(alpha=0.25)
plt.xlabel('t')
plt.show()
脚本生成此图:
我一直在尝试使用 scipy.signal 实现截止频率为 2kHz 的模拟贝塞尔滤波器,但我对要设置的 Wn 值感到困惑,因为文档指出 Wn(对于模拟滤波器)应该设置为 angular 频率(约 12000 rad/s)。但是,如果我将此应用于我的 1 秒虚拟数据,并以 500 000 Hz 采样半秒脉冲,我会得到一串 0 和 nans。我缺少什么?
import numpy as np
import scipy
import matplotlib.pyplot as plt
import scipy.signal
def make_signal(pulse_length, rate = 500000):
new_x = np.zeros(rate)
end_signal = 250000+pulse_length
new_x[250000:end_signal] = 1
data = new_x
print (np.shape(data))
# pad on both sides
data=np.concatenate((np.zeros(rate),data,np.zeros(rate)))
return data
def conv_time(t):
pulse_length = t * 500000
pulse_length = int(pulse_length)
return pulse_length
def make_data(ti): #give time in seconds
pulse_length=conv_time(ti)
print (pulse_length)
data = make_signal(pulse_length)
return data
time_scale = np.linspace(0,1,500000)
data = make_data(0.5)
[b,a] = scipy.signal.bessel(4, 12566.37, btype='low', analog=True, output='ba', norm='phase', fs=None)
output_signal = scipy.signal.filtfilt(b, a, data)
plt.plot(data[600000:800000])
plt.plot(output_signal[600000:800000])
当使用频率绘制响应时,对我来说似乎还不错;我哪里弄错了?
您正在将模拟滤波器传递给需要数字(即离散时间)滤波器的函数 scipy.signal.filtfilt
。如果您要使用 filtfilt
或 lfilter
,过滤器必须是数字的。
要使用连续时间系统,请查看函数
scipy.signal.impulse
(scipy.signal.impulse2
)scipy.signal.step
(scipy.signal.step2
)scipy.signal.lsim
(scipy.signal.lsim2
)
(2
版本解决了与没有 2
的版本相同的数学问题,但使用了不同的方法。在大多数情况下,没有 2
的版本很好并且是 比 2
版本快很多。)
其他相关函数和 类 列在 SciPy 文档的 Continuous-Time Linear Systems 部分。
例如,这是一个绘制贝塞尔滤波器脉冲响应和阶跃响应的脚本:
import numpy as np
from scipy.signal import bessel, step, impulse
import matplotlib.pyplot as plt
order = 4
Wn = 2*np.pi * 2000
b, a = bessel(order, Wn, btype='low', analog=True, output='ba', norm='phase')
# Note: the upper limit for t was chosen after some experimentation.
# If you don't give a T argument to impulse or step, it will choose a
# a "pretty good" time span.
t = np.linspace(0, 0.00125, 2500, endpoint=False)
timp, yimp = impulse((b, a), T=t)
tstep, ystep = step((b, a), T=t)
plt.subplot(2, 1, 1)
plt.plot(timp, yimp, label='impulse response')
plt.legend(loc='upper right', framealpha=1, shadow=True)
plt.grid(alpha=0.25)
plt.title('Impulse and step response of the Bessel filter')
plt.subplot(2, 1, 2)
plt.plot(tstep, ystep, label='step response')
plt.legend(loc='lower right', framealpha=1, shadow=True)
plt.grid(alpha=0.25)
plt.xlabel('t')
plt.show()
脚本生成此图: