Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.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 使用FFTs计算滤波器(b,a,x,zi)_Python_Matlab_Filter_Signal Processing_Octave - Fatal编程技术网

Python 使用FFTs计算滤波器(b,a,x,zi)

Python 使用FFTs计算滤波器(b,a,x,zi),python,matlab,filter,signal-processing,octave,Python,Matlab,Filter,Signal Processing,Octave,我想尝试使用FFT而不是在时域中计算y=filter(b,a,x,zi)和dy[I]/dx[j],以在GPU实现中实现可能的加速 我不确定这是否可能,尤其是当zi为非零时。我研究了如何实现scipy中的scipy.signal.lfilter和倍频程中的filter。它们都是直接在时域中完成的,scipy使用直接形式2和倍频程直接形式1(通过查看DLD-FUNCTIONS/filter.cc中的代码)。我还没有在MATLAB中看到类似FIR滤波器的FFT实现(即a=[1.]) 我试着做了y=if

我想尝试使用FFT而不是在时域中计算
y=filter(b,a,x,zi)
dy[I]/dx[j]
,以在GPU实现中实现可能的加速

我不确定这是否可能,尤其是当
zi
为非零时。我研究了如何实现scipy中的
scipy.signal.lfilter
和倍频程中的
filter
。它们都是直接在时域中完成的,scipy使用直接形式2和倍频程直接形式1(通过查看
DLD-FUNCTIONS/filter.cc
中的代码)。我还没有在MATLAB中看到类似FIR滤波器的FFT实现(即a=[1.])

我试着做了
y=ifft(fft(b)/fft(a)*fft(x))
,但这在概念上似乎是错误的。此外,我不确定如何处理初始瞬态
zi
。如有任何参考资料,或指向现有实现,将不胜感激

示例代码

import numpy as np
import scipy.signal as sg
import matplotlib.pyplot as plt

# create an IRR lowpass filter
N = 5
b, a = sg.butter(N, .4)
MN = max(len(a), len(b))

# create a random signal to be filtered
T = 100
P = T + MN - 1
x = np.random.randn(T)
zi = np.zeros(MN-1)

# time domain filter
ylf, zo = sg.lfilter(b, a, x, zi=zi)

# frequency domain filter
af = sg.fft(a, P)
bf = sg.fft(b, P)
xf = sg.fft(x, P)
yfft = np.real(sg.ifft(bf/af * xf))[:T]

# error
print np.linalg.norm(yfft - ylf)

# plot, note error is larger at beginning and with larger N
plt.figure(1)
plt.clf()
plt.plot(ylf)
plt.plot(yfft)

我已经忘记了我对FFT所知甚少,但您可以查看sedit.py和frequency.py at,看看是否有任何帮助。

尝试
scipy.signal.lfiltic(b,a,y,x=None)
以获得初始条件

lfiltic
的文档文本:

Given a linear filter (b,a) and initial conditions on the output y
and the input x, return the inital conditions on the state vector zi
which is used by lfilter to generate the output given the input.

If M=len(b)-1 and N=len(a)-1.  Then, the initial conditions are given
in the vectors x and y as

x = {x[-1],x[-2],...,x[-M]}
y = {y[-1],y[-2],...,y[-N]}

If x is not given, its inital conditions are assumed zero.
If either vector is too short, then zeros are added
  to achieve the proper length.

The output vector zi contains

zi = {z_0[-1], z_1[-1], ..., z_K-1[-1]}  where K=max(M,N).

通过将
p=T+MN-1
替换为
p=T+2*MN-1
,可以减少现有实现中的错误。这纯粹是直观的,但在我看来,
bf
af
的划分将需要
2*MN
术语,这是由于概括


C.S.Burrus有一本非常简洁的书,讲述了如何以面向块的方式考虑滤波,无论是FIR还是IIR。我没有详细阅读,但我认为它提供了通过卷积实现IIR滤波所需的方程,包括中间状态。

谢谢。这段代码似乎可以计算声音信号的功率谱。我无法找到通过FFT进行IRR过滤的位置。谢谢Steve。给定zi,那么如何使用FFTs计算y[0:T](例如,在scipy.signal.fftconvolve中就是这样做的)?这就是我的问题。似乎错误会随着填充的增加而减少,但不会消除。这就是为什么我认为我的FFT尝试在概念上有缺陷。谢谢Burrus的推荐信。目前,我不需要实现块式滤波器,因为t很小。如果t很小,那么我假设IIR滤波器的脉冲响应也很短。我建议将脉冲响应窗口化,放弃频率响应中的一些锐度,并将其视为FIR。这至少在概念上是合理的。你的方法感觉不错,但我不完全相信……如果我可以自由设计过滤器,这听起来是个好主意。在本例中,我被赋予了精确计算过滤器(b,a,x,zi)的任务。我不允许将滤波器转换为FIR。FFT相乘会产生循环卷积。因此,只有当T和滤波器的脉冲响应都是有限的,并且FFT大小大于两者之和时,FFT滤波才是精确的。否则你会得到“错误”。@hotpaw2,我想结论是你不能天真地将FFT用于IIR过滤器。我需要学习更多的信号处理!