def test_dlti_instantiation(self): # Test that lti can be instantiated. dt = 0.05 # TransferFunction s = dlti([1], [-1], dt=dt) assert_(isinstance(s, TransferFunction)) assert_(isinstance(s, dlti)) assert_(not isinstance(s, lti)) assert_equal(s.dt, dt) # ZerosPolesGain s = dlti(np.array([]), np.array([-1]), 1, dt=dt) assert_(isinstance(s, ZerosPolesGain)) assert_(isinstance(s, dlti)) assert_(not isinstance(s, lti)) assert_equal(s.dt, dt) # StateSpace s = dlti([1], [-1], 1, 3, dt=dt) assert_(isinstance(s, StateSpace)) assert_(isinstance(s, dlti)) assert_(not isinstance(s, lti)) assert_equal(s.dt, dt) # Number of inputs assert_raises(ValueError, dlti, 1) assert_raises(ValueError, dlti, 1, 1, 1, 1, 1)
def test_series_diagram_construction(): head_block = DirectFormI.from_model( signal.dlti(1, [1, 1, 0.5])) tail_block = DirectFormI.from_model( signal.dlti(2, [1, -0.5])) x, y = sympy.symbols('x y') diagram = series_diagram([ head_block, tail_block ], input_=x, output=y) paths = list(nx.all_simple_edge_paths( diagram, source=x, target=y)) assert len(paths) == 1 path = paths[0] assert len(path) == 2 u, v, i = path[0] assert u is x assert i == 0 assert diagram[u][v][i]['block'] is head_block w, z, i = path[1] assert v is w assert z is y assert i == 0 assert diagram[w][z][i]['block'] is tail_block
def test_model_stability(): model = signal.dlti([1], [1, 1]) assert not is_stable(model) assert_almost_equal(spectral_radius(model), 1) model = signal.dlti([1], [1, 0.5]) assert is_stable(model) assert_almost_equal(spectral_radius(model), 0.5)
def test_from_zpk(self): # 1st order low-pass filter: H(s) = 0.3 / (z - 0.2), system_ZPK = dlti([],[0.2],0.3) system_TF = dlti(0.3, [1, -0.2]) w = [0.1, 1, 10, 100] w1, H1 = dfreqresp(system_ZPK, w=w) w2, H2 = dfreqresp(system_TF, w=w) assert_almost_equal(H1, H2)
def _compute_filters(cls, pole, unit_delay): if pole == 0: poles_init = [0] if unit_delay else [] init_filt = sc_sig.dlti([], poles_init, 1) post_filt = sc_sig.dlti([], [pole], 1) else: zeros_init = [] if unit_delay else [0] init_filt = sc_sig.dlti(zeros_init, [pole], np.sqrt(1 - pole**2)) post_filt = sc_sig.dlti([1 / pole], [pole], -pole) return init_filt._as_ss(), post_filt._as_ss()
def __init__(self,**kwargs): if 'transfer function' in kwargs: self.system = signal.dlti(kwargs['transfer function']['num'], kwargs['transfer function']['denom']) elif 'zeros poles gain' in kwargs: self.system = signal.dlti(kwargs['transfer function']['zeros'], Kwargs['transfer function']['poles'], kwargs['transfer function']['gain']) else: raise Exception("System should be of the type "+\ "'transfer function' or 'zeros poles gains'") self.__xout = np.zeros(0) self.__yout = np.zeros(0)
def test_parallel_diagram_construction(): left_block = DirectFormI.from_model( signal.dlti(1, [1, 1, 0.5])) right_block = DirectFormI.from_model( signal.dlti(2, [1, -0.5])) x, y = sympy.symbols('x y') diagram = parallel_diagram([ left_block, right_block ], input_=x, output=y) assert len(diagram[x][y]) == 2 assert diagram[x][y][0]['block'] is left_block assert diagram[x][y][1]['block'] is right_block
def _make_stateful_computation_error_model(self): a = self.parameters.a.astype(float) if hasattr(self.parameters, 'k'): a[1:] = np.ldexp(a[1:], self.parameters.k) n_s = self.states[0][0] a = np.pad(a, (0, n_s + 1 - len(a))) if n_s > 1: A = np.zeros((n_s, n_s)) A[:, 0] = -a[1:n_s + 1] A[:-1, 1:] = np.eye(n_s - 1) C = np.zeros((1, n_s)) C[0, 0] = 1 else: A = -a[1] C = 1 B = np.zeros((n_s, n_s + 1)) B[:, 0] = -a[1:n_s + 1] B[:, 1:] = np.eye(n_s) D = np.zeros((1, n_s + 1)) D[0, 0] = 1 return signal.dlti(A, B, C, D)
def _make_stateful_computation_error_model(self): b = self.parameters.b.astype(float) a = self.parameters.a.astype(float) if hasattr(self.parameters, 'k'): b = np.ldexp(b, self.parameters.k) a[1:] = np.ldexp(a[1:], self.parameters.k) n_s = self.states[0][0] b = np.pad(b, (0, n_s + 1 - len(b))) a = np.pad(a, (0, n_s + 1 - len(a))) if n_s > 1: A = np.zeros((n_s, n_s)) A[0, :] = -a[1:n_s + 1] A[1:, :-1] = np.eye(n_s - 1) C = np.array([ -b[0] * a[i] + b[i] for i in range(1, n_s + 1) ]) else: A = -a[1] C = -b[0] * a[1] + b[1] B = np.zeros((n_s, 2)) B[0, 0] = 1 D = np.array([b[0], 1]) return signal.dlti(A, B, C, D)
def test_filter(self): a = iddata(np.zeros(10), np.zeros(10), 0.1, [0]) L = scipysig.dlti([1], [1], dt=0.1) b = a.copy() a.filter(L) self.assertTrue(np.all(a.y == b.y)) self.assertTrue(np.all(a.u == b.u)) self.assertTrue(np.all(a.y0 == b.y0)) self.assertTrue(a.ts == b.ts) # Test more complex model dt = 0.05 omega = 10 alpha = np.exp(-dt * omega) num_M = [(1 - alpha)**2] den_M = [1, -2 * alpha, alpha**2, 0] refModel = ExtendedTF(num_M, den_M, dt=dt) a = iddata(np.ones(10), np.ones(10), 0.1, [0]) L = refModel * (1 - refModel) b = a.copy() a.filter(L) res = np.array([ 0, 0, 0, 0.15481812, 0.342622, 0.51348521, 0.62769493, 0.67430581, 0.66237955, 0.60937255 ]) self.assertTrue(np.allclose(a.y, res)) self.assertTrue(np.allclose(a.u, res)) self.assertTrue(np.all(a.u != b.u)) self.assertTrue(np.all(a.y != b.y)) self.assertTrue(np.all(a.y0 == b.y0)) self.assertTrue(a.ts == b.ts)
def fast_xambg(ref, srv, nlag, nf): ''' Fast Cross-Ambiguity Fuction Parameters: ref, srv: input vectors for cross-ambiguity function nlag: number of lag bins to compute nfft: number of doppler bins to compute (should be power of 2) Returns: xambg: (nf, nlag+1, 1) matrix containing cross-ambiguity surface third dimension added for easy stacking in dask ''' if ref.shape != srv.shape: raise ValueError('Input vectors must have the same length') ndecim = int(ref.shape[0] / nf) xambg = np.zeros((nf, nlag + 1, 1), dtype=np.complex64) s2c = np.conj(srv) # precompute FIR filter for decimation. (flat top filter of length # 10*decimation factor). dtaps = signal.firwin(10 * ndecim + 1, 1. / ndecim, window='flattop') dfilt = signal.dlti(dtaps, 1) for k, lag in enumerate(np.arange(-nlag, 1)): sd = np.roll(s2c, lag) * ref xambg[:, k, 0] = signal.decimate(sd, ndecim, ftype=dfilt)[0:ndecim] # print(ndecim) # xambg[:, k, 0] = np.fft.fftshift(np.fft.fft(sdd, ndecim)) xambg = np.fft.fftshift(np.fft.fft(xambg, axis=0), axes=0) return xambg
def on_clicked_design(*args): designer = filter_widget.designer try: params = designer.params print(params) dt = 1 / params['fs'] system = designer.design(params) system = signal.dlti(*system, dt=dt) filter_view.system = system if export_button not in vbox.get_children(): vbox.pack_start(export_button, expand=False, fill=True, padding=0) except Exception as e: if export_button in vbox.get_children(): vbox.remove(export_button) show_error_dialog(e) raise e
def decimate_matlab(x, q, n=None, axis=-1): """ :param x: signal :param q: decimation ration :param n: order of filter :param axis: :return: resampled signal """ if not isinstance(q, int): raise TypeError("q must be an integer") if n is not None and not isinstance(n, int): raise TypeError("n must be an integer") system = signal.dlti(*signal.cheby1(n, 0.05, 0.8 / q)) #zero_phase = True y = signal.filtfilt(system.num, system.den, x, axis=axis, padlen=3 * (max(len(system.den), len(system.num)) - 1)) # make it the same as matlab nd = len(y) n_out = np.ceil(nd / q) n_beg = int(q - (q * n_out - nd)) return y[n_beg - 1::q]
def bigshow(*v): if len(v) < 2 or len(v) > 4: #Determine the number of parameters and assign values print('Error. Wrong number of input arguments.') #Report error if variables <2&>4 else: #Set a,b,tsim,timpulse a = v[0] b = v[1] if len(v) >= 3: tsim = v[2] if len(v) >= 4: timpulse = v[3] else: timpulse = 30 else: tsim = 80 timpulse = 26 #First generate the simulation (Gaussian errors) nn = 100 #Number of observations to be discarded u = np.random.randn(tsim+nn) #Generate white noise with var σ^2 = 1 y = lfilter(b,a,u,-1 ,None) #Digital filter plt.figure(figsize=(10, 4)) #Set display size 1000*400 plt.subplot(1,2,1) plt.plot(y) plt.title('Simulation') plt.xlim(0,tsim) #Impulse Response sys = dlti(b,a) #Building function system x1,y1 = dimpulse(sys) #Impulse response function plt.subplot(1,2,2) plt.plot(x1,y1[-1]) plt.title('Impulse Response') plt.xlim(0,timpulse) #plt.ylim(0) Set y limit plt.show()
def sympy_to_dlti(xpr, s=Symbol('s')): """ Convert Sympy transfer function polynomial to Scipy LTI """ num, den = simplify(xpr).as_numer_denom() # expressions p_num_den = poly(num, s), poly(den, s) # polynomials c_num_den = [expand(p).all_coeffs() for p in p_num_den] # coefficients l_num, l_den = [lambdify((), c)() for c in c_num_den] # convert to floats return signal.dlti(l_num, l_den, dt=0.1)
def smooth_waveform(sample: numpy.ndarray, filter_order: int = 2, cutoff_frequency: float = 500.0, downsample_factor: int = 4) -> numpy.ndarray: """ Method to smooth waveform using a butterworth filter to lower sensitivity of frequency calculation. :param sample: :param filter_order: :param cutoff_frequency: :param downsample_factor: downsample factor for decimate function :return: """ # smooth digital signal w/ butterworth filter # First, design the Butterworth filter # Cutoff frequencies in half-cycles / sample cutoff_frequency_nyquist = cutoff_frequency * 2 / constants.SAMPLE_RATE_HZ numerator, denominator = signal.butter(filter_order, cutoff_frequency_nyquist, output='ba') # Second, create Dicrete-time linear time invariant system instance dtltis = signal.dlti(numerator, denominator) # decimate signal to improve runtime return signal.decimate(sample, downsample_factor, ftype=dtltis)
def getSystem(rl, fc, fs=44100): l = int(fs / fc) a = l + 1 - fs / fc b = fs / fc - l num = [0] * (l + 2) den = [0] * (l + 2) num[0] = a num[1] = b den[0] = 1 den[-2] = -a * rl den[-1] = -b * rl #c = 1/(2*cos(2*pi*fc/fs)+1) # num2 = [c, c, c] # num3 = convolve(num, num2) # # den2 = [2, 0, 0] # # den3 = convolve(den, den2) return signal.dlti(num, den, dt=1 / fs)
def task3c(): sys1_num = [1, 2, 1] sys1_denom = [1] sys2_num = [1, 0] sys2_denom = [1, 0.9] sys1_gain = 1 sys1_zeros = [-1, -1] sys1_poles = [] sys1 = sig.dlti(sys1_num, sys1_denom) sys2 = sig.dlti(sys2_num, sys2_denom) w1, mag1, phase1 = sig.dbode(sys1, n=100000) w2, mag2, phase2 = sig.dbode(sys2, n=100000) plt.semilogx(w1, mag1) plt.title("magnitude response of first system") plt.savefig("task3c mag1.pdf") plt.show() plt.semilogx(w1, phase1) plt.title("phase response of first system") plt.savefig("task3c phase1.pdf") plt.show() plt.semilogx(w2, mag2) plt.title("magnitude response of second system") plt.savefig("task3c mag2.pdf") plt.show() plt.semilogx(w2, phase2) plt.title("phase response of second system") plt.savefig("task3c phase2.pdf") plt.show() sys1 = sig.ZerosPolesGain(sys1_zeros, ) n = np.arange(1000) x = 1 / 2 * np.sin(np.pi * n + np.pi / 4) out1 = sig.dlsim(sys1, x) out2 = sig.dlsim(sys2, x) plt.plot(n, out1) plt.title("output of system 1") plt.savefig("task3e output1.pdf") plt.show() plt.plot(n, out2) plt.title("output of system 2") plt.savefig("task3e output2.pdf") plt.show()
def resample(self, data, original_frequency, target_frequency ): if original_frequency==500 or original_frequency==200: numerator = [[-0.0175636017706537, -0.0208207236911009, -0.0186368912579407, 0.0, 0.0376532652007562, 0.0894912177899215, 0.143586518157187, 0.184663795586300, 0.200000000000000, 0.184663795586300, 0.143586518157187, 0.0894912177899215, 0.0376532652007562, 0.0, -0.0186368912579407, -0.0208207236911009, -0.0175636017706537], [-0.050624178425469, 0.0, 0.295059334702992, 0.500000000000000, 0.295059334702992, 0.0, -0.050624178425469]] # from matlab if original_frequency==500: s = signal.dlti(numerator[0], [1], dt=1. / target_frequency) resampled_ch = signal.decimate(data, original_frequency // target_frequency, ftype=s, zero_phase=False) elif original_frequency==200: s = signal.dlti(numerator[1], [1], dt=1. / target_frequency) resampled_ch = signal.decimate(data, original_frequency // target_frequency, ftype=s, zero_phase=False) else: resampled_ch = signal.resample_poly(data, target_frequency, original_frequency, axis=0, window=('kaiser', 5.0)) return resampled_ch
def resp(omega_n,dzeta,k): y=[0]*40 if dzeta>0: funkcja=signal.dlti([omega_n*omega_n*k], [1,2*omega_n*dzeta, omega_n*omega_n], dt=0.005) t, y = signal.dimpulse(funkcja, n=40) y=np.squeeze(y) return y
def add_filter(self, filter_, frequencies=None, dB=True, analog=False, sample_rate=None, **kwargs): """Add a linear time-invariant filter to this BodePlot Parameters ---------- filter_ : `~scipy.signal.lti`, `tuple` the filter to plot, either as a `~scipy.signal.lti`, or a `tuple` with the following number and meaning of elements - 2: (numerator, denominator) - 3: (zeros, poles, gain) - 4: (A, B, C, D) frequencies : `numpy.ndarray`, optional list of frequencies (in Hertz) at which to plot dB : `bool`, optional if `True`, display magnitude in decibels, otherwise display amplitude, default: `True` **kwargs any other keyword arguments accepted by :meth:`~matplotlib.axes.Axes.plot` Returns ------- mag, phase : `tuple` of `lines <matplotlib.lines.Line2D>` the lines drawn for the magnitude and phase of the filter. """ if not analog: if not sample_rate: raise ValueError("Must give sample_rate frequency to display " "digital (analog=False) filter") sample_rate = Quantity(sample_rate, 'Hz').value dt = 2 * pi / sample_rate if not isinstance(frequencies, (type(None), int)): frequencies = numpy.atleast_1d(frequencies).copy() frequencies *= dt # parse filter (without digital conversions) _, fcomp = parse_filter(filter_, analog=False) if analog: lti = signal.lti(*fcomp) else: lti = signal.dlti(*fcomp, dt=dt) # calculate frequency response w, mag, phase = lti.bode(w=frequencies) # convert from decibels if not dB: mag = 10 ** (mag / 10.) # draw mline = self.maxes.plot(w, mag, **kwargs)[0] pline = self.paxes.plot(w, phase, **kwargs)[0] return mline, pline
def get_tf(student_number): numb = str(student_number) dt = 0.01 G = sig.dlti([1, -int(numb[2]), int(numb[1])], [ int(numb[0]), -int(numb[3]) / 8, int(numb[4]) / 8, -int(numb[5]) / 16 ], dt=dt) return G
def test_impz_4(self): # Test case for IIR filter with n fil = IIRDesign.butter(6, self.fc / (self.fs / 2)) dl = signal.dlti(fil[0], fil[1], dt=1 / self.fs) i_d = signal.dimpulse(dl, n=self.n) T = i_d[0] yout = i_d[1][0] tt, y = FilterSpec.impz(fil, n=self.n, fs=self.fs) self.assertTrue(np.all(tt == T) and np.all(y == yout))
def test_block_as_diagram(): block = DirectFormI.from_model( signal.dlti(1, [1, 1, 0.5])) x, y = sympy.symbols('x y') diagram = as_diagram( block, input_=x, output=y ) assert len(diagram[x][y]) == 1 assert diagram[x][y][0]['block'] is block
def get_sys(self, tf): num = tf.num[0][0] den = tf.den[0][0] if tf.dt is None: sys = signal.lti(num, den) else: sys = signal.dlti(num, den, dt=tf.dt) return sys
def test_from_state_space(self): # H(z) = 2 / z^3 - 0.5 * z^2 system_TF = dlti([2], [1, -0.5, 0, 0]) A = np.array([[0.5, 0, 0], [1, 0, 0], [0, 1, 0]]) B = np.array([[1, 0, 0]]).T C = np.array([[0, 0, 2]]) D = 0 system_SS = dlti(A, B, C, D) w = 10.0**np.arange(-3, 0, .5) with suppress_warnings() as sup: sup.filter(BadCoefficients) w1, H1 = dfreqresp(system_TF, w=w) w2, H2 = dfreqresp(system_SS, w=w) assert_almost_equal(H1, H2)
def stream_data(channels, duration=600, start_time=0, fs_up=256, portNumber=31200): nds_osx = ('/opt/local/Library/Frameworks/Python.framework/' + 'Versions/2.7/lib/python2.7/site-packages/') nds_sandbox = '/usr/lib/python2.7/dist-packages/' if os.path.exists(nds_osx): sys.path.append(nds_osx) elif os.path.exists(nds_sandbox): sys.path.append(nds_sandbox) # Connect to the right server ifo = channels[0][:2] if ifo == 'L1': ndsServer = 'nds.ligo-la.caltech.edu' elif ifo == 'H1': ndsServer = 'nds.ligo-wa.caltech.edu' else: sys.exit("unknown IFO specified") # Setup connection to the NDS try: conn = nds2.connection(ndsServer, portNumber) except RuntimeError: alert( 'ERROR: Need to run `kinit albert.einstein` before nds2 ' 'can establish a connection', color='FAIL') sys.exit(1) # get data data = conn.fetch(start_time, start_time + duration, channels) data = np.array(data) # stack data and downsample vdata = [] for k in range(len(channels)): fsdown = data[k].channel.sample_rate down_factor = int(fsdown // fs_up) fir_aa = sig.firwin(20 * down_factor + 1, 0.8 / down_factor, window='blackmanharris') # Using fir_aa[1:-1] cuts off a leading and trailing zero downdata = sig.decimate(data[k].data, down_factor, ftype=sig.dlti(fir_aa[1:-1], 1.0), zero_phase=True) vdata.append(downdata) return np.array(vdata).T
def convert_forward_euler(pa, Tsampling=0.01): # if isintance(pa, TransferFunction): if isinstance(pa, lti): #reviso primero el valor final s = Symbol('s') pa_sympy = lti_to_sympy(pa) final_value_analog = pa_sympy.subs(s, 0).evalf() # print (' Final value: ' + str(final_value_analog)) #convierto backward euler num_d, den_d, td = cont2discrete((pa.num, pa.den), Tsampling, method='euler') zd, pd, kd = tf2zpk(num_d, den_d) #agrego zeros infinitos while (np.shape(zd) < np.shape(pd)): zd = np.append(zd, [-1]) #normalizo los zeros planta_d = ZerosPolesGain(zd, pd, kd) planta_d = planta_d.to_tf() zd, pd, kd = tf2zpk(planta_d.num, planta_d.den) #convierto a sympy para evaluar el valor final y ajustarlo planta_d_sympy = lti_to_sympy(planta_d) z = Symbol('z') planta_d_sympy = planta_d_sympy.subs(s, z) final_value_d = planta_d_sympy.subs(z, 1).evalf() #ahora ajusto la ganancia para que me coincidan los dos valores finales kd = kd * final_value / final_value_d # print ('Ceros digital: ' + str(zd)) # print ('Polos digital: ' + str(pd)) # print ('K digital: ' + str(kd)) #normalizo por ultima vez planta_d, ya agregue los zeros #y ajuste la ganancia con los valores finales planta_d = ZerosPolesGain(zd, pd, kd) planta_d = planta_d.to_tf() # print ('planta_d ' + str(planta_d)) #muestro el valor final planta_d_sympy = lti_to_sympy(planta_d) z = Symbol('z') planta_d_sympy = planta_d_sympy.subs(s, z) final_value_d = planta_d_sympy.subs(z, 1).evalf() # print ('planta_d final value: ' + str(final_value_d)) #reconvierto planta_d a dlti planta_d = dlti(planta_d.num, planta_d.den, dt=td) return planta_d else: raise ValueError('planta_analog is not instance of TransferFunction!')
def test_realization_error_bounds(realization_type): model = signal.dlti([1], [1, -0.5]) # y[n] = x[n - 1] - 0.5 y[n - 1] block = realization_type.from_model(model) with FixedFormatArithmeticLogicUnit( format_=Q(7), allows_overflow=False, rounding_method=nearest_integer, ): assert block.computation_error_bounds(interval(-0.25, 0.25)) in \ 10 * nearest_integer.error_bounds(-7) # reasonable tolerance
def on_clicked_design(*args): params = iir.params print(params) dt = 1 / params['fs'] system = iir.design(params) system = signal.dlti(*system, dt=dt) filter_view.system = system
def test_from_state_space(self): # H(z) = 2 / z^3 - 0.5 * z^2 system_TF = dlti([2], [1, -0.5, 0, 0]) A = np.array([[0.5, 0, 0], [1, 0, 0], [0, 1, 0]]) B = np.array([[1, 0, 0]]).T C = np.array([[0, 0, 2]]) D = 0 system_SS = dlti(A, B, C, D) w = 10.0**np.arange(-3,0,.5) with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) w1, H1 = dfreqresp(system_TF, w=w) w2, H2 = dfreqresp(system_SS, w=w) assert_almost_equal(H1, H2)