簡體   English   中英

使用Python lfilter過濾信號

[英]Filtering signal with Python lfilter

我是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中編碼相同,輸出看起來還不錯。

多克斯尋求幫助!

我不覺得這對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

代碼很好,lfilter在它創建的float64數組上工作正常。 但是分母多項式“a”的所有根都在z = 1,這使得濾波器“條件穩定”。 由於數字上的不准確性,它最終會發生分歧。 並且70.1 MHz處的輸入信號遠離通帶,因此它在輸出中不會顯示太多。 如果您將輸入更改為0.701 MHz或其左右,並將信號縮短為1000個樣本而不是21000,您將看到它按原樣工作。 嘗試這些更改,你會看到之后會發生什么:fin = 70.1e4 N = np.arange(0,2000,1)(並且為了擺脫除以0的投訴,在log10中添加1.0e-12)

要正確執行CIC,您需要一個能夠正確處理條件穩定極點的實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM