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_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_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_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_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')
Example #8
0
    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))
Example #10
0
 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_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))
Example #12
0
 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
Example #13
0
    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))
    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_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))