def l1norm(H): """Compute the l1-norm of a z-domain transfer function. The norm is evaluated over the first 100 samples. **Parameters:** H : sequence or lti object Any supported LTI representation is accepted. **Returns:** l1normH : float The L1 norm of ``H``. .. note: LTI objects are translated to ZPK tuples, with possible rounding errors. """ if _is_zpk(H): z, p, k = H HP = (z, p, k, 1.) elif _is_num_den(H): num, den = H HP = (num, den, 1.) elif _is_A_B_C_D(H): A, B, C, D = H HP = (A, B, C, D, 1.) elif isinstance(H, lti): warn('l1norm() got an LTI object, translated to zpk form, rounding errors possible.') z, p, k = _get_zpk(H) HP = (z, p, k, 1.) _, y = dimpulse(HP, t=np.arange(100)) return np.sum(np.abs(y[0]))
def test_more_step_and_impulse(self): lambda1 = 0.5 lambda2 = 0.75 a = np.array([[lambda1, 0.0], [0.0, lambda2]]) b = np.array([[1.0, 0.0], [0.0, 1.0]]) c = np.array([[1.0, 1.0]]) d = np.array([[0.0, 0.0]]) n = 10 # Check a step response. ts, ys = dstep((a, b, c, d, 1), n=n) # Create the exact step response. stp0 = (1.0 / (1 - lambda1)) * (1.0 - lambda1 ** np.arange(n)) stp1 = (1.0 / (1 - lambda2)) * (1.0 - lambda2 ** np.arange(n)) assert_allclose(ys[0][:, 0], stp0) assert_allclose(ys[1][:, 0], stp1) # Check an impulse response with an initial condition. x0 = np.array([1.0, 1.0]) ti, yi = dimpulse((a, b, c, d, 1), n=n, x0=x0) # Create the exact impulse response. imp = (np.array([lambda1, lambda2]) ** np.arange(-1, n + 1).reshape(-1, 1)) imp[0, :] = 0.0 # Analytical solution to impulse response y0 = imp[:n, 0] + np.dot(imp[1:n + 1, :], x0) y1 = imp[:n, 1] + np.dot(imp[1:n + 1, :], x0) assert_allclose(yi[0][:, 0], y0) assert_allclose(yi[1][:, 0], y1) # Check that dt=0.1, n=3 gives 3 time values. system = ([1.0], [1.0, -0.5], 0.1) t, (y,) = dstep(system, n=3) assert_allclose(t, [0, 0.1, 0.2]) assert_array_equal(y.T, [[0, 1.0, 1.5]]) t, (y,) = dimpulse(system, n=3) assert_allclose(t, [0, 0.1, 0.2]) assert_array_equal(y.T, [[0, 1, 0.5]])
def dsclansObjb(x, order, OSR, Q, rmax, Hz): """Constraint function for clans; g =||h||_1 - Q """ H = dsclansNTF(x, order, rmax, Hz) H = (H[0], H[1], H[2], 1.) # dimpulse(H, n=100)[y is 0][output 0] g = np.sum(np.abs(dimpulse(H, t=np.arange(100))[1][0])) - 1 - Q return -g
def impulse_response(self, impulse_length=30): """ Get the impulse response corresponding to our model. Returns psi, where psi[j] is the response at lag j. Note: psi[0] is unity. """ sys = self.ma_poly, self.ar_poly, 1 times, psi = dimpulse(sys, n=impulse_length) psi = psi[0].flatten() # Simplify return value into flat array return psi
def test_dimpulse(self): a = np.asarray([[0.9, 0.1], [-0.2, 0.9]]) b = np.asarray([[0.4, 0.1, -0.1], [0.0, 0.05, 0.0]]) c = np.asarray([[0.1, 0.3]]) d = np.asarray([[0.0, -0.1, 0.0]]) dt = 0.5 # Because b.shape[1] == 3, dimpulse should result in a tuple of three # result vectors yout_imp_truth = (np.asarray([0.0, 0.04, 0.012, -0.0116, -0.03084, -0.045884, -0.056994, -0.06450548, -0.068804844, -0.0703091708]), np.asarray([-0.1, 0.025, 0.017, 0.00985, 0.00362, -0.0016595, -0.0059917, -0.009407675, -0.011960704, -0.01372089695]), np.asarray([0.0, -0.01, -0.003, 0.0029, 0.00771, 0.011471, 0.0142485, 0.01612637, 0.017201211, 0.0175772927])) tout, yout = dimpulse((a, b, c, d, dt), n=10) assert_equal(len(yout), 3) for i in range(0, len(yout)): assert_equal(yout[i].shape[0], 10) assert_array_almost_equal(yout[i].flatten(), yout_imp_truth[i]) # Check that the other two inputs (tf, zpk) will work as well tfin = ([1.0], [1.0, 1.0], 0.5) yout_tfimpulse = np.asarray([0.0, 1.0, -1.0]) tout, yout = dimpulse(tfin, n=3) assert_equal(len(yout), 1) assert_array_almost_equal(yout[0].flatten(), yout_tfimpulse) zpkin = tf2zpk(tfin[0], tfin[1]) + (0.5,) tout, yout = dimpulse(zpkin, n=3) assert_equal(len(yout), 1) assert_array_almost_equal(yout[0].flatten(), yout_tfimpulse) # Raise an error for continuous-time systems system = lti([1], [1, 1]) assert_raises(AttributeError, dimpulse, system)
def impulse_response(self, n=100): """ Calculates the impulse response of the filter (n steps, default = 100) """ impulse = [1] for number in range(1, n): impulse.append(0) _times, imp_resp = signal.dimpulse((self.b, self.a, 1), n=n) impulse_response = imp_resp[0].flatten() return impulse, impulse_response
def impulse_response(self, impulse_length=30): """ Get the impulse response corresponding to our model. Returns ------- psi : array_like(float) psi[j] is the response at lag j of the impulse response. We take psi[0] as unity. """ sys = self.ma_poly, self.ar_poly, 1 times, psi = dimpulse(sys, n=impulse_length) psi = psi[0].flatten() # Simplify return value into flat array return psi
def powerGain(num, den, Nimp=100): """Calculate the power gain of a TF given in coefficient form. Nimp is the recommended number of impulse response samples for use in future calls and Nimp0 is the suggested number (100) to use. """ unstable = False _, (imp, ) = dimpulse((num, den, 1), t=np.linspace(0, Nimp, Nimp)) if np.sum(abs(imp[Nimp - 11:Nimp])) < 1e-08 and Nimp > 50: Nimp = np.round(Nimp/1.3) else: while np.sum(abs(imp[Nimp - 11:Nimp])) > 1e-06: Nimp = Nimp*2 _, (imp, ) = dimpulse((num, den, 1), t=np.linspace(0, Nimp, Nimp)) if np.sum(abs(imp[Nimp - 11:Nimp])) >= 50 or Nimp >= 10000.0: unstable = True break if not unstable: pGain = np.sum(imp**2) else: pGain = np.Inf return pGain, Nimp
plt.plot(w, np.abs(H)) plt.grid() plt.subplot(212) plt.plot(w, np.angle(H)) plt.grid() #vraag c k = 0.001 num = [-k, k] den = [1, 0] len_ = 10 dt = 1 plt.figure(2) n, y = scig.dimpulse((num, den, dt), n=len_) plt.subplot(311) plt.stem(n, y[0]) plt.grid() omega = np.arange(-np.pi, np.pi, 0.05) w, H = scig.freqz(num, a=den, worN=omega, whole=False) plt.subplot(312) plt.plot(w / np.pi, np.abs(H)) plt.grid() plt.subplot(313) plt.plot(w / np.pi, np.angle(H) / np.pi) plt.grid() plt.xlabel(r'$\Omega / 2\pi$')
def test_impulse_invariant(self, sys, sample_time, samples_number): time = np.arange(samples_number) * sample_time _, yout_cont = impulse2(sys, T=time, **self.tolerances) _, yout_disc = dimpulse(c2d(sys, sample_time, method='impulse'), n=len(time)) assert_allclose(sample_time * yout_cont.ravel(), yout_disc[0].ravel())
import numpy as np import matplotlib.pyplot as plt from scipy.signal import lfilter, TransferFunction, dimpulse a = np.array([1, 7 / 140, -6 / 130, 0, -1 / 150, 1 / 150]) b = np.array([0, -6 / 20, -4 / 20, 0, 6 / 20, -4 / 20]) samples = 30 x = TransferFunction(b, a, dt=True) signal_in = dimpulse(x, n=samples) plt.figure(num=1, figsize=(8, 6)) plt.stem(signal_in[0], signal_in[1][0]) plt.title("Графік вихідного сигналу", fontsize=14) plt.xlabel('Номер відліку', fontsize=10) plt.ylabel('Амплітуда, В', fontsize=10) plt.minorticks_on() plt.grid(which='major', linewidth=1.2) plt.grid(which='minor', linewidth=.5) plt.show()
plt.show() ##-------------------------------------------------- M = 3 b = np.ones(M) a = np.array([M] + [0] * (M - 1)) fft_samples = 1e5 Fs = 1e6 N = int(1e5) # 2^28 t = np.linspace(0, N / Fs, N) f = 10e3 mva_filter = signal.dlti(b, a, dt=1 / Fs) [t_i, y_t_i] = signal.dimpulse((b, a, 1 / Fs), n=2 * M) noise = np.random.normal(0, .1, N) x_t = np.cos(2 * np.pi * t * f) + noise x_t_out = signal.lfilter(b, a, x_t) x_t_out_dec = np.convolve(x_t_out, y_t_i[0][:, 0], mode='valid')[::M] fig1 = plt.figure(1, figsize=(32, 16)) plt.subplot(211) plt.plot(t, x_t) plt.grid() plt.ylabel('Amplitud [a.u.]') plt.subplot(212) plt.plot(x_t_out)
def realizeNTF_ct(ntf, form='FB', tdac=(0, 1), ordering=None, bp=None, ABCDc=None, method='LOOP'): """Realize an NTF with a continuous-time loop filter. **Parameters:** ntf : object A noise transfer function (NTF). form : str, optional A string specifying the topology of the loop filter. * 'FB': Feedback form, * 'FF': Feedforward form For the FB structure, the elements of ``Bc`` are calculated so that the sampled pulse response matches the L1 impulse response. For the FF structure, ``Cc`` is calculated. tdac : sequence, optional The timing for the feedback DAC(s). If ``tdac[0] >= 1``, direct feedback terms are added to the quantizer. Multiple timings (one or more per integrator) for the FB topology can be specified by making tdac a list of lists, e.g. ``tdac = [[1, 2], [1, 2], [[0.5, 1], [1, 1.5]], []]`` In this example, the first two integrators have DACs with ``[1, 2]`` timing, the third has a pair of DACs, one with ``[0.5, 1]`` timing and the other with ``[1, 1.5]`` timing, and there is no direct feedback DAC to the quantizer. ordering : sequence, optional A vector specifying which NTF zero-pair to use in each resonator Default is for the zero-pairs to be used in the order specified in the NTF. bp : sequence, optional A vector specifying which resonator sections are bandpass. The default (``zeros(...)``) is for all sections to be lowpass. ABCDc : ndarray, optional The loop filter structure, in state-space form. If this argument is omitted, ABCDc is constructed according to "form." method : str, optional The default fitting method is ``'LOOP'``, which means that the DT and CT loop responses will be matched. Alternatively, it is possible to set the method to ``'NTF'``, which will result in the NTF responses to be matched. See :ref:`discrete-time-to-continuous-time-mapping` for a more in-depth discussion. **Returns:** ABCDc : ndarray A state-space description of the CT loop filter tdac2 : ndarray A matrix with the DAC timings, including ones that were automatically added. **Example:** Realize the NTF :math:`(1 - z^{-1})^2` with a CT system (cf with the example at :func:`mapCtoD`).:: from deltasigma import * ntf = ([1, 1], [0, 0], 1) ABCDc, tdac2 = realizeNTF_ct(ntf, 'FB') Returns: ABCDc:: [[ 0. 0. 1. -1. ] [ 1. 0. 0. -1.49999999] [ 0. 1. 0. 0. ]] tdac2:: [[-1. -1.] [ 0. 1.]] """ ntf_z, ntf_p, _ = _get_zpk(ntf) ntf_z = carray(ntf_z) ntf_p = carray(ntf_p) order = max(ntf_p.shape) order2 = order // 2 odd = order - 2 * order2 # compensate for limited accuracy of zero calculation ntf_z[np.abs(ntf_z - 1) < eps**(1. / (1. + order))] = 1. method = method.upper() if method not in ('LOOP', 'NTF'): raise ValueError('Unimplemented matching method %s.' % method) # check if multiple timings mode if (type(tdac) == list or type(tdac) == tuple) and len(tdac) and \ (type(tdac[0]) == list or type(tdac[0]) == tuple): if len(tdac) != order + 1: msg = 'For multi-timing tdac, len(tdac) ' + \ ' must be order+1.' raise ValueError(msg) if form != 'FB': msg = "Currently only supporting form='FB' " + \ 'for multi-timing tdac' raise ValueError(msg) multi_timing = True else: # single timing tdac = carray(tdac) if np.prod(tdac.shape) != 2: msg = 'For single-timing tdac, len(tdac) must be 2.' raise ValueError(msg) tdac.reshape((2, )) multi_timing = False if ordering is None: ordering = np.arange(order2) if bp is None: bp = np.zeros((order2, )) if not multi_timing: # Need direct terms for every interval of memory in the DAC n_direct = int(np.ceil(tdac[1])) - 1 if tdac[0] > 0 and tdac[0] < 1 and tdac[1] > 1 and tdac[1] < 2: n_extra = n_direct - 1 # tdac pulse spans a sample point else: n_extra = n_direct tdac2 = np.vstack((np.array((-1, -1)), np.array(tdac).reshape( (1, 2)), 0.5 * np.dot(np.ones((n_extra, 1)), np.array([[-1, 1]])) + np.cumsum(np.ones( (n_extra, 2)), 0) + (n_direct - n_extra))) else: n_direct = 0 n_extra = 0 if ABCDc is None: ABCDc = np.zeros((order + 1, order + 2)) # Stuff the A portion if odd: ABCDc[0, 0] = np.real(np.log(ntf_z[0])) ABCDc[1, 0] = 1 dline = np.array([0, 1, 2]) for i in range(order2): n = bp[i] i1 = 2 * i + odd zi = 2 * ordering[i] + odd w = np.abs(np.angle(ntf_z[zi])) ABCDc[i1 + dline, i1] = np.array([0, 1, n]) ABCDc[i1 + dline, i1 + 1] = np.array([-w**2, 0, 1 - n]) ABCDc[0, order] = 1 # 2006.10.02 Changed to -1 to make FF STF have +ve gain at DC ABCDc[0, order + 1] = -1 Ac = ABCDc[:order, :order] if form == 'FB': Cc = ABCDc[order, :order].reshape((1, -1)) if not multi_timing: Bc = np.hstack((np.eye(order), np.zeros((order, 1)))) Dc = np.hstack((np.zeros((1, order)), np.array([[1]]))) tp = np.tile(np.array(tdac).reshape((1, 2)), (order + 1, 1)) else: #Assemble tdac2, Bc and Dc tdac2 = np.array([[-1, -1]]) Bc = None Dc = None Bci = np.hstack((np.eye(order), np.zeros((order, 1)))) Dci = np.hstack((np.zeros((1, order)), np.array([[1]]))) for i in range(len(tdac)): tdi = tdac[i] if (type(tdi) in (tuple, list)) and len(tdi) and \ (type(tdi[0]) in (list, tuple)): for j in range(len(tdi)): tdj = tdi[j] tdac2 = np.vstack((tdac2, np.array(tdj).reshape(1, -1))) if Bc is not None: Bc = np.hstack((Bc, Bci[:, i].reshape((-1, 1)))) else: Bc = Bci[:, i].reshape((-1, 1)) if Dc is not None: Dc = np.hstack((Dc, Dci[:, i].reshape((-1, 1)))) else: Dc = Dci[:, i].reshape((-1, 1)) elif len( tdi): # we got tdac[i] = [a, b] where a, b are scalars tdac2 = np.vstack((tdac2, np.array(tdi).reshape(1, -1))) if Bc is not None: Bc = np.hstack((Bc, Bci[:, i].reshape((-1, 1)))) else: Bc = Bci[:, i].reshape((-1, 1)) if Dc is not None: Dc = np.hstack((Dc, Dci[:, i].reshape((-1, 1)))) else: Dc = Dci[:, i].reshape((-1, 1)) tp = tdac2[1:, :] elif form == 'FF': Cc = np.vstack((np.eye(order), np.zeros((1, order)))) Bc = np.vstack((np.array([[-1]]), np.zeros((order - 1, 1)))) Dc = np.vstack((np.zeros((order, 1)), np.array([[1]]))) tp = tdac # 2008-03-24 fix from Ayman Shabra else: raise ValueError('Sorry, no code for form "%s".', form) n_imp = int(np.ceil(2 * order + np.max(tdac2[:, 1]) + 1)) if method == 'LOOP': # Sample the L1 impulse response y = impL1(ntf, n_imp) else: # Sample the NTF impulse response y = dimpulse((ntf_z, ntf_p, 1., 1.), t=np.arange(n_imp + 1))[1][0] y = np.atleast_1d(y.squeeze()) sys_c = [] for i in range(Bc.shape[1]): # number of inputs sys_tmp = [] for j in range(Cc.shape[0]): # number of outputs sys_tmp.append(ss2zpk(Ac, Bc, Cc[j, :], Dc[j, :], input=i)) sys_c.append(sys_tmp) yy = pulse(sys_c, tp, 1, n_imp, 1) yy = np.squeeze(yy) # Endow yy with n_extra extra impulses. # These will need to be implemented with n_extra extra DACs. # !! Note: if t1=int, matlab says pulse(sys) @t1 ~=0 # !! This code corrects this problem. if n_extra > 0: y_right = padb(np.vstack((np.zeros((1, n_direct)), np.eye(n_direct))), n_imp + 1) # Replace the last column in yy with an ordered set of impulses if (n_direct > n_extra): yy = np.hstack((yy, y_right[:, 1:])) else: yy = np.hstack((yy[:, :-1], y_right)) if method == 'NTF': # convolve CT loop response and NTF response yynew = None for i in range(yy.shape[1]): yytmp = np.convolve(yy[:, i], y)[:-n_imp] if yynew is None: yynew = yytmp.reshape((-1, 1)) else: yynew = np.hstack((yynew, yytmp.reshape((-1, 1)))) yy = yynew e1 = np.zeros(y.shape) e1[0] = 1. y = y - e1 # Solve for the coefficients x = linalg.lstsq(yy, y, rcond=None)[0] if linalg.norm(np.dot(yy, x) - y) > 0.0001: warn('Pulse response fit is poor.') if form == 'FB': if not multi_timing: Bc2 = np.hstack((x[:order].reshape( (-1, 1)), np.zeros((order, n_extra)))) if n_extra > 0: Dc2 = np.hstack((np.array([[0]]), x[order:].reshape((-1, 1)))) else: Dc2 = x[order:].reshape((-1, 1)) else: BcDc = np.vstack((Bc, Dc)) i = np.nonzero(BcDc) BcDc[i] = x Bc2 = BcDc[:-1, :] Dc2 = BcDc[-1, :] elif form == 'FF': Bc2 = np.hstack((Bc, np.zeros((order, n_extra)))) Cc = x[:order].reshape((1, -1)) if n_extra > 0: Dc2 = np.hstack((np.array([[0]]), x[order:].T)) else: Dc2 = x[order:].T Dc1 = np.zeros((1, 1)) Dc = np.hstack((Dc1, np.atleast_2d(Dc2))) Bc1 = np.vstack((np.ones((1, 1)), np.zeros((order - 1, 1)))) Bc = np.hstack((Bc1, Bc2)) # Scale Bc1 for unity STF magnitude at f0 fz = np.angle(ntf_z) / (2 * np.pi) f1 = fz[0] ibz = np.abs(fz - f1) <= np.abs(fz + f1) fz = fz[ibz] f0 = np.mean(fz) if np.min(np.abs(fz)) < 3 * np.min(np.abs(fz - f0)): f0 = 0 L0c = ss2zpk(Ac, Bc1, Cc, Dc1) G0 = evalTFP(L0c, ntf, f0) if f0 == 0: Bc[:, 0] = np.dot( Bc[:, 0], np.abs( np.dot(Bc[0, 1:], (tdac2[1:, 1] - tdac2[1:, 0])) / Bc[0, 0])) else: Bc[:, 0] = Bc[:, 0] / np.abs(G0) ABCDc = np.vstack((np.hstack((Ac, Bc)), np.hstack((Cc, Dc)))) #ABCDc = np.dot(ABCDc, np.abs(ABCDc) > eps**(1./2.)) ABCDc[np.nonzero(np.abs(ABCDc) < eps**(1. / 2))] = 0. return ABCDc, tdac2
def realizeNTF_ct(ntf, form='FB', tdac=(0, 1), ordering=None, bp=None, ABCDc=None, method='LOOP'): """Realize an NTF with a continuous-time loop filter. **Parameters:** ntf : object A noise transfer function (NTF). form : str, optional A string specifying the topology of the loop filter. * 'FB': Feedback form, * 'FF': Feedforward form For the FB structure, the elements of ``Bc`` are calculated so that the sampled pulse response matches the L1 impulse response. For the FF structure, ``Cc`` is calculated. tdac : sequence, optional The timing for the feedback DAC(s). If ``tdac[0] >= 1``, direct feedback terms are added to the quantizer. Multiple timings (one or more per integrator) for the FB topology can be specified by making tdac a list of lists, e.g. ``tdac = [[1, 2], [1, 2], [[0.5, 1], [1, 1.5]], []]`` In this example, the first two integrators have DACs with ``[1, 2]`` timing, the third has a pair of DACs, one with ``[0.5, 1]`` timing and the other with ``[1, 1.5]`` timing, and there is no direct feedback DAC to the quantizer. ordering : sequence, optional A vector specifying which NTF zero-pair to use in each resonator Default is for the zero-pairs to be used in the order specified in the NTF. bp : sequence, optional A vector specifying which resonator sections are bandpass. The default (``zeros(...)``) is for all sections to be lowpass. ABCDc : ndarray, optional The loop filter structure, in state-space form. If this argument is omitted, ABCDc is constructed according to "form." method : str, optional The default fitting method is ``'LOOP'``, which means that the DT and CT loop responses will be matched. Alternatively, it is possible to set the method to ``'NTF'``, which will result in the NTF responses to be matched. See :ref:`discrete-time-to-continuous-time-mapping` for a more in-depth discussion. **Returns:** ABCDc : ndarray A state-space description of the CT loop filter tdac2 : ndarray A matrix with the DAC timings, including ones that were automatically added. **Example:** Realize the NTF :math:`(1 - z^{-1})^2` with a CT system (cf with the example at :func:`mapCtoD`).:: from deltasigma import * ntf = ([1, 1], [0, 0], 1) ABCDc, tdac2 = realizeNTF_ct(ntf, 'FB') Returns: ABCDc:: [[ 0. 0. 1. -1. ] [ 1. 0. 0. -1.49999999] [ 0. 1. 0. 0. ]] tdac2:: [[-1. -1.] [ 0. 1.]] """ ntf_z, ntf_p, _ = _get_zpk(ntf) ntf_z = carray(ntf_z) ntf_p = carray(ntf_p) order = max(ntf_p.shape) order2 = int(np.floor(order/2.)) odd = order - 2*order2 # compensate for limited accuracy of zero calculation ntf_z[np.abs(ntf_z - 1) < eps**(1./(1. + order))] = 1. method = method.upper() if method not in ('LOOP', 'NTF'): raise ValueError('Unimplemented matching method %s.' % method) # check if multiple timings mode if (type(tdac) == list or type(tdac) == tuple) and len(tdac) and \ (type(tdac[0]) == list or type(tdac[0]) == tuple): if len(tdac) != order + 1: msg = 'For multi-timing tdac, len(tdac) ' + \ ' must be order+1.' raise ValueError(msg) if form != 'FB': msg = "Currently only supporting form='FB' " + \ 'for multi-timing tdac' raise ValueError(msg) multi_timing = True else: # single timing tdac = carray(tdac) if np.prod(tdac.shape) != 2: msg = 'For single-timing tdac, len(tdac) must be 2.' raise ValueError(msg) tdac.reshape((2,)) multi_timing = False if ordering is None: ordering = np.arange(order2) if bp is None: bp = np.zeros((order2,)) if not multi_timing: # Need direct terms for every interval of memory in the DAC n_direct = np.ceil(tdac[1]) - 1 if tdac[0] > 0 and tdac[0] < 1 and tdac[1] > 1 and tdac[1] < 2: n_extra = n_direct - 1 # tdac pulse spans a sample point else: n_extra = n_direct tdac2 = np.vstack( (np.array((-1, -1)), np.array(tdac).reshape((1, 2)), 0.5*np.dot(np.ones((n_extra, 1)), np.array([[-1, 1]])) + np.cumsum(np.ones((n_extra, 2)), 0) + (n_direct - n_extra) )) else: n_direct = 0 n_extra = 0 if ABCDc is None: ABCDc = np.zeros((order + 1, order + 2)) # Stuff the A portion if odd: ABCDc[0, 0] = np.real(np.log(ntf_z[0])) ABCDc[1, 0] = 1 dline = np.array([0, 1, 2]) for i in range(order2): n = bp[i] i1 = 2*i + odd zi = 2*ordering[i] + odd w = np.abs(np.angle(ntf_z[zi])) ABCDc[i1 + dline, i1] = np.array([0, 1, n]) ABCDc[i1 + dline, i1 + 1] = np.array([-w**2, 0, 1 - n]) ABCDc[0, order] = 1 # 2006.10.02 Changed to -1 to make FF STF have +ve gain at DC ABCDc[0, order + 1] = -1 Ac = ABCDc[:order, :order] if form == 'FB': Cc = ABCDc[order, :order].reshape((1, -1)) if not multi_timing: Bc = np.hstack((np.eye(order), np.zeros((order, 1)))) Dc = np.hstack((np.zeros((1, order)), np.array([[1]]))) tp = np.tile(np.array(tdac).reshape((1, 2)), (order + 1, 1)) else: #Assemble tdac2, Bc and Dc tdac2 = np.array([[-1, -1]]) Bc = None Dc = None Bci = np.hstack((np.eye(order), np.zeros((order, 1)))) Dci = np.hstack((np.zeros((1, order)), np.array([[1]]))) for i in range(len(tdac)): tdi = tdac[i] if (type(tdi) in (tuple, list)) and len(tdi) and \ (type(tdi[0]) in (list, tuple)): for j in range(len(tdi)): tdj = tdi[j] tdac2 = np.vstack((tdac2, np.array(tdj).reshape(1,-1))) if Bc is not None: Bc = np.hstack((Bc, Bci[:, i].reshape((-1, 1)))) else: Bc = Bci[:, i].reshape((-1, 1)) if Dc is not None: Dc = np.hstack((Dc, Dci[:, i].reshape((-1, 1)))) else: Dc = Dci[:, i].reshape((-1, 1)) elif len(tdi): # we got tdac[i] = [a, b] where a, b are scalars tdac2 = np.vstack((tdac2, np.array(tdi).reshape(1,-1))) if Bc is not None: Bc = np.hstack((Bc, Bci[:, i].reshape((-1, 1)))) else: Bc = Bci[:, i].reshape((-1, 1)) if Dc is not None: Dc = np.hstack((Dc, Dci[:, i].reshape((-1, 1)))) else: Dc = Dci[:, i].reshape((-1, 1)) tp = tdac2[1:, :] elif form == 'FF': Cc = np.vstack((np.eye(order), np.zeros((1, order)))) Bc = np.vstack((np.array([[-1]]), np.zeros((order-1, 1)))) Dc = np.vstack((np.zeros((order, 1)), np.array([[1]]))) tp = tdac # 2008-03-24 fix from Ayman Shabra else: raise ValueError('Sorry, no code for form "%s".', form) n_imp = np.ceil(2*order + np.max(tdac2[:, 1]) + 1) if method == 'LOOP': # Sample the L1 impulse response y = impL1(ntf, n_imp) else: # Sample the NTF impulse response y = dimpulse((ntf_z, ntf_p, 1., 1.), t=np.arange(n_imp+1))[1][0] y = np.atleast_1d(y.squeeze()) sys_c = [] for i in range(Bc.shape[1]): # number of inputs sys_tmp = [] for j in range(Cc.shape[0]): # number of outputs sys_tmp.append(ss2zpk(Ac, Bc, Cc[j, :], Dc[j, :], input=i)) sys_c.append(sys_tmp) yy = pulse(sys_c, tp, 1, n_imp, 1) yy = np.squeeze(yy) # Endow yy with n_extra extra impulses. # These will need to be implemented with n_extra extra DACs. # !! Note: if t1=int, matlab says pulse(sys) @t1 ~=0 # !! This code corrects this problem. if n_extra > 0: y_right = padb(np.vstack((np.zeros((1, n_direct)), np.eye(n_direct))), n_imp + 1) # Replace the last column in yy with an ordered set of impulses if (n_direct > n_extra): yy = np.hstack((yy, y_right[:, 1:])) else: yy = np.hstack((yy[:, :-1], y_right)) if method == 'NTF': # convolve CT loop response and NTF response yynew = None for i in range(yy.shape[1]): yytmp = np.convolve(yy[:, i], y)[:-n_imp] if yynew is None: yynew = yytmp.reshape((-1, 1)) else: yynew = np.hstack((yynew, yytmp.reshape((-1, 1)))) yy = yynew e1 = np.zeros(y.shape) e1[0] = 1. y = y - e1 # Solve for the coefficients x = linalg.lstsq(yy, y)[0] if linalg.norm(np.dot(yy, x) - y) > 0.0001: warn('Pulse response fit is poor.') if form == 'FB': if not multi_timing: Bc2 = np.hstack((x[:order].reshape((-1, 1)), np.zeros((order, n_extra)))) if n_extra > 0: Dc2 = np.hstack((np.array([[0]]), x[order:].reshape((-1, 1)))) else: Dc2 = x[order:].reshape((-1, 1)) else: BcDc = np.vstack((Bc, Dc)) i = np.nonzero(BcDc) BcDc[i] = x Bc2 = BcDc[:-1, :] Dc2 = BcDc[-1, :] elif form == 'FF': Bc2 = np.hstack((Bc, np.zeros((order, n_extra)))) Cc = x[:order].reshape((1, -1)) if n_extra > 0: Dc2 = np.hstack((np.array([[0]]), x[order:].T)) else: Dc2 = x[order:].T Dc1 = np.zeros((1, 1)) Dc = np.hstack((Dc1, np.atleast_2d(Dc2))) Bc1 = np.vstack((np.ones((1, 1)), np.zeros((order - 1, 1)))) Bc = np.hstack((Bc1, Bc2)) # Scale Bc1 for unity STF magnitude at f0 fz = np.angle(ntf_z)/(2*np.pi) f1 = fz[0] ibz = np.abs(fz - f1) <= np.abs(fz + f1) fz = fz[ibz] f0 = np.mean(fz) if np.min(np.abs(fz)) < 3*np.min(np.abs(fz - f0)): f0 = 0 L0c = ss2zpk(Ac, Bc1, Cc, Dc1) G0 = evalTFP(L0c, ntf, f0) if f0 == 0: Bc[:, 0] = np.dot(Bc[:, 0], np.abs(np.dot(Bc[0, 1:], (tdac2[1:, 1] - tdac2[1:, 0])) /Bc[0, 0])) else: Bc[:, 0] = Bc[:, 0]/np.abs(G0) ABCDc = np.vstack(( np.hstack((Ac, Bc)), np.hstack((Cc, Dc)) )) #ABCDc = np.dot(ABCDc, np.abs(ABCDc) > eps**(1./2.)) ABCDc[np.nonzero(np.abs(ABCDc) < eps**(1./2))] = 0. return ABCDc, tdac2
import numpy as np import scipy.signal as signal import matplotlib.pyplot as plt import fwliir n = 60 fs = 1000 ts = 1 / fs b_t, a_t = signal.iirdesign( wp=0.6, ws=0.4, gpass=1, gstop=40, ftype='cheby1', analog=False ) w, h_t = signal.freqz(b_t, a_t) t, (im_t,) = signal.dimpulse((b_t, a_t, ts), n=n) approx = fwliir.configure_genetic_approx( nbits=16, nlimit=10, poolsize=500, ngen=500, verbose=True ) best_slns, pool, logbook = approx(im_t, ts) iir_min_err = best_slns[0] sos_min_err = fwliir.iir2sos(iir_min_err) _, h_min_err = signal.sosfreqz(sos_min_err, worN=w) _, im_min_err = fwliir.impulse(iir_min_err, ts, n) iir_min_n = sorted(best_slns, key=lambda iir: len(iir))[0] sos_min_n = fwliir.iir2sos(iir_min_n) _, h_min_n = signal.sosfreqz(sos_min_n, worN=w) _, im_min_n = fwliir.impulse(iir_min_n, ts, n)
def __init__(self, ninputs, enc_fmaps, kwidth, activations, bnorm=False, dropout=0., pooling=4, z_dim=1024, z_all=False, skip=True, skip_blacklist=[], dec_activations=None, cuda=False, bias=False, aal=False, wd=0., core2d=False, core2d_kwidth=None, core2d_felayers=1, skip_mode='concat'): super(Generator, self).__init__() self.skip_mode = skip_mode self.skip = skip self.z_dim = z_dim self.z_all = z_all self.do_cuda = cuda self.core2d = core2d self.wd = wd self.skip_blacklist = skip_blacklist if core2d_kwidth is None: core2d_kwidth = kwidth self.gen_enc = nn.ModuleList() if aal: from scipy.signal import cheby1, dlti, dimpulse system = dlti(*cheby1(8, 0.05, 0.8 / 2)) tout, yout = dimpulse(system) filter_h = yout[0] self.filter_h = filter_h else: self.filter_h = None if isinstance(activations, str): activations = getattr(nn, activations)() if not isinstance(activations, list): activations = [activations] * len(enc_fmaps) for layer_idx, (fmaps, act) in enumerate(zip(enc_fmaps, activations)): if layer_idx == 0: inp = ninputs else: inp = enc_fmaps[layer_idx - 1] if core2d: if layer_idx < core2d_felayers: self.gen_enc.append(GBlock(inp, fmaps, kwidth, act, padding=None, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias, aal_h=self.filter_h)) else: if layer_idx == core2d_felayers: inp = 1 self.gen_enc.append(G2Block(inp, fmaps, core2d_kwidth, act, padding=None, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias)) else: self.gen_enc.append(GBlock(inp, fmaps, kwidth, act, padding=None, snorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias, aal_h=self.filter_h)) dec_inp = enc_fmaps[-1] if self.core2d: dec_fmaps = enc_fmaps[::-1][:-2] + [1, 1] else: dec_fmaps = enc_fmaps[::-1][1:] + [1] self.gen_dec = nn.ModuleList() if dec_activations is None: dec_activations = activations dec_inp += z_dim for layer_idx, (fmaps, act) in enumerate(zip(dec_fmaps, dec_activations)): if skip and layer_idx > 0 and layer_idx not in skip_blacklist: if self.skip_mode == 'concat': dec_inp += enc_fmaps[-(layer_idx + 1)] if z_all and layer_idx > 0: dec_inp += z_dim if layer_idx >= len(dec_fmaps) - 1: act = nn.Tanh() bnorm = False dropout = 0 if layer_idx < len(dec_fmaps) - 1 and core2d: self.gen_dec.append(G2Block(dec_inp, fmaps, core2d_kwidth + 1, act, padding=core2d_kwidth // 2, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=False, bias=bias)) else: if layer_idx == len(dec_fmaps) - 1: dec_inp = enc_fmaps[0] if skip and layer_idx not in skip_blacklist: dec_inp += enc_fmaps[-(layer_idx + 1)] self.gen_dec.append(GBlock(dec_inp, fmaps, kwidth + 1, act, padding=kwidth // 2, snorm=bnorm, dropout=dropout, pooling=pooling, enc=False, bias=bias)) dec_inp = fmaps self.load_pretrained('weights_EOE_G-Generator1D-61101.ckpt', load_last=True) self.fc = nn.Sequential( nn.Linear(4096, 256), #16384 for 4 seconds nn.PReLU(256), nn.Linear(256, 128), nn.PReLU(128), nn.Linear(128, 128) )
h = [[h11, h12], [h21, h22]] #h = [[h11, h12, [[], h22]] #%% OPOM Ts = 0.1 sys_opom = OPOM(h, Ts) #%% Response # -> from the OPOM representation # -> the input is delta u, y=f(du,x) # y11 = y[0][:,0] # y12 = y[1][:,0] # y21 = y[0][:,1] # y22 = y[1][:,1] sys = signal.StateSpace(sys_opom.A, sys_opom.B, sys_opom.C, sys_opom.D, dt=Ts) t, y = signal.dimpulse(sys, n=3000) # -> from the original representation g11 = h11.tf T11, y11 = signal.step(g11) T11 += h11.delay g12 = h12.tf T12, y12 = signal.step(g12) T12 += h12.delay g21 = h21.tf T21, y21 = signal.step(g21) T21 += h21.delay g22 = h22.tf
def __init__(self, ninputs, enc_fmaps, kwidth, activations, lnorm=False, dropout=0., pooling=2, z_dim=256, z_all=False, skip=True, skip_blacklist=[], dec_activations=None, cuda=False, bias=False, aal=False, wd=0., skip_init='one', skip_dropout=0., no_tanh=False, aal_out=False, rnn_core=False, linterp=False, mlpconv=False, dec_kwidth=None, no_z=False, skip_type='alpha', num_spks=None, multilayer_out=False, skip_merge='sum', snorm=False, convblock=False, post_skip=False, pos_code=False, satt=False, dec_fmaps=None, up_poolings=None, post_proc=False, out_gate=False, linterp_mode='linear', hidden_comb=False, big_out_filter=False, z_std=1, freeze_enc=False, skip_kwidth=11, pad_type='constant'): # if num_spks is specified, do onehot coditioners in dec stages # subract_mean: from output signal, get rif of mean by windows # multilayer_out: add some convs in between gblocks in decoder super().__init__(name='Generator1D') self.dec_kwidth = dec_kwidth self.skip_kwidth = skip_kwidth self.skip = skip self.skip_init = skip_init self.skip_dropout = skip_dropout self.snorm = snorm self.z_dim = z_dim self.z_all = z_all self.pos_code = pos_code self.post_skip = post_skip self.big_out_filter = big_out_filter self.satt = satt self.post_proc = post_proc self.pad_type = pad_type self.onehot = num_spks is not None if self.onehot: assert num_spks > 0 self.num_spks = num_spks # do not place any z self.no_z = no_z self.do_cuda = cuda self.wd = wd self.no_tanh = no_tanh self.skip_blacklist = skip_blacklist self.z_std = z_std self.freeze_enc = freeze_enc self.gen_enc = nn.ModuleList() if aal or aal_out: # Make cheby1 filter to include into pytorch conv blocks from scipy.signal import cheby1, dlti, dimpulse system = dlti(*cheby1(8, 0.05, 0.8 / pooling)) tout, yout = dimpulse(system) filter_h = yout[0] if aal: self.filter_h = filter_h else: self.filter_h = None if dec_kwidth is None: dec_kwidth = kwidth if isinstance(activations, str): if activations != 'glu': activations = getattr(nn, activations)() if not isinstance(activations, list): activations = [activations] * len(enc_fmaps) if not isinstance(pooling, list) or len(pooling) == 1: pooling = [pooling] * len(enc_fmaps) skips = {} # Build Encoder for layer_idx, (fmaps, pool, act) in enumerate(zip(enc_fmaps, pooling, activations)): if layer_idx == 0: inp = ninputs else: inp = enc_fmaps[layer_idx - 1] if self.skip and layer_idx < (len(enc_fmaps) - 1): if layer_idx not in self.skip_blacklist: l_i = layer_idx gskip = GSkip(skip_type, fmaps, skip_init, skip_dropout, merge_mode=skip_merge, cuda=self.do_cuda, kwidth=self.skip_kwidth) skips[l_i] = {'alpha':gskip} setattr(self, 'alpha_{}'.format(l_i), skips[l_i]['alpha']) self.gen_enc.append(GBlock(inp, fmaps, kwidth, act, padding=None, lnorm=lnorm, dropout=dropout, pooling=pool, enc=True, bias=bias, aal_h=self.filter_h, snorm=snorm, convblock=convblock, satt=self.satt, pad_type=pad_type)) self.skips = skips dec_inp = enc_fmaps[-1] if dec_fmaps is None: if mlpconv: dec_fmaps = enc_fmaps[:-1][::-1] + [16, 8, 1] print(dec_fmaps) up_poolings = [pooling] * (len(dec_fmaps) - 2) + [1] * 3 add_activations = [nn.PReLU(16), nn.PReLU(8), nn.PReLU(1)] raise NotImplementedError('MLPconv is not useful and should be' ' deleted') else: dec_fmaps = enc_fmaps[:-1][::-1] + [1] up_poolings = pooling[::-1] #up_poolings = [pooling] * len(dec_fmaps) print('up_poolings: ', up_poolings) self.up_poolings = up_poolings else: assert up_poolings is not None self.up_poolings = up_poolings if rnn_core: self.z_all = False z_all = False # place a bidirectional RNN layer in the core to condition # everything to everything AND Z will be the init state of it self.rnn_core = nn.LSTM(dec_inp, dec_inp // 2, bidirectional=True, batch_first=True) else: if no_z: all_z = False else: dec_inp += z_dim #print(dec_fmaps) # Build Decoder self.gen_dec = nn.ModuleList() if dec_activations is None: # assign same activations as in Encoder dec_activations = [activations[0]] * len(dec_fmaps) else: if mlpconv: dec_activations = dec_activations[:-1] dec_activations += add_activations enc_layer_idx = len(enc_fmaps) - 1 for layer_idx, (fmaps, act) in enumerate(zip(dec_fmaps, dec_activations)): if skip and layer_idx > 0 and enc_layer_idx not in skip_blacklist \ and up_poolings[layer_idx] > 1: if skip_merge == 'concat': dec_inp *= 2 print('Added skip conn input of enc idx: {} and size:' ' {}'.format(enc_layer_idx, dec_inp)) if z_all and layer_idx > 0: dec_inp += z_dim if self.onehot: dec_inp += self.num_spks if layer_idx >= len(dec_fmaps) - 1: if self.no_tanh: act = None else: act = nn.Tanh() lnorm = False dropout = 0 if up_poolings[layer_idx] > 1: pooling = up_poolings[layer_idx] self.gen_dec.append(GBlock(dec_inp, fmaps, dec_kwidth, act, padding=0, lnorm=lnorm, dropout=dropout, pooling=pooling, enc=False, bias=bias, linterp=linterp, linterp_mode=linterp_mode, convblock=convblock, comb=hidden_comb, pad_type=pad_type)) else: self.gen_dec.append(GBlock(dec_inp, fmaps, dec_kwidth, act, lnorm=lnorm, dropout=dropout, pooling=1, padding=0,#kwidth//2, enc=True, bias=bias, convblock=convblock, pad_type=pad_type)) dec_inp = fmaps if aal_out: # make AAL filter to put in output self.aal_out = nn.Conv1d(1, 1, filter_h.shape[0] + 1, stride=1, padding=filter_h.shape[0] // 2, bias=False) print('filter_h shape: ', filter_h.shape) # apply AAL weights, reshaping impulse response to match # in channels and out channels aal_t = torch.FloatTensor(filter_h).view(1, 1, -1) aal_t = torch.cat((aal_t, torch.zeros(1, 1, 1)), dim=-1) self.aal_out.weight.data = aal_t print('aal_t size: ', aal_t.size()) if post_proc: self.comb_net = PostProcessingCombNet(1, 512) if out_gate: self.out_gate = OutGate(1, 1) if big_out_filter: self.out_filter = nn.Conv1d(1, 1, 513, padding=513//2)
w, 180 * np.angle(h_sma) / pi, # Convert argument to degrees color=col1) plt.plot(w, 180 * np.angle(h_ema) / pi, color=col2) plt.xlabel('Frequency \n (Hz)') plt.ylabel('Phase \n (°)') plt.xlim(0, f_s / 2) plt.ylim(-180, 90) plt.yticks([-180, -135, -90, -45, 0, 45, 90]) plt.axvline(f_c, color=col3) plt.grid() plt.savefig("bode.svg") plt.show() # Plot the impulse response t, y_sma = dimpulse((b_sma, a_sma, 1 / f_s), n=2 * N) t, y_ema = dimpulse((b_ema, a_ema, 1 / f_s), n=2 * N) #plt.suptitle('Impulse Response') plt.plot(t, y_sma[0], 'o-', color=col1, label='SMA') plt.plot(t, y_ema[0], 'o-', color=col2, label='EMA') plt.xlabel('Time \n (seconds)') plt.ylabel('Output') plt.xlim(-1 / f_s, 2 * N / f_s) plt.legend() plt.grid() plt.show() # Plot the step response t, y_sma = dstep((b_sma, a_sma, 1 / f_s), n=2 * N) t, y_ema = dstep((b_ema, a_ema, 1 / f_s), n=2 * N) #plt.suptitle('Step Response')
def __init__(self, ninputs, enc_fmaps, kwidth, activations, bnorm=False, dropout=0., pooling=4, z_dim=1024, z_all=False, skip=True, skip_blacklist=[], dec_activations=None, cuda=False, bias=False, aal=False, wd=0., core2d=False, core2d_kwidth=None, core2d_felayers=1, skip_mode='concat'): # aal: anti-aliasing filter prior to each striding conv in enc super(Generator, self).__init__() self.skip_mode = skip_mode self.skip = skip self.z_dim = z_dim self.z_all = z_all self.do_cuda = cuda self.core2d = core2d self.wd = wd self.skip_blacklist = skip_blacklist if core2d_kwidth is None: core2d_kwidth = kwidth self.gen_enc = nn.ModuleList() if aal: # Make cheby1 filter to include into pytorch conv blocks from scipy.signal import cheby1, dlti, dimpulse system = dlti(*cheby1(8, 0.05, 0.8 / 2)) tout, yout = dimpulse(system) filter_h = yout[0] self.filter_h = filter_h else: self.filter_h = None if isinstance(activations, str): activations = getattr(nn, activations)() if not isinstance(activations, list): activations = [activations] * len(enc_fmaps) # always begin with 1D block for layer_idx, (fmaps, act) in enumerate(zip(enc_fmaps, activations)): if layer_idx == 0: inp = ninputs else: inp = enc_fmaps[layer_idx - 1] if core2d: if layer_idx < core2d_felayers: self.gen_enc.append( GBlock(inp, fmaps, kwidth, act, padding=None, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias, aal_h=self.filter_h)) else: if layer_idx == core2d_felayers: # fmaps is 1 after conv1d blocks inp = 1 self.gen_enc.append( G2Block(inp, fmaps, core2d_kwidth, act, padding=None, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias)) else: self.gen_enc.append( GBlock(inp, fmaps, kwidth, act, padding=None, snorm=bnorm, dropout=dropout, pooling=pooling, enc=True, bias=bias, aal_h=self.filter_h)) dec_inp = enc_fmaps[-1] if self.core2d: # dec_fmaps = enc_fmaps[::-1][1:-2]+ [1, 1] dec_fmaps = enc_fmaps[::-1][:-2] + [1, 1] else: dec_fmaps = enc_fmaps[::-1][1:] + [1] # print(dec_fmaps) # print(enc_fmaps) # print('dec_fmaps: ', dec_fmaps) self.gen_dec = nn.ModuleList() if dec_activations is None: dec_activations = activations dec_inp += z_dim for layer_idx, (fmaps, act) in enumerate(zip(dec_fmaps, dec_activations)): if skip and layer_idx > 0 and layer_idx not in skip_blacklist: # print('Adding skip conn input of idx: {} and size:' # ' {}'.format(layer_idx, dec_inp)) if self.skip_mode == 'concat': dec_inp += enc_fmaps[-(layer_idx + 1)] if z_all and layer_idx > 0: dec_inp += z_dim if layer_idx >= len(dec_fmaps) - 1: # act = None #nn.Tanh() act = nn.Tanh() bnorm = False dropout = 0 if layer_idx < len(dec_fmaps) - 1 and core2d: self.gen_dec.append( G2Block(dec_inp, fmaps, core2d_kwidth + 1, act, padding=core2d_kwidth // 2, bnorm=bnorm, dropout=dropout, pooling=pooling, enc=False, bias=bias)) else: if layer_idx == len(dec_fmaps) - 1: # after conv2d channel condensation, fmaps mirror the ones # extracted in 1D encoder dec_inp = enc_fmaps[0] if skip and layer_idx not in skip_blacklist: dec_inp += enc_fmaps[-(layer_idx + 1)] self.gen_dec.append( GBlock(dec_inp, fmaps, kwidth + 1, act, padding=kwidth // 2, snorm=bnorm, dropout=dropout, pooling=pooling, enc=False, bias=bias)) dec_inp = fmaps self.load_pretrained('weights_EOE_G-Generator1D-61101.ckpt', load_last=True) self.fc = nn.Sequential( nn.Linear(4096, 256), #16384 for 4 seconds nn.PReLU(256), nn.Linear(256, 128), nn.PReLU(128), nn.Linear(128, 128))
def impulse_resp(b, a, fs): t, y = sg.dimpulse((b, a, 1 / fs)) plt.figure(6) plt.step(t, np.squeeze(y))
#plt.setp(baseline, 'color', 'b', 'linewidth', 0.5) #plt.plot(Wp, H_y_dB, color='b', linewidth=1) f = F_nyq * Wp[0:N] / (2 * np.pi) plt.plot(f, H_y_abs, color='b', linewidth=1) plt.grid(True) plt.title("H_y_abs modulo, monolatera, calcolata dai polin. B_y, A_y") ax1.axis([0, 1.05 * max(f), 0, 1.1 * max(H_y_abs)]) # #=========================================================\ # 9) Dalla A ricavo la riposta impulsiva h_y: # t = np.arange(N) * Ts A = H_y_abs[0:N] sys = B_y, A_y, Ts tmp = dimpulse(sys, n=N) h_y_dimp = np.array( tmp[1:]).flatten() # From tuple to ndarray, then flatten dimensions if EXP_WIN: perc = 10 / 100 a = np.log(perc) exp_win = np.exp(a * (np.arange(N) / (N - 1))) # exp. win. start at 1.st sample w_rms = np.std(exp_win) # window RMS factor h_a_calc = h_y_dimp * exp_win # with final amplitude perc, long N points else: exp_win = np.ones(N) # flat window starting at 1.st sample h_a_calc = h_y_dimp # #
def l1norm(H): """Compute the l1-norm of a z-domain transfer function. """ _, y = dimpulse(H, t=np.arange(100)) return np.sum(np.abs(y[0]))
def plot_dtlti_analysis(z, p, k, fs=1, Nf=2**10, Nt=2**5): """Plot linear, time-invariant, discrete-time system. Impulse, step, frequency response (level/phase/group delay) and z-plane of transfer function H(z) given as zeros/poles/gain description Note that we use fs only for the frequency responses """ # still hard coded, TBD: # figure size # group_delay discontinuities and automatic ylim, yticks is not # useful sometimes plt.figure(figsize=(9, 9), tight_layout=True) mu = np.arange(Nf) df = fs / Nf dW = 2 * np.pi / Nf f = mu * df # frequency vector [0...fs) W = mu * dW # digital angular frequency [0...2pi) sys = signal.dlti(z, p, k, dt=True) sys_ba = signal.TransferFunction(sys) b = sys_ba.num # we need coeff b,a for group_delay() a = sys_ba.den [W, H] = signal.dlti.freqresp(sys, W) [W, gd] = signal.group_delay((b, a), w=W) # gd in samples h = signal.dimpulse(sys, n=Nt) he = signal.dstep(sys, n=Nt) # plot frequency response: level ax1 = plt.subplot(3, 2, 1) ax1t = ax1.twiny() ax1.grid(True, color='lavender', which='major') # plotted below grid :-( # ax1t.grid(True, color='mistyrose', which='minor') ax1.plot(W / (2 * np.pi), 20 * np.log10(np.abs(H)), color='C0', lw=2) ax1.set_xscale('linear') ax1.set_xlim([0, 1]) ax1.tick_params(axis='x', labelcolor='C0') ax1.set_xlabel(r'$\frac{\Omega}{2\pi} = \frac{f}{f_s}$', color='C0') ax1.set_xticks(np.arange(11) / 10) ax1.set_ylabel('level in dB or 20 lg|H| / dB', color='k') ax1.set_axisbelow(True) ax1t.plot(f, 20 * np.log10(np.abs(H)), color='C3', lw=2) ax1t.set_xscale('log') ax1t.set_xlim([f[1], f[-1]]) ax1t.tick_params(axis='x', labelcolor='C3') ax1t.set_xlabel('frequency in Hz or f / Hz for $f_s$ = ' + '{0:5.2f}'.format(fs) + ' Hz', color='C3') ax1t.set_axisbelow(True) # plot impulse response ax2 = plt.subplot(3, 2, 2) ax2.stem(np.squeeze(h[0]), np.squeeze(h[1]), use_line_collection=True, linefmt='C0:', markerfmt='C0o', basefmt='C0:') ax2.xaxis.set_major_locator(MaxNLocator(integer=True)) ax2.grid(True) ax2.set_xlabel(r'$k$') ax2.set_ylabel(r'impulse response $h[k]$') # plot frequency response: phase ax3 = plt.subplot(3, 2, 3) ax3.plot(W, np.unwrap(np.angle(H))) ax3.set_xlabel( r'digital angular frequency in radian or $\Omega$ / rad') ax3.set_ylabel(r'phase in radian or $\angle$ H / rad') ax3.set_xlim([0, 2 * np.pi]) ax3.set_xticks(np.arange(9) * np.pi / 4) ax3.set_xticklabels([ r'0', r'$\pi/4$', r'$\pi/2$', r'$3/4\pi$', r'$\pi$', r'$5/4\pi$', r'$3/2\pi$', r'$7/4\pi$', r'$2\pi$' ]) # ax3.set_ylim([-180, +180]) # ax3.set_yticks(np.arange(-180, +180+45, 45)) ax3.grid(True) # plot step response ax4 = plt.subplot(3, 2, 4) ax4.stem(np.squeeze(he[0]), np.squeeze(he[1]), use_line_collection=True, linefmt='C0:', markerfmt='C0o', basefmt='C0:') ax4.xaxis.set_major_locator(MaxNLocator(integer=True)) ax4.grid(True) ax4.set_xlabel(r'$k$') ax4.set_ylabel(r'step response $h_\epsilon[k]$') # plot frequency response: group delay ax5 = plt.subplot(3, 2, 5) ax5.plot(W / np.pi, gd / fs) ax5.set_xscale('linear') ax5.set_xlim([0, 2]) ax5.set_xlabel(r'$\frac{\Omega}{\pi}$') ax5.set_ylabel(r'group delay in seconds or $\tau_\mathrm{GD}$ / s') ax5.grid(True, which='both') # zplane ax6 = plt.subplot(3, 2, 6) plot_zplane(sys.zeros, sys.poles, sys.gain) # see function above
def impz(system: tuple, n: int = None, fs: int = 1) -> Tuple: """ Impulse response of a digital filter. Parameters ---------- system : a tuple of array_like describing the system. The following gives the number of elements in the tuple and the interpretation: * (num, den) n : int, optional The number of time points to compute. fs : int optional Sampling frequency to calcurate time points. default is 1. Returns ------- T : ndarray A 1-D array of time points. yout : ndarray A 1-D array containing the impulse response of the system (except for singularities at zero). Notes ----- If (num, den) is passed in for ``system``, coefficients for both the numerator and denominator should be specified in describing exponent order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``). """ # when FIR filter if type(system[1]) == int and system[1] == 1: # calcurate time points if n == None: # automatically determine the length of time points T = np.arange(0, (len(system[0])) / fs, 1 / fs) else: # determine the time points which length is n T = np.arange(0, n / fs, 1 / fs) # make impulse signal x = np.zeros(len(T)) x[0] = 1 # output the impulse response yout = signal.lfilter(system[0], system[1], x) else: # when IIR filter # convert to instance of dlti dl = signal.dlti(system[0], system[1], dt=1 / fs) # output impulse response of discrete-time system. if n == None: i_d = signal.dimpulse(dl) else: i_d = signal.dimpulse(dl, n=n) # split to time points and impulse response T = i_d[0] yout = i_d[1][0] return T, yout
plt.plot(W[1], 20 * np.log10(abs(H[1])), 'g', label='alpha = 0.5') # alpha = 0.5 plt.plot(W[2], 20 * np.log10(abs(H[2])), 'b', label='alpha = 0.1') # alpha = 0.1 plt.plot(W[3], 20 * np.log10(abs(H[3])), 'y', label='alpha = -0.5') # alpha = -0.5 legend = plt.legend() plt.ylabel('Amplitude [dB]') plt.xlabel('v (cycle/sample)') plt.show() # Plot Impulse Response for the AR filter num = [0.1] den = [1, -0.9] dlti = signal.dlti(num, den, dt=0.1) tout, yout = signal.dimpulse(dlti, n=20) toutMod = tout[1:] * 10 # print(toutMod) dataMod = yout[0] dataMod = dataMod[1:, :] # print(dataMod) # print(tout.shape) # print(yout[0]) fig = plt.figure() plt.title('Impulse Response For alpha = 0.9') markerline, stemlines, baseline = plt.stem(toutMod, dataMod, '-') plt.show() num = [0.5] den = [1, -0.5] dlti = signal.dlti(num, den, dt=0.1)
NumU = 2 * NumURows + NumUCols - 1 Time = np.arange(NumU) uu = rnd.randn(NumU, NumInputs) # u is the actual input tu, u, xu = sp.dlsim(USys, uu) w = rnd.randn(NumU, NumStates + NumOutputs) bigU = np.hstack((w, u)) tout, y, xout = sp.dlsim(P, bigU) plt.plot(tout, u) plt.plot(tout, y) # Identify matrices using the Standard N4SID algorithm AID, BID, CID, DID, CovID, S = ssid.N4SID(u.T, y.T, NumURows, NumUCols, 4) # For conistency with the Subspace ID literature, # we transpose the signals so that each input and output instance is a column vector # This is opposite from the lsim convention # Check the singular values plt.plot(S / S.sum()) # Check how the computed impulse resonse compares. plt.figure() NhSteps = 200 tout, hTrue = sp.dimpulse((A, B, C, D, dt), t=dt * np.arange(NhSteps)) tout, hID = sp.dimpulse((AID, BID, CID, DID, dt), t=dt * np.arange(NhSteps)) for i in range(NumOutputs): for j in range(NumInputs): plt.figure() plt.plot(tout, hTrue[j][:, i]) plt.plot(tout, hID[j][:, i])
def wyswietlSkokowa(funk): t_n,y_n=signal.dstep(funk, n=40) y_n=np.squeeze(y_n) plt.plot(t_n,y_n) plt.show() pprint.pprint(funk._as_ss()) pprint.pprint(funk._as_zpk()) fitted=dopasuj() wynikowe=stworzTeorie(fitted) print('omega_n = ',fitted[0],'dzeta = ',fitted[1],'k = ',fitted[2]) # wyswietlModelDane() funkcja=signal.dlti([fitted[0]*fitted[0]*fitted[2]], [1,2*fitted[0]*fitted[1], fitted[0]*fitted[0]], dt=0.005) #wyswietlSkokowa(funkcja) t_n,y_n=signal.dimpulse(funkcja, n=20) y_n=np.squeeze(y_n) Y_skok = np.fft.fft(y_n) freq_skok = np.fft.fftfreq(len(y_n), t_n[1] - t_n[0]) print(freq_skok) plt.figure() plt.plot( freq_skok, np.abs(Y_skok) ) plt.title('Amplitudowa') plt.ylabel('|S[n]|') plt.xlabel('n') plt.figure() plt.scatter(freq_skok, np.angle(Y_skok) ) plt.title('Fazowa') plt.ylabel('fi S[n]') plt.xlabel('n')
norm=colors.LogNorm(vmin=0.001, vmax=2), cmap=cm.Blues, rstride=1, cstride=1) ax.view_init(elev=54, azim=45) # make the panes transparent ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) plt.xlabel("Im(z)") plt.ylabel("Re(z)") plt.savefig("../fig/z_plane_%d.png" % indice) # Réponse impulsionnelle plt.figure() t, yout = sig.dimpulse(tf_temp, n=30) plt.stem(t, yout[0]) np.savetxt("../csv/ri_%d.txt" % indice, yout[0], delimiter=',') # Réponse frequentielle w, h = sig.dfreqresp(tf_temp, n=200) amp = abs(h) angles = np.unwrap(np.angle(h)) M = np.matrix([w, amp, angles]).T plt.figure() plt.plot(w, amp) plt.figure() plt.plot(w, angles) np.savetxt("../csv/rf_%d.txt" % indice, M, delimiter=',')
def impL1(arg1, n=10): """Impulse response evaluation for NTFs. Compute the impulse response from the comparator output to the comparator input for the given NTF. **Parameters:** arg1 : object The NTF, which may be represented as: * ZPK tuple, * num, den tuple, * A, B, C, D tuple, * ABCD matrix, * a scipy LTI object, * a sequence of the tuples of any of the above types (experimental). n : int is the (optional) number of time steps (default: 10), resulting in an impulse response with n+1 (default: 11) samples. This function is useful when verifying the realization of a NTF with a specified topology. **Returns:** y : ndarray The NTF impulse response .. note:: In the original implementation of impL1 in delsig, there is a bug: impL1 calls MATLAB's impulse with tfinal=n, which means that the function will return the impulse response evaluated on the times [0, 1, 2 ... n], ie n+1 points. We keep the same behavior here, but we state clearly that n is the number of time steps. """ if _is_num_den(arg1): num, den = arg1 p = np.roots(den) elif _is_zpk(arg1): z, p, _ = arg1 num = np.poly(z) den = np.poly(p) else: num, den = _get_num_den(arg1) p = np.roots(den) num = np.asarray(num) den = np.asarray(den) p = np.asarray(p) lf_den = padr(num, len(p)+1) lf_num = lf_den - den ts = np.arange(n + 1) # be coherent with the original toolbox all_lf = np.concatenate((lf_num, lf_den), axis=1) lf_num, lf_den = lf_num.squeeze(), lf_den.squeeze() if not np.allclose(np.imag(all_lf), np.zeros(all_lf.shape), atol=1e-9): # Complex loop filter lfr_den = np.real(convolve(lf_den, np.conj(lf_den))).squeeze() lfr_num = convolve(lf_num, np.conj(lf_den)).squeeze() lf_i = (np.real(lfr_num).tolist(), lfr_den.tolist(), 1) lf_q = (np.imag(lfr_num).tolist(), lfr_den.tolist(), 1) y = dimpulse(lf_i, t=ts)[1][0] + 1j*dimpulse(lf_q, t=ts)[1][0] y = y.squeeze() else: _, y = dimpulse((lf_num, lf_den, 1), t=ts) y = y[0].squeeze() return y
from scipy import signal import matplotlib.pyplot as plt butter = signal.dlti(*signal.butter(3, 0.5)) t, y = signal.dimpulse(butter, n=25) plt.step(t, np.squeeze(y)) plt.grid() plt.xlabel('n [samples]') plt.ylabel('Amplitude')