def valuesChanged(self): states = self['states'] # new number of states dt = self['description type'] m = self._lti ps = m.A.shape[0] # previous number of states dch = False # description changed indicator if (self['A'] and dt==0) or (self['num'] and dt==1): dch = True if ps != states: # Number of states changed - resize matrixes A, B, C, D = m.A, m.B, m.C, m.D if A.shape != (states, states): A = eye(states) p = B.shape[1] # number ouf inputs if B.shape != (states, p): B = eye(states, p) q = C.shape[0] # number ouf outputs if C.shape != (q, states): C = eye(q, states) if D.shape != (q, p): D = zeros((q, p)) self._lti = lti(A, B, C, D) m = self._lti if dt==0: # 'transfer function' # TODO: why m.num.tolist() returns (1,2)? - should be vector self['num'], self['den'] = m.num.tolist()[0], m.den.tolist() elif dt==1: # 'state space' self['A'], self['B'], self['C'], self['D'] = m.A.tolist(), m.B.tolist(), m.C.tolist(), m.D.tolist() elif dch: # number of states doesn't changed - change descr. type if dt==0: # 'transfer function' n, d = self['num'], self['den'] self._lti = lti(n, d) del self['A']; del self['B']; del self['C']; del self['D'] elif dt==1: # 'state space' A, B, C, D = self['A'], self['B'], self['C'], self['D'] if A.shape != (states, states): A = eye(states) p = len(B[1]) # number ouf inputs if B.shape != (states, p): B = eye(states, p) q = len(C[0]) # number ouf outputs if C.shape != (q, states): C = eye(q, states) if D.shape != (q, p): D = zeros(q, p) self._lti = lti(A, B, C, D) del self['num']; del self['den']
def test_05(self): # Test that bode() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) n = 10 # Expected range is from 0.01 to 10. expected_w = np.logspace(-2, 1, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_freq_range(self): # Test that freqresp() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) # Expected range is from 0.01 to 10. system = lti([1], [1, 1]) n = 10 expected_w = np.logspace(-2, 1, n) w, H = freqresp(system, n=n) assert_almost_equal(w, expected_w)
def test_05(self): """Test that bode() finds a reasonable frequency range.""" # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) n = 10 # Expected range is from 0.01 to 10. expected_w = np.logspace(-2, 1, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_03(self): # Test bode() magnitude calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_mag = 20.0 * np.log10(abs(y)) assert_almost_equal(mag, expected_mag)
def test_03(self): """Test bode() magnitude calculation.""" # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_mag = 20.0 * np.log10(abs(y)) assert_almost_equal(mag, expected_mag)
def test_imag_part(self): # Test freqresp() imaginary part calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, H = freqresp(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_im = y.imag assert_almost_equal(H.imag, expected_im)
def test_04(self): # Test bode() phase calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_phase = np.arctan2(y.imag, y.real) * 180.0 / np.pi assert_almost_equal(phase, expected_phase)
def test_lti_instantiation(self): # Test that lti can be instantiated with sequences, scalars. # See PR-225. # TransferFunction s = lti([1], [-1]) assert_(isinstance(s, TransferFunction)) assert_(isinstance(s, lti)) # ZerosPolesGain s = lti(np.array([]), np.array([-1]), 1) assert_(isinstance(s, ZerosPolesGain)) assert_(isinstance(s, lti)) # StateSpace s = lti([], [-1], 1) s = lti([1], [-1], 1, 3) assert_(isinstance(s, StateSpace)) assert_(isinstance(s, lti))
def test_04(self): """Test bode() phase calculation.""" # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_phase = np.arctan2(y.imag, y.real) * 180.0 / np.pi assert_almost_equal(phase, expected_phase)
def test_real_part_manual(self): # Test freqresp() real part calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # re(H(s=0.1)) ~= 0.99 # re(H(s=1)) ~= 0.5 # re(H(s=10)) ~= 0.0099 system = lti([1], [1, 1]) w = [0.1, 1, 10] w, H = freqresp(system, w=w) expected_re = [0.99, 0.5, 0.0099] assert_almost_equal(H.real, expected_re, decimal=1)
def test_imag_part_manual(self): # Test freqresp() imaginary part calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # im(H(s=0.1)) ~= -0.099 # im(H(s=1)) ~= -0.5 # im(H(s=10)) ~= -0.099 system = lti([1], [1, 1]) w = [0.1, 1, 10] w, H = freqresp(system, w=w) expected_im = [-0.099, -0.5, -0.099] assert_almost_equal(H.imag, expected_im, decimal=1)
def test_02(self): # Test bode() phase calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # angle(H(s=0.1)) ~= -5.7 deg # angle(H(s=1)) ~= -45 deg # angle(H(s=10)) ~= -84.3 deg system = lti([1], [1, 1]) w = [0.1, 1, 10] w, mag, phase = bode(system, w=w) expected_phase = [-5.7, -45, -84.3] assert_almost_equal(phase, expected_phase, decimal=1)
def test_02(self): """Test bode() phase calculation (manual sanity check).""" # 1st order low-pass filter: H(s) = 1 / (s + 1), # angle(H(s=0.1)) ~= -5.7 deg # angle(H(s=1)) ~= -45 deg # angle(H(s=10)) ~= -84.3 deg system = lti([1], [1, 1]) w = [0.1, 1, 10] w, mag, phase = bode(system, w=w) expected_phase = [-5.7, -45, -84.3] assert_almost_equal(phase, expected_phase, decimal=1)
def test_05(self): """Test that bode() finds a reasonable frequency range.""" # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) vals = linalg.eigvals(system.A) minpole = min(abs(np.real(vals))) maxpole = max(abs(np.real(vals))) n = 10 # Expected range is from 0.01 to 10. expected_w = np.logspace(-2, 1, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_freq_range(self): # Test that freqresp() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) # Expected range is from 0.01 to 10. system = lti([1], [1, 1]) vals = linalg.eigvals(system.A) minpole = min(abs(np.real(vals))) maxpole = max(abs(np.real(vals))) n = 10 expected_w = np.logspace(-2, 1, n) w, H = freqresp(system, n=n) assert_almost_equal(w, expected_w)
def test_01(self): # Test bode() magnitude calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # cutoff: 1 rad/s, slope: -20 dB/decade # H(s=0.1) ~= 0 dB # H(s=1) ~= -3 dB # H(s=10) ~= -20 dB # H(s=100) ~= -40 dB system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) expected_mag = [0, -3, -20, -40] assert_almost_equal(mag, expected_mag, decimal=1)
def test_01(self): """Test bode() magnitude calculation (manual sanity check).""" # 1st order low-pass filter: H(s) = 1 / (s + 1), # cutoff: 1 rad/s, slope: -20 dB/decade # H(s=0.1) ~= 0 dB # H(s=1) ~= -3 dB # H(s=10) ~= -20 dB # H(s=100) ~= -40 dB system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) expected_mag = [0, -3, -20, -40] assert_almost_equal(mag, expected_mag, decimal=1)
def test_05(self): """Test that bode() finds a reasonable frequency range. A reasonable frequency range is two orders of magnitude before the minimum (slowest) pole and two orders of magnitude after the maximum (fastest) pole. """ # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) vals = linalg.eigvals(system.A) minpole = min(abs(np.real(vals))) maxpole = max(abs(np.real(vals))) n = 10; expected_w = np.logspace(np.log10(minpole) - 2, np.log10(maxpole) + 2, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_05(self): """Test that bode() finds a reasonable frequency range. A reasonable frequency range is two orders of magnitude before the minimum (slowest) pole and two orders of magnitude after the maximum (fastest) pole. """ # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) vals = linalg.eigvals(system.A) minpole = min(abs(np.real(vals))) maxpole = max(abs(np.real(vals))) n = 10 expected_w = np.logspace( np.log10(minpole) - 2, np.log10(maxpole) + 2, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0], [0.0], [1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) expected_magnitude = np.sqrt(1.0 / (1.0 + w**6)) assert_almost_equal(np.abs(H), expected_magnitude)
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0],[0.0],[1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) expected_magnitude = np.sqrt(1.0 / (1.0 + w**6)) assert_almost_equal(np.abs(H), expected_magnitude)
def __init__ ( self, *args, **kwords ): InstrumentBase.__init__(self) af = self.parameters.append sc = self.__class__ # set the name attribute self.name = sc.defaults['NAME'] d = sc.defaults af(Parameter('states', sc.defaults['STATES']))#, IntType, None, self.valuesChanged))#sc.defaults['STATES'] #self['states'] = sc.defaults['STATES'] #self._lti = lti(sc.defaults['NUM'], sc.defaults['DEN']) self._lti = lti(d['A'], d['B'], d['C'], d['D']) af(Parameter('description type', sc.defaults['DESCRIPTION_TYPE'], IntType, LTI_DESCRIPTION_TYPE, self._changeDescriptionType)) self._changeDescriptionType(1) af(Parameter('generate states', sc.defaults['GENERATE_STATES'], BooleanType)) self.setProperties(kwords)
def lti(self): """ Calculates the lti models for the PLL Return ------ G : lti The open loop transfer function T : lti The error transfer function H : lti the input to output transfer function """ Navg, Kvco, fvals = (self.Navg, self.Kvco, self.filter_vals) if self.order == 3 and self.plltype == 2: C1, C2, R1, Icp = (fvals['C1'], fvals['C2'], fvals['R1'], fvals['Icp']) tp = R1 * C1 * C2 / (C1 + C2) tz = R1 * C1 Kf = 1 / (C1 + C2) Kpfd = Icp / 2 / k.pi K = Kf * Kpfd / Navg * 2 * k.pi * Kvco G = lti.lti([K * tz, K], [tp, 1, 0, 0]) T = lti.lti([tp, 1, 0, 0], [tp, 1, K * tz, K]) H = lti.lti([Navg * K * tz, Navg * K], [tp, 1, K * tz, K]) if self.order == 4 and self.plltype == 2: Navg, Kvco, fvals = (self.Navg, self.Kvco, self.filter_vals) C1, C2, C3, R1, R2, Icp = (fvals['C1'], fvals['C2'], fvals['C3'], fvals['R1'], fvals['R2'], fvals['Icp']) tz = R1 * C1 Kf = 1 / (C1 + C2 + C3) a2 = C1 * C2 * C3 * R1 * R2 * Kf a1 = (C1 * C2 * R1 + C1 * C3 * R1 + C1 * C3 * R2 + C2 * C3 * R2) * Kf a0 = 1 Kpfd = Icp / 2 / k.pi K = Kf * Kpfd / Navg * 2 * k.pi * Kvco G = lti.lti([K * tz, K], [a2, a1, a0, 0, 0]) T = lti.lti([a2, a1, a0, 0, 0], [a2, a1, a0, K * tz, K]) H = lti.lti([Navg * K * tz, Navg * K], [a2, a1, a0, K * tz, K]) if self.order not in (3, 4): print('order not implemented, the noise can not be calculated') raise self.G, self.T, self.H = G, T, H return G, T, H
def lti(self): """ Calculates the lti models for the PLL Return ------ G : lti The open loop transfer function T : lti The error transfer function H : lti the input to output transfer function """ Navg, Kvco, fvals = (self.Navg, self.Kvco, self.filter_vals) if self.order == 3 and self.plltype == 2: C1, C2, R1, Icp = (fvals['C1'], fvals['C2'], fvals['R1'], fvals['Icp']) tp = R1 * C1 * C2 / (C1 + C2) tz = R1 * C1 Kf = 1 / (C1 + C2) Kpfd = Icp / 2 / k.pi K = Kf * Kpfd / Navg * 2 * k.pi * Kvco G = lti.lti([K*tz, K], [tp, 1, 0, 0]) T = lti.lti([tp, 1, 0, 0], [tp, 1, K*tz, K]) H = lti.lti([Navg*K*tz, Navg*K], [tp, 1, K*tz, K]) if self.order == 4 and self.plltype == 2: Navg, Kvco, fvals = (self.Navg, self.Kvco, self.filter_vals) C1, C2, C3, R1, R2, Icp = (fvals['C1'], fvals['C2'], fvals['C3'], fvals['R1'], fvals['R2'],fvals['Icp']) tz = R1 * C1 Kf = 1 / (C1 + C2 + C3) a2 = C1 * C2 * C3 * R1 * R2 * Kf a1 = (C1 * C2 * R1 + C1 * C3 * R1 + C1 * C3 * R2 + C2 * C3 * R2) * Kf a0 = 1 Kpfd = Icp / 2 / k.pi K = Kf * Kpfd / Navg * 2 * k.pi * Kvco G = lti.lti([K*tz, K], [a2, a1, a0, 0, 0]) T = lti.lti([a2, a1, a0, 0, 0], [a2, a1, a0, K*tz, K]) H = lti.lti( [Navg*K*tz, Navg*K], [a2, a1, a0, K*tz, K]) if self.order not in(3, 4): print('order not implemented, the noise can not be calculated') raise self.G, self.T, self.H = G, T, H return G, T, H
def test_pole_zero(self): # Test that freqresp() doesn't fail on a system with a pole at 0. # integrator, pole at zero: H(s) = 1 / s system = lti([1], [1, 0]) w, H = freqresp(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number
num4 = numpy.array([2 * numpy.pi * fhi]) den4 = numpy.array([1, 2 * numpy.pi * fhi]) G4 = ltimul(num4, den4) #fho low pass fho = 27.843813 * pow(10, 6) num5 = numpy.array([2 * numpy.pi * fho]) den5 = numpy.array([1, 2 * numpy.pi * fho]) G5 = ltimul(num5, den5) num6 = numpy.array([-70]) den6 = numpy.array([1]) Av_mid = ltimul(num6, den6) G_temp = Av_mid * G1 * G2 * G3 * G4 * G5 G = lti(G_temp.num, G_temp.den) print(G) data_freq = numpy.array([ 50, 100, 200, 400, 600, 800, 1 * pow(10, 3), 2 * pow(10, 3), 3 * pow(10, 3), 5 * pow(10, 3), 10 * pow(10, 3), 50 * pow(10, 3), 100 * pow(10, 3), 200 * pow(10, 3), 500 * pow(10, 3), 600 * pow(10, 3), 700 * pow(10, 3), 800 * pow(10, 3), 900 * pow(10, 3), 1 * pow(10, 6), 2 * pow(10, 6) ]) data_Av = numpy.array([ 14, 28, 46, 58, 64, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70 ])
def test_lti_instantiation(): # Test that lti can be instantiated with sequences, scalars. See PR-225. s = lti([1], [-1]) s = lti(np.array([]), np.array([-1]), 1) s = lti([], [-1], 1) s = lti([1], [-1], 1, 3)
def test_08(self): """Test that bode() return continuous phase, issues/2331.""" system = lti([], [-10, -30, -40, -60, -70], 1) w, mag, phase = system.bode(w=np.logspace(-3, 40, 100)) assert_almost_equal(min(phase), -450, decimal=15)
def test_07(self): """bode() should not fail on a system with pure imaginary poles.""" # The test passes if bode doesn't raise an exception. system = lti([1], [1, 0, 100]) w, mag, phase = bode(system, n=2)
def test_06(self): """Test that bode() doesn't fail on a system with a pole at 0.""" # integrator, pole at zero: H(s) = 1 / s system = lti([1], [1, 0]) w, mag, phase = bode(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number
def test_06(self): # Test that bode() doesn't fail on a system with a pole at 0. # integrator, pole at zero: H(s) = 1 / s system = lti([1], [1, 0]) w, mag, phase = bode(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number
def test_07(self): # bode() should not fail on a system with pure imaginary poles. # The test passes if bode doesn't raise an exception. system = lti([1], [1, 0, 100]) w, mag, phase = bode(system, n=2)
def test_08(self): # Test that bode() return continuous phase, issues/2331. system = lti([], [-10, -30, -40, -60, -70], 1) w, mag, phase = system.bode(w=np.logspace(-3, 40, 100)) assert_almost_equal(min(phase), -450, decimal=15)
def lti_nowarn(self, *args): with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) system = lti(*args) return system