我是Python的新手,在过滤信号时我完全陷入困境。这是代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
fs=105e6
fin=70.1e6
N=np.arange(0,21e3,1)
# Create a input sin signal of 70.1 MHz sampled at 105 MHz
x_in=np.sin(2*np.pi*(fin/fs)*N)
# Define the "b" and "a" polynomials to create a CIC filter (R=8,M=2,N=6)
b=np.zeros(97)
b[[0,16,32,48,64,80,96]]=[1,-6,15,-20,15,-6,1]
a=np.zeros(7)
a[[0,1,2,3,4,5,6]]=[1,-6,15,-20,15,-6,1]
w,h=signal.freqz(b,a)
plt.plot(w/max(w),20*np.log10(abs(h)/np.nanmax(h)))
plt.title('CIC Filter Response')
output_nco_cic=signal.lfilter(b,a,x_in)
plt.figure()
plt.plot(x_in)
plt.title('Input Signal')
plt.figure()
plt.plot(output_nco_cic)
plt.title('Filtered Signal')
情节:
如您所见,虽然过滤器传递函数是正确的,但输出不是。我无法理解为什么我的代码不起作用。我在Matlab中编写了相同的代码,输出看起来还不错。
请求帮助!
答案 0 :(得分:7)
我并不觉得这与Python没有用,这让人感到困惑,但我确实发现它与Matlab一起工作令人困惑。
CIC过滤器不支持浮点数。
更新:
有趣的是,至少对于我所拥有的scipy版本,lfilter不能处理整数数组 - 我得到一个NotImplemented错误。这是一个CIC过滤器的numpy版本,大约是我机器上纯Python实现的两倍:
# Implements an in-memory CIC decimator using numpy.
from math import log
from numpy import int32, int64, array
def cic_decimator(source, decimation_factor=32, order=5, ibits=1, obits=16):
# Calculate the total number of bits used internally, and the output
# shift and mask required.
numbits = order * int(round(log(decimation_factor) / log(2))) + ibits
outshift = numbits - obits
outmask = (1 << obits) - 1
# If we need more than 64 bits, we can't do it...
assert numbits <= 64
# Create a numpy array with the source
result = array(source, int64 if numbits > 32 else int32)
# Do the integration stages
for i in range(order):
result.cumsum(out=result)
# Decimate
result = array(result[decimation_factor - 1 : : decimation_factor])
# Do the comb stages. Iterate backwards through the array,
# because we use each value before we replace it.
for i in range(order):
result[len(result) - 1 : 0 : -1] -= result[len(result) - 2 : : -1]
# Normalize the output
result >>= outshift
result &= outmask
return result
答案 1 :(得分:1)
代码很好,lfilter在它创建的float64数组上运行良好。但是分母多项式“a”的所有根都在z = 1,这使得滤波器“条件稳定”。由于数字上的不准确性,它最终会发生分歧。并且70.1 MHz处的输入信号远离通带,因此它在输出中不会显示太多。如果您将输入更改为0.701 MHz或其左右,并将信号缩短为1000个样本而不是21000,您将看到它按原样工作。尝试这些更改,您将看到之后会发生什么: 鳍= 70.1e4 N = np.arange(0,2000,1) (并且通过零投诉摆脱鸿沟,在log10中添加1.0e-12)
要正确执行CIC,您需要一个能够正确处理条件稳定极点的实现。