def test_realizeNTF(self): """Test function for realizeNTF()""" for f0 in self.f0s: for form in self.forms: for order in self.orders: if f0 != 0. and order % 2 == 1: # odd-order pass band modulator continue # Optimized zero placement print("Testing form: %s, order: %d, f0: %f, OSR %d" % \ (form, order, f0, self.osr)) ntf = ds.synthesizeNTF(order,self. osr, 2, self.Hinf, f0) a, g, b, c = ds.realizeNTF(ntf, form) print(ntf) print(a, g, b, c) print(self.res[f0][form][order]['a'], self.res[f0][form][order]['g'], self.res[f0][form][order]['b'], self.res[f0][form][order]['c']) self.assertTrue(np.allclose(a, self.res[f0][form][order]['a'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(g, self.res[f0][form][order]['g'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(b, self.res[f0][form][order]['b'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(c, self.res[f0][form][order]['c'], atol=1e-4, rtol=1e-3)) return
def test_logsmooth(self): """Test function for logsmooth()""" f0 = 1. / 8 OSR = 64 order = 8 N = 8192 H = synthesizeNTF(order, OSR, 1, 1.5, f0) # fB = int(np.ceil(N/(2. * OSR))) quadrature = False M = 1 f1, f2 = ds_f1f2(OSR, f0, quadrature) Amp = undbv(-3) f = .3 fin = np.round(((1 - f) / 2 * f1 + (f + 1) / 2 * f2) * N) t = np.arange(0, N).reshape((1, -1)) u = Amp * M * np.cos((2 * np.pi / N) * fin * t) v, _, _, _ = simulateDSM(u, H, M + 1) window = ds_hann(N) # NBW = 1.5/N spec0 = fft(v * window) / (M * N / 4) ### -1 is really important THIS IS NOT MATLAB!! fl, pl = logsmooth(spec0, fin - 1) fname = pkg_resources.resource_filename( __name__, "test_data/test_logsmooth.mat") data = scipy.io.loadmat(fname) self.assertTrue(np.allclose(fl, data['fl'], atol=1e-8, rtol=1e-5)) self.assertTrue(np.allclose(pl, data['pl'], atol=1e-8, rtol=1e-5))
def test_simulateSNR_2(self): """Test function for simulateSNR() 2/4""" # next test: f0 = 0 # Load test references fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp2.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1, )) snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1, )) ABCD_ref = scipy.io.loadmat(fname)['ABCD'].reshape((4, 5)) order = 3 osr = 256 nlev = 2 f0 = 0. Hinf = 1.25 form = 'CIFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) a1, g1, b1, c1 = ds.realizeNTF(ntf, form) a1_ref = [0.008863535715733, 0.093216950269955, 0.444473912607388] g1_ref = [9.035620546615189e-05] b1_ref = [0.008863535715733, 0.093216950269955, 0.444473912607388, 1.] c1_ref = [1., 1., 1.] self.assertTrue(np.allclose(a1, a1_ref, atol=1e-9, rtol=5e-5)) self.assertTrue(np.allclose(g1, g1_ref, atol=1e-9, rtol=5e-5)) self.assertTrue(np.allclose(b1, b1_ref, atol=1e-9, rtol=1e-4)) self.assertTrue(np.allclose(c1, c1_ref, atol=1e-9, rtol=2e-5)) ABCD = ds.stuffABCD(a1, g1, b1, c1, form) self.assertTrue(np.allclose(ABCD, ABCD_ref, atol=9e-5, rtol=1e-4)) snr, amp = ds.simulateSNR(ABCD, osr, None, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp, amp_ref, atol=1e-5, rtol=1e-5))
def test_mapABCD_1(self): """Test function for mapABCD() 1/2""" for f0 in self.f0s: for form in self.forms: for order in self.orders: if f0 != 0. and order % 2 == 1: # odd-order pass band modulator continue # Optimized zero placement print("Testing form: %s, order: %d, f0: %f" % \ (form, order, f0)) ntf = synthesizeNTF(order, self.osr, 2, self.Hinf, f0) a1, g1, b1, c1 = realizeNTF(ntf, form) # we check realize NTF too self.assertTrue(np.allclose(a1, self.res[f0][form][order]['a'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(g1, self.res[f0][form][order]['g'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(b1, self.res[f0][form][order]['b'], atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(c1, self.res[f0][form][order]['c'], atol=1e-4, rtol=1e-3)) ABCD = stuffABCD(a1, g1, b1, c1, form) a, g, b, c = mapABCD(ABCD, form) self.assertTrue(np.allclose(a1, a, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(g1, g, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(b1, b, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(c1, c, atol=1e-4, rtol=1e-3))
def test_simulateSNR_2(self): """Test function for simulateSNR() 2/4""" # next test: f0 = 0 # Load test references fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp2.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1,)) snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1,)) ABCD_ref = scipy.io.loadmat(fname)['ABCD'].reshape((4, 5)) order = 3 osr = 256 nlev = 2 f0 = 0. Hinf = 1.25 form = 'CIFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) a1, g1, b1, c1 = ds.realizeNTF(ntf, form) a1_ref = [0.008863535715733, 0.093216950269955, 0.444473912607388] g1_ref = [9.035620546615189e-05] b1_ref = [0.008863535715733, 0.093216950269955, 0.444473912607388, 1.] c1_ref = [1., 1., 1.] self.assertTrue(np.allclose(a1, a1_ref, atol=1e-9, rtol=5e-5)) self.assertTrue(np.allclose(g1, g1_ref, atol=1e-9, rtol=5e-5)) self.assertTrue(np.allclose(b1, b1_ref, atol=1e-9, rtol=1e-4)) self.assertTrue(np.allclose(c1, c1_ref, atol=1e-9, rtol=2e-5)) ABCD = ds.stuffABCD(a1, g1, b1, c1, form) self.assertTrue(np.allclose(ABCD, ABCD_ref, atol=9e-5, rtol=1e-4)) snr, amp = ds.simulateSNR(ABCD, osr, None, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp, amp_ref, atol=1e-5, rtol=1e-5))
def test_logsmooth(self): """Test function for logsmooth()""" f0 = 1./8 OSR = 64 order = 8 N = 8192 H = synthesizeNTF(order, OSR, 1, 1.5, f0) # fB = int(np.ceil(N/(2. * OSR))) quadrature = False M = 1 f1, f2 = ds_f1f2(OSR, f0, quadrature) Amp = undbv(-3) f = .3 fin = np.round(((1 - f)/2*f1 + (f + 1)/2 * f2) * N) t = np.arange(0, N).reshape((1, -1)) u = Amp * M * np.cos((2*np.pi/N)*fin*t) v, _, _, _ = simulateDSM(u, H, M + 1) window = ds_hann(N) # NBW = 1.5/N spec0 = fft(v * window) / (M*N/4) ### -1 is really important THIS IS NOT MATLAB!! fl, pl = logsmooth(spec0, fin - 1) fname = pkg_resources.resource_filename(__name__, "test_data/test_logsmooth.mat") data = scipy.io.loadmat(fname) self.assertTrue(np.allclose(fl, data['fl'], atol=1e-8, rtol=1e-5)) self.assertTrue(np.allclose(pl, data['pl'], atol=1e-8, rtol=1e-5))
def test_plotSpectrum(self): """Test function for plotSpectrum()""" f0 = 0 osr = 32 quadrature = False Hinf = 1.5 order = 3 ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0) f1, f2 = ds.ds_f1f2(osr, f0, quadrature) delta = 2 Amp = ds.undbv(-3) f = 0.3 N = 2**12 f1_bin = np.round(f1*N) f2_bin = np.round(f2*N) fin = np.round(((1 - f)/2*f1 + (f + 1)/2*f2) * N) t = np.arange(0, N) u = Amp*np.cos((2*np.pi/N)*fin*t) v, xn, xmax, y = ds.simulateDSM(u, ntf, 2) window = ds.ds_hann(N) NBW = 1.5/N spec0 = fft(v * window)/(N/4) freq = np.linspace(0, 0.5, N/2 + 1) # plotting plt.subplot(211) plt.plot(freq, ds.dbv(spec0[:N/2 + 1]), 'c', linewidth=1, label='$S$') plt.hold(True) spec_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16) plt.plot(freq, ds.dbp(spec_smoothed[:N/2 + 1]), 'b--', linewidth=2, label='$\\mathrm{circ\\_smooth}(S)$') ds.plotSpectrum(spec0, fin, 'r', linewidth=2, label='$\\mathrm{plotSpectrum}(S)$') Snn = np.abs(ds.evalTF(ntf, np.exp(2j*np.pi*freq)))**2 * 2/12*(delta)**2 plt.plot(freq, ds.dbp(Snn*NBW), 'm', linewidth=1.5, label='$\mathrm{from\\ NTF}$') plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right', verticalalignment='top') ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None) plt.ylabel('Spectrum [dB]') ax = plt.gca() ax.set_title('Smoothing and plotting for LOG and LIN axes') plt.legend(loc=4) plt.subplot(212) plt.plot(freq, ds.dbv(spec0[:N/2 + 1]), 'c', linewidth=1, label='$S$') plt.hold(True) ds.plotSpectrum(spec0, fin, '--r', linewidth=2, label='$\\mathrm{plotSpectrum}(S)$') plt.plot(freq, ds.dbp(spec_smoothed[:N/2 + 1]), 'b', linewidth=2, label='$\\mathrm{circ\\_smooth}(S)$') plt.plot(freq, ds.dbp(Snn*NBW), 'm', linewidth=1.5, label='$\mathrm{from\\ NTF}$') plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right', verticalalignment='top') ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None) ax = plt.gca() ax.set_xscale('linear') plt.ylabel('Spectrum [dB]') plt.xlabel('Normalized frequency ($f_s \\rightarrow 1$)') plt.legend(loc=4)
def test_PlotExampleSpectrum(self): """Test function for PlotExampleSpectrum()""" order = 3 osr = 32 f0 = 0. Hinf = 1.5 ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0) ret = ds.PlotExampleSpectrum(ntf, M=1, osr=osr, f0=f0) self.assertIsNone(ret)
def test_synthesizeNTF_5(self): """Test function for synthesizeNTF() 5/15""" z, p, k = synthesizeNTF(opt=2) zref = [1.0000 + 0.0000j, 0.9993 + 0.0380j, 0.9993 - 0.0380j] pref = [0.7652 - 0.2795j, 0.7652 + 0.2795j, 0.6692 + 0.0000j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_PlotExampleSpectrum_NTF(self): """Test function for PlotExampleSpectrum()""" order = 3 osr = 32 f0 = 0. Hinf = 1.5 ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0) ret = ds.PlotExampleSpectrum(ntf, M=1, osr=osr, f0=f0) self.assertIsNone(ret)
def test_simulateSNR_1(self): """Test function for simulateSNR() 1/4""" # first test: f0 = 0 # Load test references fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1, )) snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1, )) amp_user_ref = scipy.io.loadmat(fname)['amp_user'].reshape((-1, )) snr_user_ref = scipy.io.loadmat(fname)['snr_user'].reshape((-1, )) order = 4 osr = 256 nlev = 2 f0 = 0.22 Hinf = 1.25 form = 'CRFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) a1, g1, b1, c1 = ds.realizeNTF(ntf, form) ABCD = ds.stuffABCD(a1, g1, b1, c1, form) ABCD_ref = np.array([[1., -1.6252, 0, 0, -0.0789, 0.0789], [1., -0.6252, 0, 0, -0.0756, 0.0756], [0, 1., 1., -1.6252, -0.2758, 0.2758], [0, 1., 1., -0.6252, 0.0843, -0.0843], [0, 0, 0, 1., 1., 0]]) self.assertTrue(np.allclose(ABCD, ABCD_ref, atol=9e-5, rtol=1e-4)) # bonus test, mapABCD - realizeNTF - stuffABCD a2, g2, b2, c2 = ds.mapABCD(ABCD, form) self.assertTrue(np.allclose(a1, a2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(g1, g2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(b1, b2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(c1, c2, atol=1e-5, rtol=1e-5)) # We do three tests: # SNR from ABCD matrix # SNR from NTF # SNR from LTI obj with user specified amplitudes snr, amp = ds.simulateSNR(ABCD, osr, None, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1, rtol=5e-2)) self.assertTrue(np.allclose(amp, amp_ref, atol=5e-1, rtol=1e-2)) snr2, amp2 = ds.simulateSNR(ntf, osr, None, f0, nlev) self.assertTrue(np.allclose(snr2, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp2, amp_ref, atol=1e-5, rtol=1e-5)) amp_user = np.linspace(-100, 0, 200)[::10] snr_user, amp_user = ds.simulateSNR(lti(*ntf), osr=osr, amp=amp_user, f0=f0, nlev=nlev) self.assertTrue( np.allclose(snr_user, snr_user_ref[::10], atol=1e-5, rtol=1e-5)) self.assertTrue( np.allclose(amp_user, amp_user_ref[::10], atol=1e-5, rtol=1e-5))
def test_synthesizeNTF_3(self): """Test function for synthesizeNTF() 3/15""" # repeat with zeros optimization z, p, k = synthesizeNTF(opt=1) zref = [1.0000 + 0.0000j, 0.9993 + 0.0380j, 0.9993 - 0.0380j] pref = [0.7652 - 0.2795j, 0.7652 + 0.2795j, 0.6692 + 0.0000j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_synthesizeNTF_6(self): """Test function for synthesizeNTF() 6/15""" z, p, k = synthesizeNTF(order=4, osr=32, opt=2, H_inf=1.3, f0=.33) zref = [-0.4818 + 0.8763j, -0.4818 - 0.8763j, -0.4818 + 0.8763j, -0.4818 - 0.8763j] pref = [-0.5125 - 0.7018j, -0.5125 + 0.7018j, -0.3233 - 0.8240j, -0.3233 + 0.8240j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_synthesizeNTF_4(self): """Test function for synthesizeNTF() 4/15""" z, p, k = synthesizeNTF(order=4, osr=32, opt=1, H_inf=1.3, f0=.33) zref = [-0.4567 + 0.8896j, -0.4567 - 0.8896j, -0.5064 + 0.8623j, -0.5064 - 0.8623j] pref = [-0.5125 - 0.7014j, -0.5125 + 0.7014j, -0.3230 - 0.8239j, -0.3230 + 0.8239j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-4)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_synthesizeNTF_1(self): """Test function for synthesizeNTF() 1/15""" # synthesizeNTF should have as default values: # order=3, osr=64, opt=0, H_inf=1.5, f0=0.0 z, p, k = synthesizeNTF() zref = [1., 1., 1.] pref = [.6694, .7654 + .2793j, .7654 - .2793j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-4)) self.assertTrue( np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-4)) self.assertTrue( np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_synthesizeNTF_10(self): """Test function for synthesizeNTF() 10/15""" # Up next: odd order lowpass w zero at center band test z, p, k = synthesizeNTF(order=5, osr=32, opt=4, H_inf=1.3, f0=0.0) zref = [1.0000 + 0.0000j, 0.9986 + 0.0531j, 0.9986 - 0.0531j, 0.9960 + 0.0892j, 0.9960 - 0.0892j] pref = [0.8718 - 0.0840j, 0.8718 + 0.0840j, 0.9390 - 0.1475j, 0.9390 + 0.1475j, 0.8491 + 0.0000j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_simulateSNR_1(self): """Test function for simulateSNR() 1/4""" # first test: f0 = 0 # Load test references fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1,)) snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1,)) amp_user_ref = scipy.io.loadmat(fname)['amp_user'].reshape((-1,)) snr_user_ref = scipy.io.loadmat(fname)['snr_user'].reshape((-1,)) order = 4 osr = 256 nlev = 2 f0 = 0.22 Hinf = 1.25 form = 'CRFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) a1, g1, b1, c1 = ds.realizeNTF(ntf, form) ABCD = ds.stuffABCD(a1, g1, b1, c1, form) ABCD_ref = np.array([[1., -1.6252, 0, 0, -0.0789, 0.0789], [1., -0.6252, 0, 0, -0.0756, 0.0756], [0, 1., 1., -1.6252, -0.2758, 0.2758], [0, 1., 1., -0.6252, 0.0843, -0.0843], [0, 0, 0, 1., 1., 0]]) self.assertTrue(np.allclose(ABCD, ABCD_ref, atol=9e-5, rtol=1e-4)) # bonus test, mapABCD - realizeNTF - stuffABCD a2, g2, b2, c2 = ds.mapABCD(ABCD, form) self.assertTrue(np.allclose(a1, a2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(g1, g2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(b1, b2, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(c1, c2, atol=1e-5, rtol=1e-5)) # We do three tests: # SNR from ABCD matrix # SNR from NTF # SNR from LTI obj with user specified amplitudes snr, amp = ds.simulateSNR(ABCD, osr, None, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1, rtol=5e-2)) self.assertTrue(np.allclose(amp, amp_ref, atol=5e-1, rtol=1e-2)) snr2, amp2 = ds.simulateSNR(ntf, osr, None, f0, nlev) self.assertTrue(np.allclose(snr2, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp2, amp_ref, atol=1e-5, rtol=1e-5)) amp_user = np.linspace(-100, 0, 200)[::10] snr_user, amp_user = ds.simulateSNR(lti(*ntf), osr=osr, amp=amp_user, f0=f0, nlev=nlev) self.assertTrue(np.allclose(snr_user, snr_user_ref[::10], atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp_user, amp_user_ref[::10], atol=1e-5, rtol=1e-5))
def setUp(self): fname = pkg_resources.resource_filename(__name__, "test_data/test_simulateDSM.mat") self.v_ref = scipy.io.loadmat(fname)['v'] self.xn_ref = scipy.io.loadmat(fname)['xn'] self.xmax_ref = scipy.io.loadmat(fname)['xmax'] self.y_ref = scipy.io.loadmat(fname)['y'] OSR = 32 self.H = synthesizeNTF(5, OSR, 1) N = 8192 f = 85 self.u = 0.5*np.sin(2*np.pi*f/N*np.arange(N)) a, g, b, c = realizeNTF(self.H, 'CRFB') self.ABCD = stuffABCD(a, g, b, c, form='CRFB')
def test_synthesizeNTF_11(self): """Test function for synthesizeNTF() 11/15""" # zeros passed explicitly opt = [1.0000 + 0.0000j, 0.9986 + 0.06j, 0.9986 - 0.06j, 0.9960 + 0.0892j, 0.9960 - 0.0892j] z, p, k = synthesizeNTF(order=5, osr=32, opt=opt, H_inf=1.3, f0=0.0) zref = [1.0000 + 0.0000j, 0.9986 + 0.06j, 0.9986 - 0.06j, 0.9960 + 0.0892j, 0.9960 - 0.0892j] pref = [0.8718 - 0.0840j, 0.8718 + 0.0840j, 0.9390 - 0.1475j, 0.9390 + 0.1475j, 0.8491 + 0.0000j] kref = 1. self.assertTrue(np.allclose(cpx(z), cpx(zref), atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(cpx(p), cpx(pref), atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(k, kref, atol=1e-4, rtol=1e-4))
def test_bilogplot(self): """Test function for bilogplot()""" f0 = 1./8 OSR = 64 order = 8 N = 8192 H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0) fB = int(np.ceil(N/(2. * OSR))) ftest = int(np.round(f0*N + 1./3 * fB)) u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N)) v, xn, xmax, y = ds.simulateDSM(u, H) spec = np.fft.fft(v*ds.ds_hann(N))/(N/4) X = spec[:N/2 + 1] plt.figure() # graphical function: we check it doesn't fail ds.bilogplot(X, f0*N, ftest, (.03, .3, .3), (-140, 0, 10, 20))
def test_pretty_lti(): """Test function for pretty_lti()""" H = synthesizeNTF(5, 32, 1) tv = pretty_lti(H) res = ' (z^2 - 1.992z + 0.9999) (z^2 - 1.997z + 1) (z - 1) \n' + \ '-------------------------------------------------------------\n' + \ ' (z^2 - 1.613z + 0.665) (z^2 - 1.796z + 0.8549) (z - 0.7778) ' assert res == tv assert int(pretty_lti(([], [], 2))) == 2 assert pretty_lti([[1], [], 2]) == '2 (z - 1)' assert pretty_lti([[], [.22222222], 2]) == \ ' 2 \n--------------\n (z - 0.2222) ' assert pretty_lti(((0, 0, 1), (1, 2-1j, 2+1j, 2-1j, 2+1j), 5)) == \ ' z^2 (z - 1) \n' + \ '5 --------------------------\n' + \ ' (z^2 - 4z + 5)^2 (z - 1) '
def test_bilogplot(self): """Test function for bilogplot()""" f0 = 1. / 8 OSR = 64 order = 8 N = 8192 H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0) fB = int(np.ceil(N / (2. * OSR))) ftest = int(np.round(f0 * N + 1. / 3 * fB)) u = 0.5 * np.sin(2 * np.pi * ftest / N * np.arange(N)) v, xn, xmax, y = ds.simulateDSM(u, H) spec = np.fft.fft(v * ds.ds_hann(N)) / (N / 4) X = spec[:N / 2 + 1] plt.figure() # graphical function: we check it doesn't fail ds.bilogplot(X, f0 * N, ftest, (.03, .3, .3), (-140, 0, 10, 20))
def setUp(self): fname = pkg_resources.resource_filename( __name__, "test_data/test_bplogsmooth.mat") self.data = scipy.io.loadmat(fname) f0 = 1./8 OSR = 64 order = 8 N = 8192 H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0) fB = int(np.ceil(N/(2. * OSR))) ftest = int(mround(f0*N + 1./3*fB)) u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N)) v, xn, xmax, y = ds.simulateDSM(u, H) spec = np.fft.fft(v*ds.ds_hann(N))/(N/4) X = spec[:N/2 + 1] self.f, self.p = ds.bplogsmooth(X, ftest, f0)
def setUp(self): fname = pkg_resources.resource_filename( __name__, "test_data/test_bplogsmooth.mat") self.data = scipy.io.loadmat(fname) f0 = 1./8 OSR = 64 order = 8 N = 8192 H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0) fB = int(np.ceil(N/(2. * OSR))) ftest = int(mround(f0*N + 1./3*fB)) u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N)) v, xn, xmax, y = ds.simulateDSM(u, H) spec = np.fft.fft(v*ds.ds_hann(N))/(N/4) X = spec[:N//2 + 1] self.f, self.p = ds.bplogsmooth(X, ftest, f0)
def __init__(self, input: FixedPointValue, osr=32, order=4, n_lev=2): self.input = input self.fmt = input.fmt self.h = synthesizeNTF(order, osr, 1) a, g, b, c = realizeNTF(self.h, form='CIFB') abcd = stuffABCD(a, g, b, c) abcd_scaled, umax, s = scaleABCD(abcd, n_lev) self.parameters = mapABCD(abcd_scaled) print(umax) self.order = order self.osr = osr assert n_lev > 1 self.n_lev = n_lev self.quantization_values = [i * 2 - (n_lev / 2) for i in range(n_lev)] self.output = Signal(range(0, len(self.quantization_values)))
def setUp(self): order = 8 osr = 32 self.nlev = 2 self.f0 = 0.125 Hinf = 1.5 form = 'CRFB' # Optimized zero placement ntf = ds.synthesizeNTF(order, osr, 2, Hinf, self.f0) a, g, b, c = ds.realizeNTF(ntf, form) # we pass b = b[0] # if you use a single feed-in for the input, b may be scalar too ABCD = ds.stuffABCD(a, g, b[0], c, form) # now we correct b for the assert b = np.concatenate(( # Use a single feed-in for the input np.atleast_1d(b[0]), np.zeros((max(b.shape) - 1,)) )) self.ABCD0 = ABCD.copy() # References self.Sdiag_ref = np.array([71.9580, 51.9359, 8.2133, 6.5398, 1.9446, 1.2070, 0.4223, 0.3040]) self.umax_ref = 0.8667 ABCD_ref1 = np.array([[1., -0.7320, 0, 0, 0, 0], [0.7218, 0.4717, 0, 0, 0, 0], [0, 0.1581, 1., -0.7357, 0, 0], [0, 0.1259, 0.7962, 0.4142, 0, 0], [0, 0, 0, 0.2973, 1., -0.9437], [0, 0, 0, 0.1846, 0.6207, 0.4142], [0, 0, 0, 0, 0, 0.3499], [0, 0, 0, 0, 0, 0.2518], [0, 0, 0, 0, 0, 0]]) ABCD_ref2 = np.array([[0, 0, 0.0858, -0.0858], [0, 0, 0.0619, 0.0428], [0, 0, 0, 0.0642], [0, 0, 0, 0.1835], [0, 0, 0, 0.2447], [0, 0, 0, 0.0581], [1., -0.8971, 0, -0.0076], [0.7197, 0.3543, 0, -0.1746], [0, 3.29, 0, 0]]) self.ABCD_ref = np.hstack((ABCD_ref1, ABCD_ref2))
def test_predictSNR_1(self): """Test function for predictSNR() 1/3""" snr_ref = [-32.3447, -22.3447, -12.3447, -2.3447, 7.6553, 17.6553, 27.6553, 37.6552, 47.6545, 57.6475, 67.5768, 72.4043, 76.8266, 77.5913, 78.2773, 78.8451, 79.2116, 79.0974, -np.Inf, -np.Inf, -np.Inf, -np.Inf, -np.Inf] amp_ref = [-120., -110., -100., -90., -80., -70., -60., -50., -40., -30, -20, -15, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0] k0_ref = [1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6288, 1.6283, 1.6227, 1.6088, 1.5596, 1.5383, 1.5088, 1.4663, 1.4003, 1.2747, 0., 0., 0., 0., 0.] k1_ref = [1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6289, 1.6287, 1.6274, 1.6142, 1.5819, 1.4752, 1.4326, 1.3768, 1.3025, 1.1995, 1.0387, 0.3706, 0., 0., 0., 0.] sigma_e2_ref = [0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3631, 0.3607, 0.3591, 0.3566, 0.3525, 0.3459, 0.3352, 0.3178, 0., 0., 0., 0.] order = 5 osr = 32 f0 = 0 Hinf = 1.5 ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) snr_pred, amp_pred, k0, k1, sigma_e2 = ds.predictSNR(ntf, osr, None, f0) # Delete garbage data for check in (np.isinf, np.isnan): i = check(snr_ref) snr_ref = np.delete(snr_ref, np.where(i)) amp_ref = np.delete(amp_ref, np.where(i)) i = check(snr_pred) snr_pred = np.delete(snr_pred, np.where(i)) amp_pred = np.delete(amp_pred, np.where(i)) self.assertTrue(np.allclose(snr_pred, snr_ref, atol=1e-2, rtol=1e-3)) self.assertTrue(np.allclose(amp_pred, amp_ref, atol=1e-2, rtol=5e-4)) self.assertTrue(np.allclose(k0, k0_ref, atol=1e-3, rtol=1e-2)) self.assertTrue(np.allclose(k1, k1_ref, atol=1e-3, rtol=50e-2)) self.assertTrue(np.allclose(sigma_e2, sigma_e2_ref, atol=1e-3, rtol=1e-2))
def test_simulateSNR_3(self): """Test function for simulateSNR() 3/4""" # next test: amp is a scalar fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp2.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1,))[0] snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1,))[0] ABCD = scipy.io.loadmat(fname)['ABCD'].reshape((4, 5)) order = 3 osr = 256 nlev = 2 f0 = 0. Hinf = 1.25 form = 'CIFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) snr, amp = ds.simulateSNR(ABCD, osr, amp_ref, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp, amp_ref, atol=1e-5, rtol=1e-5))
def setUp(self): fname = pkg_resources.resource_filename( __name__, "test_data/test_simulateDSM.mat") self.v_ref = scipy.io.loadmat(fname)['v'] self.xn_ref = scipy.io.loadmat(fname)['xn'] self.xmax_ref = scipy.io.loadmat(fname)['xmax'] self.y_ref = scipy.io.loadmat(fname)['y'] self.u_ref = scipy.io.loadmat(fname)['u'] self.ABCD_ref = scipy.io.loadmat(fname)['ABCD'] self.zeros = cplxpair(scipy.io.loadmat(fname)['zeros']) self.poles = cplxpair(scipy.io.loadmat(fname)['poles']) self.v_ref = self.v_ref.reshape(-1) self.y_ref = self.y_ref.reshape(-1) OSR = 32 self.H = synthesizeNTF(5, OSR, 10) N = 8192 f = 85 self.u = 0.5 * np.sin(2 * np.pi * f / N * np.arange(N)) a, g, b, c = realizeNTF(self.H, 'CRFB') self.ABCD = stuffABCD(a, g, b, c, form='CRFB')
def test_simulateSNR_3(self): """Test function for simulateSNR() 3/4""" # next test: amp is a scalar fname = pkg_resources.resource_filename(__name__, "test_data/test_snr_amp2.mat") amp_ref = scipy.io.loadmat(fname)['amp'].reshape((-1, ))[0] snr_ref = scipy.io.loadmat(fname)['snr'].reshape((-1, ))[0] ABCD = scipy.io.loadmat(fname)['ABCD'].reshape((4, 5)) order = 3 osr = 256 nlev = 2 f0 = 0. Hinf = 1.25 form = 'CIFB' ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) snr, amp = ds.simulateSNR(ABCD, osr, amp_ref, f0, nlev) self.assertTrue(np.allclose(snr, snr_ref, atol=1e-5, rtol=1e-5)) self.assertTrue(np.allclose(amp, amp_ref, atol=1e-5, rtol=1e-5))
def test_realizeNTF(self): """Test function for realizeNTF()""" for f0 in self.f0s: for form in self.forms: for order in self.orders: if f0 != 0. and order % 2 == 1: # odd-order pass band modulator continue # Optimized zero placement print("Testing form: %s, order: %d, f0: %f, OSR %d" % \ (form, order, f0, self.osr)) ntf = ds.synthesizeNTF(order, self.osr, 2, self.Hinf, f0) a, g, b, c = ds.realizeNTF(ntf, form) print(ntf) print(a, g, b, c) print(self.res[f0][form][order]['a'], self.res[f0][form][order]['g'], self.res[f0][form][order]['b'], self.res[f0][form][order]['c']) self.assertTrue( np.allclose(a, self.res[f0][form][order]['a'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(g, self.res[f0][form][order]['g'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(b, self.res[f0][form][order]['b'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(c, self.res[f0][form][order]['c'], atol=1e-4, rtol=1e-3)) return
def test_mapABCD_1(self): """Test function for mapABCD() 1/2""" for f0 in self.f0s: for form in self.forms: for order in self.orders: if f0 != 0. and order % 2 == 1: # odd-order pass band modulator continue # Optimized zero placement print("Testing form: %s, order: %d, f0: %f" % \ (form, order, f0)) ntf = synthesizeNTF(order, self.osr, 2, self.Hinf, f0) a1, g1, b1, c1 = realizeNTF(ntf, form) # we check realize NTF too self.assertTrue( np.allclose(a1, self.res[f0][form][order]['a'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(g1, self.res[f0][form][order]['g'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(b1, self.res[f0][form][order]['b'], atol=1e-4, rtol=1e-3)) self.assertTrue( np.allclose(c1, self.res[f0][form][order]['c'], atol=1e-4, rtol=1e-3)) ABCD = stuffABCD(a1, g1, b1, c1, form) a, g, b, c = mapABCD(ABCD, form) self.assertTrue(np.allclose(a1, a, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(g1, g, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(b1, b, atol=1e-4, rtol=1e-3)) self.assertTrue(np.allclose(c1, c, atol=1e-4, rtol=1e-3))
def setUp(self): order = 8 osr = 32 self.nlev = 2 self.f0 = 0.125 Hinf = 1.5 form = 'CRFB' # Optimized zero placement ntf = ds.synthesizeNTF(order, osr, 2, Hinf, self.f0) a, g, b, c = ds.realizeNTF(ntf, form) # we pass b = b[0] # if you use a single feed-in for the input, b may be scalar too ABCD = ds.stuffABCD(a, g, b[0], c, form) # now we correct b for the assert # Use a single feed-in for the input b = np.concatenate((np.atleast_1d(b[0]), np.zeros( (max(b.shape) - 1, )))) self.ABCD0 = ABCD.copy() # References self.Sdiag_ref = np.array( [71.9580, 51.9359, 8.2133, 6.5398, 1.9446, 1.2070, 0.4223, 0.3040]) self.umax_ref = 0.8667 ABCD_ref1 = np.array([[1., -0.7320, 0, 0, 0, 0], [0.7218, 0.4717, 0, 0, 0, 0], [0, 0.1581, 1., -0.7357, 0, 0], [0, 0.1259, 0.7962, 0.4142, 0, 0], [0, 0, 0, 0.2973, 1., -0.9437], [0, 0, 0, 0.1846, 0.6207, 0.4142], [0, 0, 0, 0, 0, 0.3499], [0, 0, 0, 0, 0, 0.2518], [0, 0, 0, 0, 0, 0]]) ABCD_ref2 = np.array([[0, 0, 0.0858, -0.0858], [0, 0, 0.0619, 0.0428], [0, 0, 0, 0.0642], [0, 0, 0, 0.1835], [0, 0, 0, 0.2447], [0, 0, 0, 0.0581], [1., -0.8971, 0, -0.0076], [0.7197, 0.3543, 0, -0.1746], [0, 3.29, 0, 0]]) self.ABCD_ref = np.hstack((ABCD_ref1, ABCD_ref2))
import pylab as plt from deltasigma import synthesizeNTF, plotPZ order = 5 osr = 32 f0 = 0. Hinf = 1.5 ntf = synthesizeNTF(order, osr, 2, Hinf, f0) plt.figure(figsize=(8, 6)) plotPZ(ntf, color=('r', 'b'), showlist=True) plt.title("NTF singularities") plt.show()
def test_plotSpectrum(self): """Test function for plotSpectrum()""" f0 = 0 osr = 32 quadrature = False Hinf = 1.5 order = 3 ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0) f1, f2 = ds.ds_f1f2(osr, f0, quadrature) delta = 2 Amp = ds.undbv(-3) f = 0.3 N = 2**12 f1_bin = np.round(f1 * N) f2_bin = np.round(f2 * N) fin = np.round(((1 - f) / 2 * f1 + (f + 1) / 2 * f2) * N) t = np.arange(0, N) u = Amp * np.cos((2 * np.pi / N) * fin * t) v, xn, xmax, y = ds.simulateDSM(u, ntf, 2) window = ds.ds_hann(N) NBW = 1.5 / N spec0 = fft(v * window) / (N / 4) freq = np.linspace(0, 0.5, N // 2 + 1) # plotting plt.subplot(211) plt.plot(freq, ds.dbv(spec0[:N // 2 + 1]), 'c', linewidth=1, label='$S$') #plt.hold(True) spec_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16) plt.plot(freq, ds.dbp(spec_smoothed[:N // 2 + 1]), 'b--', linewidth=2, label='$\\mathrm{circ\\_smooth}(S)$') ds.plotSpectrum(spec0, fin, 'r', linewidth=2, label='$\\mathrm{plotSpectrum}(S)$') Snn = np.abs(ds.evalTF(ntf, np.exp( 2j * np.pi * freq)))**2 * 2 / 12 * (delta)**2 plt.plot(freq, ds.dbp(Snn * NBW), 'm', linewidth=1.5, label='$\\mathrm{from\\ NTF}$') plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right', verticalalignment='top') ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None) plt.ylabel('Spectrum [dB]') ax = plt.gca() ax.set_title('Smoothing and plotting for LOG and LIN axes') plt.legend(loc=4) plt.subplot(212) plt.plot(freq, ds.dbv(spec0[:N // 2 + 1]), 'c', linewidth=1, label='$S$') #plt.hold(True) ds.plotSpectrum(spec0, fin, '--r', linewidth=2, label='$\\mathrm{plotSpectrum}(S)$') plt.plot(freq, ds.dbp(spec_smoothed[:N // 2 + 1]), 'b', linewidth=2, label='$\\mathrm{circ\\_smooth}(S)$') plt.plot(freq, ds.dbp(Snn * NBW), 'm', linewidth=1.5, label='$\\mathrm{from\\ NTF}$') plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right', verticalalignment='top') ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None) ax = plt.gca() ax.set_xscale('linear') plt.ylabel('Spectrum [dB]') plt.xlabel('Normalized frequency ($f_s \\rightarrow 1$)') plt.legend(loc=4)
def fixp(self, y, scaling='mult'): """ Return fixed-point integer or fractional representation for `y` (scalar or array-like) with the same shape as `y`. Saturation / two's complement wrapping happens outside the range +/- MSB, requantization (round, floor, fix, ...) is applied on the ratio `y / LSB`. Parameters ---------- y: scalar or array-like object input value (floating point format) to be quantized scaling: String Determine the scaling before and after quantizing / saturation *'mult'* float in, int out: `y` is multiplied by `self.scale` *before* quantizing / saturating **'div'**: int in, float out: `y` is divided by `self.scale` *after* quantizing / saturating. **'multdiv'**: float in, float out (default): both of the above For all other settings, `y` is transformed unscaled. Returns ------- float scalar or ndarray with the same shape as `y`, in the range `-2*self.MSB` ... `2*self.MSB-self.LSB` Examples -------- >>> q_obj_a = {'WI':1, 'WF':6, 'ovfl':'sat', 'quant':'round'} >>> myQa = Fixed(q_obj_a) # instantiate fixed-point object myQa >>> myQa.resetN() # reset overflow counter >>> a = np.arange(0,5, 0.05) # create input signal >>> aq = myQa.fixed(a) # quantize input signal >>> plt.plot(a, aq) # plot quantized vs. original signal >>> print(myQa.N_over, "overflows!") # print number of overflows >>> # Convert output to same format as input: >>> b = np.arange(200, dtype = np.int16) >>> btype = np.result_type(b) >>> # MSB = 2**7, LSB = 2**(-2): >>> q_obj_b = {'WI':7, 'WF':2, 'ovfl':'wrap', 'quant':'round'} >>> myQb = Fixed(q_obj_b) # instantiate fixed-point object myQb >>> bq = myQb.fixed(b) >>> bq = bq.astype(btype) # restore original variable type """ #====================================================================== # (1) : INITIALIZATION # Convert input argument into proper floating point scalars / # arrays and initialize flags #====================================================================== scaling = scaling.lower() if np.shape(y): # Input is an array: # Create empty arrays for result and overflows with same shape as y # for speedup, test for invalid types SCALAR = False y = np.asarray(y) # convert lists / tuples / ... to numpy arrays yq = np.zeros(y.shape) over_pos = over_neg = np.zeros(y.shape, dtype=bool) self.ovr_flag = np.zeros(y.shape, dtype=int) if np.issubdtype(y.dtype, np.number): # numpy number type self.N += y.size elif y.dtype.kind in {'U', 'S'}: # string or unicode try: y = y.astype(np.float64) # try to convert to float self.N += y.size except (TypeError, ValueError): try: np.char.replace(y, ' ', '') # remove all whitespace y = y.astype(complex) # try to convert to complex self.N += y.size * 2 except (TypeError, ValueError ) as e: # try converting elements recursively y = np.asarray( list( map( lambda y_scalar: self.fixp( y_scalar, scaling=scaling), y))) # was: list() self.N += y.size else: logger.error("Argument '{0}' is of type '{1}',\n" "cannot convert to float.".format(y, y.dtype)) y = np.zeros(y.shape) else: # Input is a scalar SCALAR = True # get rid of errors that have occurred upstream if y is None or str(y) == "": y = 0 # If y is not a number, remove whitespace and try to convert to # to float and or to complex format: elif not np.issubdtype(type(y), np.number): y = qstr(y) y = y.replace(' ', '') # remove all whitespace try: y = float(y) except (TypeError, ValueError): try: y = complex(y) except (TypeError, ValueError) as e: logger.error("Argument '{0}' yields \n {1}".format( y, e)) y = 0.0 over_pos = over_neg = yq = 0 self.ovr_flag = 0 self.N += 1 # convert pseudo-complex (imag = 0) and complex values to real y = np.real_if_close(y) if np.iscomplexobj(y): logger.warning( "Casting complex values to real before quantization!") # quantizing complex objects is not supported yet y = y.real y_in = y # y before scaling / quantizing #====================================================================== # (2) : INPUT SCALING # Multiply by `scale` factor before requantization and saturation # when `scaling=='mult'`or 'multdiv' #====================================================================== if scaling in {'mult', 'multdiv'}: y = y * self.scale #====================================================================== # (3) : QUANTIZATION # Divide by LSB to obtain an intermediate format where the # quantization step size = 1. # Next, apply selected quantization method to convert # floating point inputs to "fixpoint integers". # Finally, multiply by LSB to restore original scale. #===================================================================== y = y / self.LSB if self.quant == 'floor': yq = np.floor(y) # largest integer i, such that i <= x (= binary truncation) elif self.quant == 'round': yq = np.round(y) # rounding, also = binary rounding elif self.quant == 'fix': yq = np.fix(y) # round to nearest integer towards zero ("Betragsschneiden") elif self.quant == 'ceil': yq = np.ceil(y) # smallest integer i, such that i >= x elif self.quant == 'rint': yq = np.rint(y) # round towards nearest int elif self.quant == 'dsm': if DS: # Synthesize DSM loop filter, # TODO: parameters should be adjustable via quantizer dict H = synthesizeNTF(order=3, osr=64, opt=1) # Calculate DSM stream and shift/scale it from -1 ... +1 to # 0 ... 1 sequence yq = (simulateDSM(y * self.LSB, H)[0] + 1) / (2 * self.LSB) # returns four ndarrays: # v: quantizer output (-1 or 1) # xn: modulator states. # xmax: maximum value that each state reached during simulation # y: The quantizer input (ie the modulator output). else: raise Exception( '"deltasigma" Toolbox not found.\n' 'Try installing it with "pip install deltasigma".') elif self.quant == 'none': yq = y # return unquantized value else: raise Exception('Unknown Requantization type "%s"!' % (self.quant)) yq = yq * self.LSB # logger.debug("y_in={0} | y={1} | yq={2}".format(y_in, y, yq)) #====================================================================== # (4) : Handle Overflow / saturation w.r.t. to the MSB, returning a # result in the range MIN = -2*MSB ... + 2*MSB-LSB = MAX #===================================================================== if self.ovfl == 'none': pass else: # Bool. vectors with '1' for every neg./pos overflow: over_neg = (yq < self.MIN) over_pos = (yq > self.MAX) # create flag / array of flags for pos. / neg. overflows self.ovr_flag = over_pos.astype(int) - over_neg.astype(int) # No. of pos. / neg. / all overflows occured since last reset: self.N_over_neg += np.sum(over_neg) self.N_over_pos += np.sum(over_pos) self.N_over = self.N_over_neg + self.N_over_pos # Replace overflows with Min/Max-Values (saturation): if self.ovfl == 'sat': yq = np.where(over_pos, self.MAX, yq) # (cond, true, false) yq = np.where(over_neg, self.MIN, yq) # Replace overflows by two's complement wraparound (wrap) elif self.ovfl == 'wrap': yq = np.where( over_pos | over_neg, yq - 4. * self.MSB * np.fix( (np.sign(yq) * 2 * self.MSB + yq) / (4 * self.MSB)), yq) else: raise Exception('Unknown overflow type "%s"!' % (self.ovfl)) return None #====================================================================== # (5) : OUTPUT SCALING # Divide result by `scale` factor when `scaling=='div'`or 'multdiv' # to obtain correct scaling for floats # - frmt2float() always returns float # - input_coeffs when quantizing the coefficients # float2frmt passes on the scaling argument #====================================================================== if scaling in {'div', 'multdiv'}: yq = yq / self.scale if SCALAR and isinstance(yq, np.ndarray): yq = yq.item() # convert singleton array to scalar return yq
def test_predictSNR_2(self): """Test function for predictSNR() 2/2""" snr_ref = [-54.7270, -53.5149, -52.3028, -51.0907, -49.8786, -48.6664, -47.4543, -46.2422, -45.0301, -43.8180, -42.6058, -41.3937, -40.1816, -38.9695, -37.7574, -36.5452, -35.3331, -34.1210, -32.9089, -31.6967, -30.4846, -29.2725, -28.0604, -26.8483, -25.6361, -24.4240, -23.2119, -21.9998, -20.7877, -19.5755, -18.3634, -17.1513, -15.9392, -14.7270, -13.5149, -12.3028, -11.0907, -9.8786, -8.6664, -7.4543, -6.2422, -5.0301, -3.8180, -2.6058, -1.3937, -0.1816, 1.0305, 2.2426, +3.4548, 4.6669, 5.8790, 7.0911, 8.3032, 9.5154, +10.7275, 11.9396, 13.1517, 14.3638, 15.5759, 16.7881, +18.0002, 19.2123, 20.4244, 21.6365, 22.8485, 24.0606, +25.2727, 26.4847, 27.6967, 28.9087, 30.1206, 31.3324, +32.5442, 33.7558, 34.9673, 36.1785, 37.3895, 38.6002, +39.8103, 41.0198, 42.2285, 43.4360, 44.6421, 45.8462, +47.0478, 48.2458, 49.4393, 50.6266, 51.8058, 52.9741, +54.1277, 55.2617, 56.3694, 57.4405, 58.4607, 59.4074, +60.2442, 60.9031, 61.2360, 60.8103] amp_ref = [-120.0000, -118.7879, -117.5758, -116.3636, -115.1515, -113.9394, -112.7273, -111.5152, -110.3030, -109.0909, -107.8788, -106.6667, -105.4545, -104.2424, -103.0303, -101.8182, -100.6061, -99.3939, -98.1818, -96.9697, -95.7576, -94.5455, -93.3333, -92.1212, -90.9091, -89.6970, -88.4848, -87.2727, -86.0606, -84.8485, -83.6364, -82.4242, -81.2121, -80.0000, -78.7879, -77.5758, -76.3636, -75.1515, -73.9394, -72.7273, -71.5152, -70.3030, -69.0909, -67.8788, -66.6667, -65.4545, -64.2424, -63.0303, -61.8182, -60.6061, -59.3939, -58.1818, -56.9697, -55.7576, -54.5455, -53.3333, -52.1212, -50.9091, -49.6970, -48.4848, -47.2727, -46.0606, -44.8485, -43.6364, -42.4242, -41.2121, -40.0000, -38.7879, -37.5758, -36.3636, -35.1515, -33.9394, -32.7273, -31.5152, -30.3030, -29.0909, -27.8788, -26.6667, -25.4545, -24.2424, -23.0303, -21.8182, -20.6061, -19.3939, -18.1818, -16.9697, -15.7576, -14.5455, -13.3333, -12.1212, -10.9091, -9.6970, -8.4848, -7.2727, -6.0606, -4.8485, -3.6364, -2.4242, -1.2121, 0.] k0_ref = [3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6300, 3.6300, 3.6300, 3.6300, 3.6299, 3.6299, 3.6298, 3.6298, 3.6297, 3.6295, 3.6293, 3.6291, 3.6287, 3.6283, 3.6277, 3.6270, 3.6260, 3.6246, 3.6228, 3.6205, 3.6173, 3.6131, 3.6075, 3.6000, 3.5899, 3.5762, 3.5576, 3.5320, 3.4961, 3.4447, 3.3690, 3.2518, 3.0562, 2.6817] k1_ref = [3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6301, 3.6300, 3.6300, 3.6300, 3.6300, 3.6299, 3.6299, 3.6298, 3.6297, 3.6296, 3.6295, 3.6293, 3.6290, 3.6286, 3.6282, 3.6275, 3.6267, 3.6256, 3.6242, 3.6223, 3.6198, 3.6164, 3.6120, 3.6062, 3.5984, 3.5881, 3.5744, 3.5561, 3.5318, 3.4993, 3.4557, 3.3969, 3.3171, 3.2075, 3.0547, 2.8367, 2.5142, 2.0040] sigma_e2_ref = [0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3634, 0.3633, 0.3633, 0.3633, 0.3633, 0.3632, 0.3630, 0.3628, 0.3624, 0.3616, 0.3603, 0.3579, 0.3536, 0.3459, 0.3319, 0.3059] amp = np.linspace(-120, 0, 100) order = 4 osr = 64 f0 = 0.333 Hinf = 1.2 ntf = ds.synthesizeNTF(order, osr, 2, Hinf, f0) snr_pred, amp_pred, k0, k1, sigma_e2 = ds.predictSNR(ntf, osr, amp, f0) # Delete garbage data for check in (np.isinf, np.isnan): i = check(snr_ref) snr_ref = np.delete(snr_ref, np.where(i)) amp_ref = np.delete(amp_ref, np.where(i)) i = check(snr_pred) snr_pred = np.delete(snr_pred, np.where(i)) amp_pred = np.delete(amp_pred, np.where(i)) self.assertTrue(np.allclose(snr_pred, snr_ref, atol=1e-2, rtol=1e-3)) self.assertTrue(np.allclose(amp_pred, amp_ref, atol=1e-2, rtol=5e-4)) self.assertTrue(np.allclose(k0, k0_ref, atol=1e-3, rtol=1e-2)) self.assertTrue(np.allclose(k1, k1_ref, atol=1e-3, rtol=50e-2)) self.assertTrue(np.allclose(sigma_e2, sigma_e2_ref, atol=1e-3, rtol=1e-2))
def test_dsdemo3(self): """dsdemo3 test: Delta sigma modulator synthesis""" order = 5 R = 42 opt = 1 H = ds.synthesizeNTF(order, R, opt) # ## Evaluation of the coefficients for a CRFB topology a, g, b, c = ds.realizeNTF(H) # Use a single feed-in for the input # Lets check that stuffABCD understands that if b is scalar it means 1 feed-in. ABCD = ds.stuffABCD(a, g, b[0], c) # for passing the assertion below, we need b to have the trailing zeros b = np.concatenate((np.atleast_1d(b[0]), np.zeros((b.shape[0] - 1,)))) u = np.linspace(0, 0.6, 30) N = 1e4 T = np.ones((1, N)) maxima = np.zeros((order, len(u))) for i in range(len(u)): ui = u[i] v, xn, xmax, _ = ds.simulateDSM(ui*T, ABCD); maxima[:, i] = np.squeeze(xmax) if any(xmax > 1e2): umax = ui u = u[:i+1] maxima = maxima[:, :i] break # save the maxima prescale_maxima = np.copy(maxima) # ## Scaled modulator # ### Calculate the scaled coefficients ABCDs, umax, _ = ds.scaleABCD(ABCD, N_sim=1e5) as_, gs, bs, cs = ds.mapABCD(ABCDs) # ### Calculate the state maxima u = np.linspace(0, umax, 30) N = 1e4 T = np.ones((N,)) maxima = np.zeros((order, len(u))) for i in range(len(u)): ui = u[i] v, xn, xmax, _ = ds.simulateDSM(ui*T, ABCDs) maxima[:, i] = xmax.squeeze() if any(xmax > 1e2): umax = ui; u = u[:i] maxima = maxima[:, :i] break self.assertTrue(np.allclose(ABCD, self.data['ABCD'])) self.assertTrue(np.allclose(ABCDs, self.data['ABCDs'], atol=1e-2, rtol=5e-2)) self.assertTrue(np.allclose(a, self.data['a'], atol=1e-5, rtol=1e-3)) self.assertTrue(np.allclose(b, self.data['b'], atol=1e-5, rtol=1e-3)) self.assertTrue(np.allclose(g, self.data['g'], atol=1e-5, rtol=1e-3)) self.assertTrue(np.allclose(c, self.data['c'], atol=1e-5, rtol=1e-3)) self.assertTrue(np.allclose(as_, self.data['as'], atol=1e-2, rtol=5e-3)) self.assertTrue(np.allclose(bs, self.data['bs'], atol=5e-3, rtol=5e-3)) self.assertTrue(np.allclose(gs, self.data['gs'], atol=5e-3, rtol=5e-3)) self.assertTrue(np.allclose(cs, self.data['cs'], atol=3e-2, rtol=3e-2)) self.assertTrue(np.allclose(umax, self.data['umax'], atol=5e-3, rtol=5e-3)) self.assertTrue(np.allclose(maxima, self.data['maxima'], atol=2e-2, rtol=5e-2))
def test_synthesizeNTF_15(self): """Test function for synthesizeNTF() 15/15""" # order < len(opt) with self.assertRaises(ValueError): z, p, k = synthesizeNTF(order=3, osr=32, opt=[0., 0., 0., 0.], H_inf=1.3, f0=0.)
def test_synthesizeNTF_12(self): """Test function for synthesizeNTF() 12/15""" # f0 > 0.5 -> ValueError z, p, k = synthesizeNTF(order=2, osr=32, opt=0, H_inf=1.3, f0=0.7)
def test_synthesizeNTF_15(self): """Test function for synthesizeNTF() 15/15""" # order < len(opt) z, p, k = synthesizeNTF(order=3, osr=32, opt=[0., 0., 0., 0.], H_inf=1.3, f0=0.)
def test_synthesizeNTF_14(self): """Test function for synthesizeNTF() 14/15""" # 1 < len(opt) < order z, p, k = synthesizeNTF(order=3, osr=32, opt=[0., 0.], H_inf=1.3, f0=0.3)
def test_synthesizeNTF_13(self): """Test function for synthesizeNTF() 13/15""" # f0 > 0. and order odd -> ValueError z, p, k = synthesizeNTF(order=3, osr=32, opt=0, H_inf=1.3, f0=0.3)