class LCladder(Filter): def __init__(self, R1, R2, fp, fs, gpass, gstop, ftype, btype): """ Variables init """ Filter.__init__(self, fp, fs, gpass, gstop, ftype, btype) self.R1 = R1 self.R2 = R2 self.units = Units() """ TEST DATA FOR CHEBY """ #self.gpass = 1.5 #self.ord = 4 #self.wn = np.pi * 100000.0 """ TEST DATA FOR BUTTER """ #self.ord = 5 #self.wn = 100000.0 if ftype == 'butter': self.alpha = self.alpha() elif ftype in ('cheby1', 'cheby2'): self.E = self.epsilon() self.gamma = self.gamma() self.a = self.a_help_var() self.a_ = self.a_prim_help_var() print("gamma ", self.gamma) print("epsilon ", self.E) print("a", self.a) print("a_ ", self.a_) #Frequency to pulsation self.wn = self.wn * np.pi * 2 def load_matched(self): """ Normalized matched LC ladder elements """ if self.R1 != self.R2: raise Exception("Load not matched!") sys.exit(1) elif self.ftype in ('cheby1', 'cheby2'): lc_ladder = self.load_not_matched() elif self.ftype == "butter": lc_ladder = [] for k in range(1, self.ord + 1): x = 2.0 * np.sin(((2.0*k-1.0)*np.pi)/(2.0*self.ord)) lc_ladder.append(x) lc_ladder = self.load_matched_denormalizer(lc_ladder) else: lc_ladder = None return lc_ladder def load_matched_denormalizer(self, elements): """ Denormalize normalized elements of matched LC ladder ciurcuit """ lc_ladder = {} id = 1 for element in elements: if id % 2 == 0: key = "C" unit = "F" element = element / (self.wn * self.R1) else: key = "L" unit = "H" element = element / self.R1 key = key + str(id) id = id + 1 lc_ladder[key] = np.around(self.units.rescale(element, unit), 3) return lc_ladder def load_not_matched(self): if self.R2 > self.R1: value_1 = self.coil_1() #Initial value initial_element_key = "L1" key_2 = 'C' value_2_unit = "F" key_1 = 'L' value_1_unit = "H" elif self.R2 < self.R1: value_1 = self.cap_1() #Initial value initial_element_key = "C1" key_2 = 'L' value_2_unit = "H" key_1 = 'C' value_1_unit = "F" else: if self.ftype == "butter": raise Exception("Load matched! Please execute LCladder.load_matched()") sys.exit(1) elif self.ftype in ("cheby1", "cheby2"): value_1 = self.coil_1() #Initial value initial_element_key = "L1" key_2 = 'C' value_2_unit = "F" key_1 = 'L' value_1_unit = "H" else: raise Exception("Unknown filter type.") sys.exit(1) lc_ladder = {} m = self.ord/2 lc_ladder[initial_element_key] = np.around(self.units.rescale(value_1, value_1_unit), 3) for m in range(1, m+1): if self.ftype == "butter": value_2 = (4.0 * np.sin(self.phi_m(4.0*m-3.0)) * np.sin(self.phi_m(4.0*m-1.0))) / (value_1 * np.power(self.wn, 2.0)*(1.0 - 2.0 * self.alpha*np.cos(self.phi_m(4.0*m-2.0))+np.power(self.alpha,2.0))) #2.65a value_1 = (4.0 * np.sin(self.phi_m(4.0*m-1.0)) * np.sin(self.phi_m(4.0*m+1.0))) / (value_2 * np.power(self.wn, 2.0)*(1.0 - 2.0 * self.alpha*np.cos(self.phi_m(4.0*m))+np.power(self.alpha,2.0))) #2.65b elif self.ftype in ("cheby1", "cheby2"): value_2 = (4.0 * np.sin(self.phi_m(4.0*m-3.0)) * np.sin(self.phi_m(4.0*m-1.0))) / (value_1 * np.power(self.wn, 2.0) * self.fm(2.0*m-1.0, np.sinh(self.a), np.sinh(self.a_))) value_1 = (4.0 * np.sin(self.phi_m(4.0*m-1.0)) * np.sin(self.phi_m(4.0*m+1.0))) / (value_2 * np.power(self.wn, 2.0) * self.fm(2.0*m, np.sinh(self.a), np.sinh(self.a_))) value_2_id = 2 * m value_2_key = key_2 + str(value_2_id) lc_ladder[value_2_key] = np.around(self.units.rescale(value_2, value_2_unit), 3) if len(lc_ladder) == self.ord: break value_1_id = 2 * m + 1 value_1_key = key_1 + str(value_1_id) lc_ladder[value_1_key] = np.around(self.units.rescale(value_1, value_1_unit), 3) return lc_ladder def phi_m(self, m): """ LC ladder help variable""" phi_m = (m * np.pi) / (2 * self.ord) #2.67 return phi_m def alpha(self): """ LC ladder help variable""" alpha = np.power(abs((self.R1-self.R2)/(self.R1+self.R2)), 1.0 / self.ord) #2.66 return alpha def cap_1(self): """Computing initial capacitor value""" if self.ftype == 'butter': cap_1 = (2.0 * np.sin(self.phi_m(1.0)))/(self.R1*(1.0-self.alpha) * self.wn) #2.68 elif self.ftype in ('cheby1', 'cheby2'): cap_1 = (2.0 * np.sin((np.pi/2.0)/self.ord))/(self.R1*(np.sinh(self.a) - np.sinh(self.a_)) * self.wn) #2.77 return cap_1 def coil_1(self): """Computing initial coil value""" if self.ftype == 'butter': coil_1 = (2.0 * self.R1 * np.sin(self.phi_m(1.0)))/((1.0-self.alpha) * self.wn) #2.64 elif self.ftype in ('cheby1', 'cheby2'): coil_1 = (2.0*self.R1*np.sin((np.pi/2.0)/self.ord))/((np.sinh(self.a) - np.sinh(self.a_)) * self.wn) #2.73 return coil_1 def a_help_var(self): """Chebyshev lc ladder help variable""" a = (1.0/4.0)*np.arcsinh(1.0/self.E) #2.72 return a def a_prim_help_var(self): """Chebyshev lc ladder help variable""" a_ = (1.0/self.ord)*np.arcsinh(((np.sqrt(1.0 - np.power(self.gamma, 2.0)))/(self.E))) #2.72 return a_ def gamma(self): """Power transfer ratio. Chebyshev lc ladder help variable""" #gamma = ((np.sqrt(self.R1*self.R2))*np.sqrt(1.0 + np.power(self.E, 2.0)))/((self.R1+self.R2)/2.0) gamma = ((np.sqrt(self.R1*self.R2)))/((self.R1+self.R2)/2.0) return gamma def epsilon(self): """Maximum pass band ripple. Chebyshev lc ladder help variable""" E = np.sqrt(np.power(10.0, self.gpass/10.0)-1.0) return E def fm(self, m, x, y): "Chebyshev lc ladder help variable" fm = np.power(x, 2) + np.power(y, 2) + np.power((np.sin(self.phi_m(2.0*m))),2) - 2.0*x*y*np.cos(self.phi_m(2.0*m)) return fm def prototype(self): if self.btype in ("bandpass", "bandstop"): w0 = np.sqrt(self.fp[0]*self.fp[1]) #middle frequency beta = (omega0)/(self.fp[1]-self.fp[0]) #beta factor print(omega0, beta) else: pass def lowpass_prototype_order(self, wpass, wstop): if self.btype == "butter": order = (np.log(np.pow(10,0.1*self.gstop)-1.0)-(np.pow(0.1*self.gpass)-1.0))/(np.log(abs(wstop/w0 - w0/wstop)) - np.log(abs(wpass/w0 - w0/wpass))) #page 68 elif self.ftype in ('cheby1', 'cheby2'): """TBI""" else: raise Exception("Unknown filter's approximation type.") sys.exit(1)
class LCladder(Filter): def __init__(self, R1, R2, fp, fs, gpass, gstop, ftype, btype): """ Variables init """ Filter.__init__(self, fp, fs, gpass, gstop, ftype, btype) self.R1 = R1 self.R2 = R2 self.units = Units() """ TEST DATA FOR CHEBY """ #self.gpass = 1.5 #self.ord = 4 #self.wn = np.pi * 100000.0 """ TEST DATA FOR BUTTER """ #self.ord = 5 #self.wn = 100000.0 if ftype == 'butter': self.alpha = self.alpha() elif ftype in ('cheby1', 'cheby2'): self.E = self.epsilon() self.gamma = self.gamma() self.a = self.a_help_var() self.a_ = self.a_prim_help_var() print "gamma ", self.gamma print "epsilon ", self.E print "a", self.a print "a_ ", self.a_ #Frequency to pulsation self.wn = self.wn * np.pi * 2 def load_matched(self): """ Normalized matched LC ladder elements """ if self.R1 != self.R2: raise Exception("Load not matched!") sys.exit(1) elif self.ftype in ('cheby1', 'cheby2'): lc_ladder = self.load_not_matched() elif self.ftype == "butter": lc_ladder = [] for k in range(1, self.ord + 1): x = 2.0 * np.sin(((2.0*k-1.0)*np.pi)/(2.0*self.ord)) lc_ladder.append(x) lc_ladder = self.load_matched_denormalizer(lc_ladder) else: lc_ladder = None return lc_ladder def load_matched_denormalizer(self, elements): """ Denormalize normalized elements of matched LC ladder ciurcuit """ lc_ladder = {} id = 1 for element in elements: if id % 2 == 0: key = "C" unit = "F" element = element / (self.wn * self.R1) else: key = "L" unit = "H" element = element / self.R1 key = key + str(id) id = id + 1 lc_ladder[key] = np.around(self.units.rescale(element, unit), 3) return lc_ladder def load_not_matched(self): if self.R2 > self.R1: value_1 = self.coil_1() #Initial value initial_element_key = "L1" key_2 = 'C' value_2_unit = "F" key_1 = 'L' value_1_unit = "H" elif self.R2 < self.R1: value_1 = self.cap_1() #Initial value initial_element_key = "C1" key_2 = 'L' value_2_unit = "H" key_1 = 'C' value_1_unit = "F" else: if self.ftype == "butter": raise Exception("Load matched! Please execute LCladder.load_matched()") sys.exit(1) elif self.ftype in ("cheby1", "cheby2"): value_1 = self.coil_1() #Initial value initial_element_key = "L1" key_2 = 'C' value_2_unit = "F" key_1 = 'L' value_1_unit = "H" else: raise Exception("Unknown filter type.") sys.exit(1) lc_ladder = {} m = self.ord/2 lc_ladder[initial_element_key] = np.around(self.units.rescale(value_1, value_1_unit), 3) for m in range(1, m+1): if self.ftype == "butter": value_2 = (4.0 * np.sin(self.phi_m(4.0*m-3.0)) * np.sin(self.phi_m(4.0*m-1.0))) / (value_1 * np.power(self.wn, 2.0)*(1.0 - 2.0 * self.alpha*np.cos(self.phi_m(4.0*m-2.0))+np.power(self.alpha,2.0))) #2.65a value_1 = (4.0 * np.sin(self.phi_m(4.0*m-1.0)) * np.sin(self.phi_m(4.0*m+1.0))) / (value_2 * np.power(self.wn, 2.0)*(1.0 - 2.0 * self.alpha*np.cos(self.phi_m(4.0*m))+np.power(self.alpha,2.0))) #2.65b elif self.ftype in ("cheby1", "cheby2"): value_2 = (4.0 * np.sin(self.phi_m(4.0*m-3.0)) * np.sin(self.phi_m(4.0*m-1.0))) / (value_1 * np.power(self.wn, 2.0) * self.fm(2.0*m-1.0, np.sinh(self.a), np.sinh(self.a_))) value_1 = (4.0 * np.sin(self.phi_m(4.0*m-1.0)) * np.sin(self.phi_m(4.0*m+1.0))) / (value_2 * np.power(self.wn, 2.0) * self.fm(2.0*m, np.sinh(self.a), np.sinh(self.a_))) value_2_id = 2 * m value_2_key = key_2 + str(value_2_id) lc_ladder[value_2_key] = np.around(self.units.rescale(value_2, value_2_unit), 3) if len(lc_ladder) == self.ord: break value_1_id = 2 * m + 1 value_1_key = key_1 + str(value_1_id) lc_ladder[value_1_key] = np.around(self.units.rescale(value_1, value_1_unit), 3) return lc_ladder def phi_m(self, m): """ LC ladder help variable""" phi_m = (m * np.pi) / (2 * self.ord) #2.67 return phi_m def alpha(self): """ LC ladder help variable""" alpha = np.power(abs((self.R1-self.R2)/(self.R1+self.R2)), 1.0 / self.ord) #2.66 return alpha def cap_1(self): """Computing initial capacitor value""" if self.ftype == 'butter': cap_1 = (2.0 * np.sin(self.phi_m(1.0)))/(self.R1*(1.0-self.alpha) * self.wn) #2.68 elif self.ftype in ('cheby1', 'cheby2'): cap_1 = (2.0 * np.sin((np.pi/2.0)/self.ord))/(self.R1*(np.sinh(self.a) - np.sinh(self.a_)) * self.wn) #2.77 return cap_1 def coil_1(self): """Computing initial coil value""" if self.ftype == 'butter': coil_1 = (2.0 * self.R1 * np.sin(self.phi_m(1.0)))/((1.0-self.alpha) * self.wn) #2.64 elif self.ftype in ('cheby1', 'cheby2'): coil_1 = (2.0*self.R1*np.sin((np.pi/2.0)/self.ord))/((np.sinh(self.a) - np.sinh(self.a_)) * self.wn) #2.73 return coil_1 def a_help_var(self): """Chebyshev lc ladder help variable""" a = (1.0/4.0)*np.arcsinh(1.0/self.E) #2.72 return a def a_prim_help_var(self): """Chebyshev lc ladder help variable""" a_ = (1.0/self.ord)*np.arcsinh(((np.sqrt(1.0 - np.power(self.gamma, 2.0)))/(self.E))) #2.72 return a_ def gamma(self): """Power transfer ratio. Chebyshev lc ladder help variable""" #gamma = ((np.sqrt(self.R1*self.R2))*np.sqrt(1.0 + np.power(self.E, 2.0)))/((self.R1+self.R2)/2.0) gamma = ((np.sqrt(self.R1*self.R2)))/((self.R1+self.R2)/2.0) return gamma def epsilon(self): """Maximum pass band ripple. Chebyshev lc ladder help variable""" E = np.sqrt(np.power(10.0, self.gpass/10.0)-1.0) return E def fm(self, m, x, y): "Chebyshev lc ladder help variable" fm = np.power(x, 2) + np.power(y, 2) + np.power((np.sin(self.phi_m(2.0*m))),2) - 2.0*x*y*np.cos(self.phi_m(2.0*m)) return fm def prototype(self): if self.btype in ("bandpass", "bandstop"): w0 = np.sqrt(self.fp[0]*self.fp[1]) #middle frequency beta = (omega0)/(self.fp[1]-self.fp[0]) #beta factor print omega0, beta else: pass def lowpass_prototype_order(self, wpass, wstop): if self.btype == "butter": order = (np.log(np.pow(10,0.1*self.gstop)-1.0)-(np.pow(0.1*self.gpass)-1.0))/(np.log(abs(wstop/w0 - w0/wstop)) - np.log(abs(wpass/w0 - w0/wpass))) #page 68 elif self.ftype in ('cheby1', 'cheby2'): """TBI""" else: raise Exception("Unknown filter's approximation type.") sys.exit(1)