def calcFiltros(A1,A2,Wc,Wp): plt.figure() Nb, Wnb = signal.buttord(Wp,Wc,A1,A2,True) Nc, Wnc = signal.cheb1ord(Wp,Wc,A1,A2,True) Ne, Wne = signal.ellipord(Wp,Wc,A1,A2,True) print('Butterbord Wp =' + str(Wp)) print("N = "+ str(Nb) ) print("Wn = "+ str(Wnb) ) Zb,Pb,Kb = signal.buttap(Nb) ab,bb = signal.zpk2tf(Zb,Pb,Kb) print("H(s) = ") strFunTrans = funTrans([ab,bb]) print(strFunTrans) print("\n") wb, hb = freqs(ab, bb) plt.semilogx(wb, abs(hb)) print('Chebychev Wp =' + str(Wp)) print("N = "+ str(Nc) ) print("Wn = "+ str(Wnc) ) Zc,Pc,Kc = signal.buttap(Nc) ac,bc = signal.zpk2tf(Zc,Pc,Kc) print("H(s) = ") strFunTrans = funTrans([ac,bc]) print(strFunTrans) print("\n") wc, hc = freqs(ac, bc) plt.semilogx(wc, abs(hc)) print('Eliptica Wp =' + str(Wp)) print("N = "+ str(Ne) ) print("Wn = "+ str(Wne) ) Ze,Pe,Ke = signal.buttap(Ne) ae,be = signal.zpk2tf(Ze,Pe,Ke) print("H(s) = ") strFunTrans = funTrans([ae,be]) print(strFunTrans) print("\n") we, he = freqs(ae, be) plt.semilogx(we, abs(he)) plt.xlabel('Frequency') plt.ylabel('Amplitude response') plt.grid()
def compute_normalised_by_order(self, ap, n, aa) -> ApproximationErrorCode: """ Generates normalised transfer function prioritising the fixed order """ # Computing needed constants epsilon = self.compute_epsilon(ap) factor = 1 / np.float_power(epsilon, 1 / n) # Getting the Butterworth approximation for the given order # and matching it with the given maximum attenuation for pass band zeros, poles, gain = ss.buttap(n) new_zeros = zeros new_poles = [factor * pole for pole in poles] new_gain = gain # Updating the local transfer function, no errors! self.h_aux = ss.ZerosPolesGain(new_zeros, new_poles, new_gain) return ApproximationErrorCode.OK
def butter(N, Wn, btype="lowpass", output="sos", fs=None): """ A modified filter design that will return a suite of Butterworth filters, for all the provided Wn values. """ try: btype = signal.filter_design.band_dict[btype] except KeyError as e: raise ValueError("'{}' is an invalid bandtype.".format(btype)) from e Wn = np.asarray(Wn) if fs is not None: Wn = 2 * Wn / fs # generate the single Nth-order filter at 1 rad/s cutoff z, p, k = signal.buttap(N) fs = 2.0 warped = 2 * fs * np.tan(np.pi * Wn / fs) if btype == "lowpass": z, p, k = lp2lp_zpk(z, p, k, wo=warped) elif btype == "highpass": z, p, k = lp2hp_zpk(z, p, k, wo=warped) else: raise NotImplementedError( "'{}' is not a supported bandtype".format(btype)) # after this point, z, p, k are arrays of multiple filters: # for z, p: axis 0 is the "normal" shape; axis 1 is filter number # k is an array with length number of filters z, p, k = bilinear_zpk_multiple(z, p, k, fs=fs) if output == "zpk": return z, p, k elif output == "ba": return zpk2tf_multiple(z, p, k) elif output == "sos": return zpk2sos_multiple(z.astype(np.complex_), p.astype(np.complex_), k)
p = b[0] q = a[0] for k in range(1, len(b)): p += b[k] * np.power(z, -k) for k in range(1, len(a)): q += a[k] * np.power(z, -k) return p / q # Absolute value in decibel def abs_db(h): return 20 * np.log10(np.abs(h)) # Poles of analog low-pass prototype none, S, none = signal.buttap(M) # Band limits c = np.power(2, 1 / 12.0) f_l = f0 / c f_u = f0 * c # Analog frequencies in radians w0 = 2 * np.pi * f0 w_l = 2 * np.pi * f_l w_u = 2 * np.pi * f_u # Relative bandwidth rbw = (w_u - w_l) / w0 jw0 = 2j * np.pi * f0
""" from splane import bodePlot, pzmap from matplotlib import pyplot as plt import scipy.signal as sig from scipy.signal import TransferFunction as tf import numpy as np plt.close('all') ripple_ = 3 # Ripple en la Banda de Paso, alfa_máx en dB fp = 1000 #wp = 2*np.pi*fp wp = 1 # Omega_p Normalizado. order_filter = 2 z, p, k = sig.buttap(order_filter) # No Le Interesa el valor de epsilon. NUM, DEN = sig.zpk2tf(z, p, k) my_tf = tf(NUM, DEN) #Ploteo: bodePlot(my_tf) pzmap(my_tf) # Plano $ - Diagrama de Polos y Ceros
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed May 8 23:19:00 2019 @author: mariano """ import scipy.signal as sig import numpy as np from splane import analyze_sys, pzmap, grpDelay, bodePlot z, p, k = sig.buttap(3) num_lp, den_lp = sig.zpk2tf(z, p, k) eps = np.sqrt(10**(0.1) - 1) num_lp_d, den_lp_d = sig.lp2lp(num_lp, den_lp, eps**(-1 / 3)) num_hp_d, den_hp_d = sig.lp2hp(num_lp_d, den_lp_d) num_hp_d, den_hp_d = sig.lp2hp(num_lp, den_lp, eps**(-1 / 3)) #%matplotlib qt5 analyze_sys([sig.TransferFunction(num_lp, den_lp)], ['mp_norm']) analyze_sys([sig.TransferFunction(num_lp_d, den_lp_d)], ['mp_desnorm'])
attenuation = [40, 40, 40] # dB \alpha_{min} <-- Sin parametrizar, att fija #attenuation = [20, 40, 60] # dB \alpha_{min} #orders2analyze = [2, 2, 2] # <-- Sin parametrizar, orden fijo orders2analyze = [2, 3, 4] all_sys = [] filter_names = [] for (this_order, this_ripple, this_att) in zip(orders2analyze, ripple, attenuation): if aprox_name == 'Butterworth': z, p, k = sig.buttap(this_order) eps = np.sqrt(10**(this_ripple / 10) - 1) num, den = sig.zpk2tf(z, p, k) num, den = sig.lp2lp(num, den, eps**(-1 / this_order)) z, p, k = sig.tf2zpk(num, den) elif aprox_name == 'Chebyshev1': z, p, k = sig.cheb1ap(this_order, this_ripple) elif aprox_name == 'Chebyshev2': z, p, k = sig.cheb2ap(this_order, this_ripple)
# Normalizo a Nivel de Frecuencia, norma = wp_hp wp_hp_n = wp_hp / wp_hp w_zt_hp_n = w_zt_hp / wp_hp # ---------------------------------------------------------------------------- # Filtro Prototipo Low-Pass: # Transformación en Frecuencia: ====> w_hp = -1 / w_lp wp_lp_n = -1 / wp_hp_n wp_lp_n = np.abs(wp_lp_n) w_zt_lp_n = -1 / w_zt_hp_n w_zt_lp_n = np.abs(w_zt_lp_n) z_lp_n, p_lp_n, k_lp_n = sig.buttap(orden_filtro) NUM_LP_n, DEN_LP_n = sig.zpk2tf(z_lp_n, p_lp_n, k_lp_n) NUM_LP_n = [1, 0, 9] # Le agrego el cero de transmisión. my_tf_lp_n = transf_f(NUM_LP_n, DEN_LP_n) bodePlot(my_tf_lp_n) pzmap(my_tf_lp_n) # ---------------------------------------------------------------------------- # Filtro Destino High-Pass: NUM_HP_n, DEN_HP_n = sig.lp2hp(NUM_LP_n, DEN_LP_n) z_hp_n, p_hp_n, k_hp_n = sig.tf2zpk(NUM_HP_n, DEN_HP_n)
# Prewarp fpw = fs # sin prewarp #fpw = np.pi*fc/np.tan(np.pi*fc/fs); # prewarp para fc all_sys = [] analog_filters = [] digital_filters = [] filter_names = [] analog_filters_names = [] digital_filters_names = [] if aprox_name == 'Butterworth': z, p, k = sig.buttap(order2analyze) elif aprox_name == 'Chebyshev1': z, p, k = sig.cheb1ap(order2analyze, ripple) elif aprox_name == 'Chebyshev2': z, p, k = sig.cheb2ap(order2analyze, ripple) elif aprox_name == 'Bessel': z, p, k = sig.besselap(order2analyze, norm='mag') elif aprox_name == 'Cauer':
orden_filtro = np.log( ((10**(attenuation_ / 10) - 1) / (eps**2))) / (2 * np.log(ws_lp_prima)) N = orden_filtro if (orden_filtro >= (int(orden_filtro) + 0.05)): orden_filtro = int(orden_filtro) + 1 # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Hallo el Numerador y Denominador de mi Transferencia Prototipo Low-Pass # Calculo los Ceros, Polos y K(Ganancia) de mi filtro, según el Orden. z, p, k = sig.buttap( orden_filtro) # Aprox. Butterworth ==> No le importa el eps. # Calculo del Numerador y Denominador NUM, DEN = sig.zpk2tf(z, p, k) # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Genero el Filtro Prototipo Low Pass if (eps != 1): # Caso de Máxima Planicidad!! wb_lp = eps**(-1 / orden_filtro) # Omega de Butterworth Low Pass NUM_lp, DEN_lp = sig.lp2lp(NUM, DEN, wb_lp) # Renormalizo con wb_lp else:
t = np.linspace(t0, tf, N) # array temporal de 601 muestras equispaciadas Ts. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Diseño los Filtros Normalizados de Orden 5 para Luego Compararlos: orden_filtro = 5 # Orden de los Filtros. eps = 0.311 # ---------------------------------------------------------------------------- print('\n\nFiltro Butterworth de Orden 5:\n') # Filtro de Butterworth: Uso de los Métodos dentro del Paquete signal de Scipy. z1, p1, k1 = sig.buttap(orden_filtro) # Obtengo los Coeficientes de mi Transferencia. NUM1, DEN1 = sig.zpk2tf(z1, p1, k1) # Cálculo de wb: wb = eps**(-1 / orden_filtro) # Obtengo la Transferencia Normalizada my_tf_bw = tfunction(NUM1, DEN1) print('\n', my_tf_bw) #pretty_print_lti(my_tf_bw) print('\nDenominador Factorizado de la Transferencia Normalizada:', convert2SOS(my_tf_bw))
#Víctor Hugo Flores Pineda 155990 #Rebeca Baños #Python 3 import numpy as np import matplotlib.pyplot as plt from scipy import signal as sg N, Wn = sg.buttord(1, 2, 2, 14, True) print(N) print(Wn) N, Wn = sg.buttord(1, 1.5, 2, 14, True) print(N) print(Wn) N, Wn = sg.buttord(1, 1.3, 2, 14, True) print(N) print(Wn) z, p, k = sg.buttap(N)
#aprox_name = 'Cauer' # Requerimientos de plantilla ripple = 0.5 attenuation = 40 orders2analyze = range(2,7) all_sys = [] filter_names = [] for ii in orders2analyze: if aprox_name == 'Butterworth': z,p,k = sig.buttap(ii) elif aprox_name == 'Chebyshev1': z,p,k = sig.cheb1ap(ii, ripple) elif aprox_name == 'Chebyshev2': z,p,k = sig.cheb2ap(ii, ripple) elif aprox_name == 'Bessel': z,p,k = sig.besselap(ii, norm='mag') elif aprox_name == 'Cauer':
order_filter = np.log( (10**(attenuation_ / 10) - 1) / (eps**2)) / (2 * np.log(ws_prima)) N = order_filter # En caso de que N sea decimal redondeo al nro entero mas grande if (order_filter >= (int(order_filter) + 0.05)): order_filter = int(order_filter) + 1 # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Calculo de Ceros, Polos y Ganancia(k) dado el Orden del Filtro. Low-Pass z, p, k = sig.buttap( int(order_filter)) #Filtro Butterworth / no le importa el eps my_k = 10 # Agrego la Ganacia que Deseo: my_k (en veces) k = my_k * k # Ganancia Total del Filtro NUM, DEN = sig.zpk2tf(z, p, k) # Genero el Numerador y Denominador # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Se ejecuta Únicamente si estoy en el Caso de MÁXIMA PLANICIDAD !!! eps != 1 if (eps != 1): wb = eps**(-1 / order_filter) #Omega de Butterworth NUM, DEN = sig.lp2lp(NUM, DEN, wb) # Renormalizo para wb
#aprox_name = "Bessel" print('\nIngrese Ripple (alfa_máx) en dB: ') ripple_ = float ( input( ) ) ## Valor de alfa_máx en dB # Máxima Atenuación Band Pass print('\nIngrese Atenuación Mínima (alfa_mín) en dB: ') attenuation_ = float ( input( ) ) # Valor de alfa_mín en dB # Mínima Atenuación Band Stop print ('\nIngrese Orden (Nro. Entero): ') order_filter = int ( input ( ) ) if ( aprox_name == "Butterworth" ): # Paso el Orden y devuelve ceros, polos y Ganancia z, p, k = sig.buttap (order_filter) # No le Interesa el ripple # Cálculo del Epsilon (Ripple) eps = np.sqrt ( 10**(ripple_/10) - 1 ) wb = eps**(-1/order_filter) # Omega_Butter / Renormalización. NUM, DEN = sig.zpk2tf (z, p, k) NUM, DEN = sig.lp2lp ( NUM, DEN, wb ) z, p, k = sig.tf2zpk ( NUM, DEN ) elif (aprox_name == 'Chebyshev1'): # Le paso Orden y ripple (alfa_máx)
Created on Wed May 8 23:14:49 2019 @author: mariano """ import scipy.signal as sig import numpy as np from splane import analyze_sys, pzmap, grpDelay, bodePlot, pretty_print_lti nn = 2 # orden ripple = 1 # dB eps = np.sqrt(10**(ripple / 10) - 1) # Diseño un Butter. z, p, k = sig.buttap(nn) num_lp, den_lp = sig.zpk2tf(z, p, k) # paso de un Butter. a maxima planicidad si eps != 1 num_lp_butter, den_lp_butter = sig.lp2lp(num_lp, den_lp, eps**(-1 / nn)) # obtengo la transferencia normalizada del pasabanda num_bp_n, den_bp_n = sig.lp2bp(num_lp_butter, den_lp_butter, wo=1, bw=1 / .253) # obtengo la transferencia desnormalizada del pasabanda num_bp, den_bp = sig.lp2bp(num_lp_butter, den_lp_butter, wo=8.367, bw=33) # Averiguo los polos y ceros z_bp_n, p_bp_n, k_bp_n = sig.tf2zpk(num_bp_n, den_bp_n) str_aux = 'Pasabanda normalizado'