La respuesta de frecuencia para el filtro diseñado con la
función de mantequilla es:
Pero no hay razón para limitar el filtro a un diseño de filtro monotónico constante. Si desea una mayor atenuación en la banda de parada y la banda de transición más pronunciada, existen otras opciones. Para obtener más información sobre cómo especificar un filtro mediante iirdesing, consulte esto . Como se muestra en las gráficas de respuesta de frecuencia para el diseño de mantequilla , la frecuencia de corte (punto de -3dB) está lejos del objetivo. Esto puede aliviarse mediante un muestreo descendente antes del filtrado (las funciones de diseño tendrán dificultades con un filtro tan estrecho, el 2% del ancho de banda). Veamos cómo filtrar la frecuencia de muestreo original con el límite especificado.
import numpy as np
from scipy import signal
from matplotlib import pyplot as plt
from scipy.signal import fir_filter_design as ffd
from scipy.signal import filter_design as ifd
# setup some of the required parameters
Fs = 1e9 # sample-rate defined in the question, down-sampled
# remez (fir) design arguements
Fpass = 10e6 # passband edge
Fstop = 11.1e6 # stopband edge, transition band 100kHz
Wp = Fpass/(Fs) # pass normalized frequency
Ws = Fstop/(Fs) # stop normalized frequency
# iirdesign agruements
Wip = (Fpass)/(Fs/2)
Wis = (Fstop+1e6)/(Fs/2)
Rp = 1 # passband ripple
As = 42 # stopband attenuation
# Create a FIR filter, the remez function takes a list of
# "bands" and the amplitude for each band.
taps = 4096
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
# The iirdesign takes passband, stopband, passband ripple,
# and stop attenuation.
bc, ac = ifd.iirdesign(Wip, Wis, Rp, As, ftype='ellip')
bb, ab = ifd.iirdesign(Wip, Wis, Rp, As, ftype='cheby2')
Como se mencionó, debido a que estamos tratando de filtrar un porcentaje tan pequeño del ancho de banda, el filtro no tendrá un corte brusco. En este caso, filtro de paso bajo, podemos reducir el ancho de banda para obtener un filtro más atractivo. La función de remuestreo python / scipy.signal se puede usar para reducir el ancho de banda.
Tenga en cuenta que la función de remuestreo realizará el filtrado para evitar el alias. El prefiltrado también se puede realizar (para reducir el aliasing) y en este caso podríamos simplemente volver a muestrear en 100 y listo , pero se hizo la pregunta sobre la creación de filtros. Para este ejemplo, reduciremos la muestra en 25 y crearemos un nuevo filtro
R = 25; # how much to down sample by
Fsr = Fs/25. # down-sampled sample rate
xs = signal.resample(x, len(x)/25.)
Si actualizamos los parámetros de diseño para el filtro FIR, la nueva respuesta es.
# Down sampled version, create new filter and plot spectrum
R = 25. # how much to down sample by
Fsr = Fs/R # down-sampled sample rate
Fstop = 11.1e6 # modified stopband
Wp = Fpass/(Fsr) # pass normalized frequency
Ws = Fstop/(Fsr) # stop normalized frequency
taps = 256
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
El filtro que opera en los datos muestreados abajo tiene una mejor respuesta. Otro beneficio de usar un filtro FIR es que tendrá una respuesta de fase lineal.