예제 #1
0
def test_check_sys_equal():
    assert not sys_equal(np.zeros(2), np.zeros(3))

    assert s != z
    assert not z == s
    assert LinearSystem(5, analog=True) != LinearSystem(5, analog=False)

    with pytest.raises(ValueError):
        sys_equal(s, z)

    with pytest.raises(ValueError):
        ss_equal(s, z)
예제 #2
0
def test_check_sys_equal():
    assert not sys_equal(np.ones(2), np.ones(3))

    assert s != z
    assert not z == s
    assert LinearSystem(5, analog=True) != LinearSystem(5, analog=False)

    with pytest.raises(ValueError):
        sys_equal(s, z)

    with pytest.raises(ValueError):
        ss_equal(s, z)
예제 #3
0
def test_similarity_transform():
    sys = Alpha(0.1)

    TA, TB, TC, TD = sys.transform(np.eye(2), np.eye(2)).ss
    A, B, C, D = sys2ss(sys)
    assert np.allclose(A, TA)
    assert np.allclose(B, TB)
    assert np.allclose(C, TC)
    assert np.allclose(D, TD)

    T = [[1, 1], [-0.5, 0]]
    rsys = sys.transform(T)
    assert ss_equal(rsys, sys.transform(T, inv(T)))

    TA, TB, TC, TD = rsys.ss
    assert not np.allclose(A, TA)
    assert not np.allclose(B, TB)
    assert not np.allclose(C, TC)
    assert np.allclose(D, TD)
    assert sys_equal(sys, (TA, TB, TC, TD))

    length = 1000
    dt = 0.001
    x_old = np.asarray(
        [sub.impulse(length=length, dt=dt) for sub in sys])
    x_new = np.asarray(
        [sub.impulse(length=length, dt=dt) for sub in rsys])

    # dot(T, x_new(t)) = x_old(t)
    assert np.allclose(np.dot(T, x_new), x_old)
