Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的IIR响应_Python_Filter_Response - Fatal编程技术网

Python中的IIR响应

Python中的IIR响应,python,filter,response,Python,Filter,Response,我有一个新问题与Python直接相关-内置在Python中我有一个具有给定特性的二阶IIR带通滤波器[以下代码是故意惯用的]: fs = 40e6 # 40 MHz f sample frequency fc = 1e6/fs # 1 MHz center cutoff BW = 20e3/fs # 20 kHz bandwidth fl = (fc - BW/2)/fs # 0.99 MHz f lower cutoff fh = (fc +

我有一个新问题与Python直接相关-内置在Python中我有一个具有给定特性的二阶IIR带通滤波器[以下代码是故意惯用的]:

fs = 40e6           # 40 MHz f sample frequency
fc = 1e6/fs         # 1 MHz center cutoff
BW = 20e3/fs        # 20 kHz bandwidth 
fl = (fc - BW/2)/fs # 0.99 MHz f lower cutoff
fh = (fc + BW/2)/fs # 1.01 MHz f higher cutoff
其中给出了系数:

R  = 1 - (3*BW)
K  = (1 - 2*R*np.cos(2*np.pi*fc) + (R*R)) / (2 - 2*np.cos(2*np.pi*fc))

a0 = 1 - K                       # a0 =  0.00140
a1 = 2*(K-R)*np.cos(2*np.pi*fc)  # a1 =  0.00018 
a2 = (R*R) - K                   # a2 = -0.00158

b1 = 2*R*np.cos(2*np.pi*fc)      # b1 =  1.97241
b2 = -(R*R)                      # b2 = -0.99700
正如我所建议的,我已经使用了scipy.signal.freqz,但遗憾的是没有得到我想要的响应——也就是说,我相信过滤器可以按预期工作(代码如下)。以下是freqz的结果:

我的问题是:如何生成更像预期响应的图形?

代码:


用线性x标度你看不到任何漂亮的东西。我不知道numpy,但我熟悉matlab,有一些函数可以在日志中进行绘图。尝试将x-log比例用于:

import matplotlib.pyplot  as pyplot
fig = pyplot.figure()
ax = fig.add_subplot(2,1,1)    
line, = ax.plot(w/np.max(w), h_dB, color='blue', lw=2)
ax.set_xscale('log')

show()
顺便说一句,我没有测试它,我没有安装python:(

编辑:

我尝试在matlab中为一个IIR滤波器阶数为4和一个IIR滤波器阶数为20的butterworth滤波器建模

%!/usr/local/bin/matlab

%% Inputs
fs = 40e6;
fc = 1e6;
BW = 20e3;
fl = (fc - BW/2);
fh = (fc + BW/2);

%% Build bandpass filter IIR Butterworth order 4
N   = 4;        % Filter Order
h  = fdesign.bandpass('N,F3dB1,F3dB2', N, fl, fh, fs);
Hd1 = design(h, 'butter');

%% Build bandpass filter IIR Butterworth order 50
N   = 20;        % Filter Order
h  = fdesign.bandpass('N,F3dB1,F3dB2', N, fl, fh, fs);
Hd2 = design(h, 'butter');

%% Compare
fvtool(Hd1,Hd2);

这里是第一个滤波器的系数A和B:

FilterStructure: 'Direct-Form II Transposed'                                               
A: [2.46193004641106e-06 0 -4.92386009282212e-06 0 2.46193004641106e-06]     
B: [1 -3.94637005453608 5.88902106889851 -3.93761314372475 0.995566972065978]

如果我有时间,我会尝试对numpy做同样的事情。

问题是
signal.freqz
返回半圆上的点…所以你不能扩展到更大的
x
,除非你通过
signal.freqz
来实现。我试着戳了戳它,我发现你可以使用pass
whole=True
signal.freqz
,你会得到上面的结果,但是镜像到负数
x
。所以不是这样。但是,还有一个关键字参数,允许你传递你想要的
signal.freqz
点数组np.arange(-5,5,0.1)…它看起来一点也不像你期望的右边的曲线图——它看起来像是原始曲线图的一束反射。所以我想…也许右边的曲线图和左边的曲线图有不同的轴?具体来说,是一个角频率,而另一个只是普通的旧频率

进一步拨动后,
signal.freqz
返回
w,h
,其中
w
是以弧度/采样为单位的标准化角频率。因此,您不需要通过
np.max(w)进行标准化
在您的代码中进行绘图。但是,这仍然不能解决问题。右侧的绘图似乎以
fc
为单位,并且
fc
以MHz为单位(例如1/样本)

因此,要使左边的图与右边的图匹配,我想这意味着你需要“非标准化”你的
x
轴,然后你需要转换成MHz的角频率单位


或者,更可能的情况是,使用不同于
信号的函数。freqz

我不认为问题在于您绘制响应的方式-这取决于您选择的过滤器。您正在尝试仅使用低阶IIR过滤器创建非常窄的过滤器响应。我认为您要么需要高阶过滤器,要么放松约束ts

例如,下面使用了一个实现为IIR的butterworth过滤器,它给出的响应形状与您正在寻找的形状更为相似。显然,要获得预期的过滤器特性,还需要做更多的工作

    b, a = signal.butter(4, [1.0/4-1.0/2e2,1.0/4+1.0/2e2], 'bandpass', analog=False)
    w, h = signal.freqs(b, a)

    import matplotlib.pyplot as plt
    fig = plt.figure()
    plt.title('Digital filter frequency response')
    ax1 = fig.add_subplot(111)
    plt.semilogy(w, np.abs(h), 'b')

    plt.ylabel('Amplitude (dB)', color='b')
    plt.xlabel('Frequency (rad/sample)')
    ax2 = ax1.twinx()

    angles = np.unwrap(np.angle(h))
    plt.plot(w, angles, 'g')
    plt.ylabel('Angle (radians)', color='g')
    plt.grid()
    plt.axis('tight')
    plt.show()
其中:


我想知道代码中的
Fc
Ft
是什么?它们以前没有定义。我应该很清楚:Fc是由采样频率(fs)归一化的中心频率。Ft与Fc(打字错误)相同--根据您的评论,方程式取自我将
Fc
改为
Fc
Ft
改为
Fc
。感谢您澄清了这一点,Jan Philip并没有解决这个问题。更简单的方法是执行
plt.semilogx()
(或者,对于其他人来说,
plt.semilogy())
plt.loglog
)。您可以在预先存在的绘图上执行它们,也可以将它们用作
plt.plot
。Pro提示:在交互模式下,按
L
K
切换对数轴(仅当0不在绘图上时有效,但您可以移动它).不。这对您完全没有任何作用。将比例更改为对数比例无法显示更多的点。基本上,您得到的绘图与线性比例绘图相同。您需要在不同的范围内绘图。
    b, a = signal.butter(4, [1.0/4-1.0/2e2,1.0/4+1.0/2e2], 'bandpass', analog=False)
    w, h = signal.freqs(b, a)

    import matplotlib.pyplot as plt
    fig = plt.figure()
    plt.title('Digital filter frequency response')
    ax1 = fig.add_subplot(111)
    plt.semilogy(w, np.abs(h), 'b')

    plt.ylabel('Amplitude (dB)', color='b')
    plt.xlabel('Frequency (rad/sample)')
    ax2 = ax1.twinx()

    angles = np.unwrap(np.angle(h))
    plt.plot(w, angles, 'g')
    plt.ylabel('Angle (radians)', color='g')
    plt.grid()
    plt.axis('tight')
    plt.show()