예제 #4
0
def test_canonical():
    sys = ([1], [1], [1], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [1, 0]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 1]], [[0], [1]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 1]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 0]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 0]], [[0], [1]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0, 1], [0, 1, 1], [1, 0, 0]], [[0], [1], [-1]],
           [[1, 1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = nengo.Alpha(0.1)
    csys = canonical(sys, controllable=True)
    osys = canonical(sys, controllable=False)

    assert ss_equal(csys, LinearSystem(sys).controllable)
    assert ss_equal(osys, LinearSystem(sys).observable)

    assert sys_equal(csys, osys)
    assert not ss_equal(csys, osys)  # different state-space realizations

    A, B, C, D = csys.ss
    assert sys_equal(csys, sys)
    assert ss_equal(csys,
                    ([[-20, -100], [1, 0]], [[1], [0]], [[0, 100]], [[0]]))

    assert sys_equal(osys, sys)
    assert ss_equal(osys,
                    ([[-20, 1], [-100, 0]], [[0], [100]], [[1, 0]], [[0]]))
예제 #5
0
def test_canonical():
    sys = ([1], [1], [1], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [1, 0]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 1]], [[0], [1]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 1]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 0]], [[1], [0]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0], [0, 0]], [[0], [1]], [[1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = ([[1, 0, 1], [0, 1, 1], [1, 0, 0]], [[0], [1], [-1]],
           [[1, 1, 1]], [0])
    assert sys_equal(canonical(sys), sys)

    sys = nengo.Alpha(0.1)
    csys = canonical(sys, controllable=True)
    osys = canonical(sys, controllable=False)

    assert sys_equal(csys, osys)
    assert not ss_equal(csys, osys)  # different state-space realizations

    A, B, C, D = csys.ss
    assert sys_equal(csys, sys)
    assert ss_equal(csys,
                    ([[-20, -100], [1, 0]], [[1], [0]], [[0, 100]], [[0]]))

    assert sys_equal(osys, sys)
    assert ss_equal(osys,
                    ([[-20, 1], [-100, 0]], [[0], [100]], [[1, 0]],  [[0]]))
예제 #6
0
def test_linear_system():
    tau = 0.05
    sys = Lowpass(tau)
    dsys = (1 - np.exp(-1)) * z / (1 - np.exp(-1) * z)

    # Test attributes before state-space/zpk computed
    assert sys.is_tf
    assert not sys.is_ss
    assert not sys.is_zpk

    # Test representations
    assert sys == (1, [tau, 1])
    assert sys_equal(sys.tf, sys)
    assert sys_equal(sys.ss, sys)
    assert sys_equal(sys.zpk, sys)

    # Test attributes after state-space/zpk computed
    assert sys.is_tf
    assert sys.is_ss
    assert sys.is_zpk

    # Test attributes
    assert np.allclose(sys.num, (1,))
    assert np.allclose(sys.den, (tau, 1))
    assert sys.causal
    assert sys.proper
    assert not sys.has_passthrough
    assert not (sys/s).has_passthrough
    assert (sys*s).has_passthrough
    assert (sys*s).causal
    assert not (sys*s).proper
    assert not (sys*s*s).has_passthrough and not (sys*s*s).causal
    assert (sys*s*s + sys*s).has_passthrough

    assert np.allclose(sys.A, -1/tau)
    assert np.allclose(sys.B, 1)
    assert np.allclose(sys.C, 1/tau)
    assert np.allclose(sys.D, 0)

    assert np.allclose(sys.zeros, [0])
    assert np.allclose(sys.poles, [-1/tau])
    assert np.allclose(sys.gain, 1/tau)

    assert sys.order_num == 0
    assert sys.order_den == 1
    assert len(sys) == 1  # order_den
    assert len(LinearSystem(sys.ss)) == 1  # uses state-space rep

    # Test dcgain and __call__
    assert np.allclose(sys.dcgain, 1)
    assert np.allclose(dsys.dcgain, 1)
    assert np.allclose((s*sys)(1e12), 1.0 / tau)  # initial value theorem
    assert np.allclose((s*sys)(0), 0)  # final value theorem
    assert np.allclose(((1 - ~z)*dsys)(1), 0)  # final value theorem

    # Test multiplication and squaring
    assert sys*2 == 2*sys
    assert (0.4*sys) + (0.6*sys) == sys
    assert sys + sys == 2*sys
    assert sys * sys == sys**2
    assert sys_equal(sys + sys*sys, sys*sys + sys)

    # Test pow
    with pytest.raises(TypeError):
        sys**0.5
    assert sys**0 == LinearSystem(1)

    # Test inversion
    inv = ~sys
    assert inv == ([tau, 1], 1)
    assert not inv.causal

    assert inv == 1 / sys
    assert inv == sys**(-1)

    # Test repr/str
    copy = eval(
        repr(sys), {}, {'LinearSystem': LinearSystem, 'array': np.array})
    assert copy == sys
    assert str(copy) == str(sys)

    # Test addition/subtraction
    assert sys + 2 == ((2*tau, 3), (tau, 1))
    assert 3 + sys == (-sys)*(-1) + 3
    assert (4 - sys) + 2 == (-sys) + 6
    assert np.allclose((sys - sys).num, 0)

    # Test division
    assert sys / 2 == sys * 0.5
    assert 2 / sys == 2 * inv

    cancel = sys / sys
    assert np.allclose(cancel.num, cancel.den)

    # Test inequality
    assert sys != (sys*2)

    # Test usage of differential building block
    assert sys == 1 / (tau*s + 1)
예제 #7
0
def test_sys_conversions():
    sys = Alpha(0.1)

    tf = sys2tf(sys)
    ss = sys2ss(sys)
    zpk = sys2zpk(sys)

    assert sys_equal(sys2ss(tf), ss)
    assert sys_equal(sys2ss(ss), ss)  # unchanged
    assert sys_equal(sys2tf(tf), tf)  # unchanged
    assert sys_equal(sys2tf(ss), tf)

    assert sys_equal(sys2zpk(zpk), zpk)  # sanity check
    assert sys_equal(sys2zpk(tf), zpk)  # sanity check
    assert sys_equal(sys2zpk(ss), zpk)
    assert sys_equal(sys2tf(zpk), tf)
    assert sys_equal(sys2ss(zpk), ss)

    # should also work with nengo's synapse types
    assert sys_equal(sys2zpk(nengo.Alpha(0.1)), zpk)
    assert sys_equal(sys2tf(nengo.Alpha(0.1)), tf)
    assert sys_equal(sys2ss(nengo.Alpha(0.1)), ss)

    # system can also be just a scalar
    assert sys_equal(sys2tf(2.0), (1, 0.5))
    assert np.allclose(sys2ss(5)[3], 5)
    assert sys_equal(sys2zpk(5), 5)

    with pytest.raises(ValueError):
        sys2ss(np.zeros(5))

    with pytest.raises(ValueError):
        sys2zpk(np.zeros(5))

    with pytest.raises(ValueError):
        sys2tf(np.zeros(5))

    with pytest.raises(ValueError):
        # _ss2tf(...): passthrough must be single element
        sys2tf(([], [], [], [1, 2]))
예제 #8
0
def test_linear_system():
    tau = 0.05
    sys = Lowpass(tau)
    dsys = (1 - np.exp(-1)) * z / (1 - np.exp(-1) * z)

    # Test attributes before state-space/zpk computed
    assert sys.is_tf
    assert not sys.is_ss
    assert not sys.is_zpk

    # Test representations
    assert sys == (1, [tau, 1])
    assert sys_equal(sys.tf, sys)
    assert sys_equal(sys.ss, sys)
    assert sys_equal(sys.zpk, sys)

    # Test attributes after state-space/zpk computed
    assert sys.is_tf
    assert sys.is_ss
    assert sys.is_zpk

    # Size in/out-related properties
    assert sys.is_SISO
    assert dsys.is_SISO
    assert sys.size_in == sys.size_out == dsys.size_in == dsys.size_out == 1

    # Test attributes
    assert np.allclose(sys.num, (1/tau,))
    assert np.allclose(sys.den, (1, 1/tau))
    assert sys.causal
    assert sys.strictly_proper
    assert not sys.has_passthrough
    assert not (sys/s).has_passthrough
    assert (sys*s).has_passthrough
    assert (sys*s).causal
    assert not (sys*s).strictly_proper
    assert not (sys*s*s).has_passthrough and not (sys*s*s).causal
    assert (sys*s*s + sys*s).has_passthrough

    assert np.allclose(sys.A, -1/tau)
    assert np.allclose(sys.B, 1)
    assert np.allclose(sys.C, 1/tau)
    assert np.allclose(sys.D, 0)

    assert np.allclose(sys.zeros, [0])
    assert np.allclose(sys.poles, [-1/tau])
    assert np.allclose(sys.gain, 1/tau)
    assert np.allclose(sys.zpk[0], np.array([]))
    assert np.allclose(sys.zpk[1], np.array([-1/tau]))
    assert np.allclose(sys.zpk[2], 1/tau)

    assert sys.order_num == 0
    assert sys.order_den == 1
    assert len(sys) == 1  # order_den
    assert len(LinearSystem(sys.ss)) == 1  # uses state-space rep

    # Test dcgain and __call__
    assert np.allclose(sys.dcgain, 1)
    assert np.allclose(dsys.dcgain, 1)
    assert np.allclose((s*sys)(1e12), 1.0 / tau)  # initial value theorem
    assert np.allclose((s*sys)(0), 0)  # final value theorem
    assert np.allclose(((1 - ~z)*dsys)(1), 0)  # final value theorem

    # Test multiplication and squaring
    assert sys*2 == 2*sys
    assert (0.4*sys) + (0.6*sys) == sys
    assert sys + sys == 2*sys
    assert sys * sys == sys**2
    assert sys_equal(sys + sys*sys, sys*sys + sys)

    # Test pow
    with pytest.raises(TypeError):
        sys**0.5
    assert sys**0 == LinearSystem(1)

    # Test inversion
    inv = ~sys
    assert inv == ([tau, 1], 1)
    assert not inv.causal

    assert inv == 1 / sys
    assert inv == sys**(-1)

    # Test repr/str
    copy = _eval(sys)
    assert copy == sys

    # Test addition/subtraction
    assert sys + 2 == ((2*tau, 3), (tau, 1))
    assert 3 + sys == (-sys)*(-1) + 3
    assert (4 - sys) + 2 == (-sys) + 6
    assert np.allclose((sys - sys).num, 0)

    # Test division
    assert sys / 2 == sys * 0.5
    assert 2 / sys == 2 * inv

    cancel = sys / sys
    assert np.allclose(cancel.num, cancel.den)

    # Test inequality
    assert sys != (sys*2)

    # Test usage of differential building block
    assert sys == 1 / (tau*s + 1)
예제 #9
0
def test_sys_conversions():
    sys = Alpha(0.1)

    tf = sys2tf(sys)
    ss = sys2ss(sys)
    zpk = sys2zpk(sys)

    assert sys_equal(sys2ss(tf), ss)
    assert sys_equal(sys2ss(ss), ss)  # unchanged
    assert sys_equal(sys2tf(tf), tf)  # unchanged
    assert sys_equal(sys2tf(ss), tf)

    assert sys_equal(sys2zpk(zpk), zpk)  # sanity check
    assert sys_equal(sys2zpk(tf), zpk)  # sanity check
    assert sys_equal(sys2zpk(ss), zpk)
    assert sys_equal(sys2tf(zpk), tf)
    assert sys_equal(sys2ss(zpk), ss)

    # should also work with nengo's synapse types
    assert sys_equal(sys2zpk(nengo.Alpha(0.1)), zpk)
    assert sys_equal(sys2tf(nengo.Alpha(0.1)), tf)
    assert sys_equal(sys2ss(nengo.Alpha(0.1)), ss)

    # system can also be just a scalar
    assert sys_equal(sys2tf(2.0), (1, 0.5))
    assert np.allclose(sys2ss(5)[3], 5)
    assert sys_equal(sys2zpk(5), 5)

    with pytest.raises(ValueError):
        sys2ss(np.zeros(5))

    with pytest.raises(ValueError):
        sys2zpk(np.zeros(5))

    with pytest.raises(ValueError):
        sys2tf(np.zeros(5))

    with pytest.raises(ValueError):
        # _ss2tf(...): passthrough must be single element
        sys2tf(([], [], [], [1, 2]))