Пример #1
0
def test_chull_one_step_inputs():
    'test convex hull with one-step lpi for a system with inputs (bug where current vars was not set correctly)'

    mode = HybridAutomaton().new_mode('mode_name')

    step_size = math.pi/4

    a_mat = np.array([[0, 1], [-1, 0]], dtype=float)

    b_mat = [[1], [0]]
    b_constraints = [[1], [-1]]
    b_rhs = [0.2, 0.2]

    mode.set_dynamics(a_mat)
    mode.set_inputs(b_mat, b_constraints, b_rhs)
    mode.init_time_elapse(step_size)

    box = [[-5, -4], [0.0, 1.0]]
    lpi = lputil.from_box(box, mode)

    lpi_one_step = lpi.clone()
    bm, ie_mat = mode.time_elapse.get_basis_matrix(1)

    lputil.set_basis_matrix(lpi_one_step, bm)
    lputil.add_input_effects_matrix(lpi_one_step, ie_mat, mode)

    lpi_list = [lpi, lpi_one_step]
    chull_lpi = lputil.aggregate_chull(lpi_list, mode)

    # 2 current vars and 2 total input effect vars, so expected to be 4 from the end
    assert chull_lpi.cur_vars_offset == chull_lpi.get_num_cols() - 4, "cur_vars in wrong place"
Пример #2
0
def test_reject_constant_inputs():
    'tests the detection of B matrix + constraints where an input is fixed to a constant'

    # x' = Ax + Bu
    # x: [[1, 0], [0, 1]]

    mode = HybridAutomaton().new_mode('mode_name')
    mode.set_dynamics(np.identity(2))

    b_mat = np.identity(2)
    b_con = [[1, 0], [-1, 0], [0, -1], [0, -1]]
    b_rhs = [1, 0, 2, -2]

    try:
        mode.set_inputs(b_mat, b_con, b_rhs)
        assert False, "expected fixed inputs to be rejected"
    except AssertionError:
        pass

    b_rhs = [1, 0, 2, -1]
    mode.set_inputs(b_mat, b_con, b_rhs)
    # should be okay

    b_mat = [[1, 1], [1, 1]]
    b_rhs = [1, 0, 2, -2]
    mode.set_inputs(b_mat, b_con, b_rhs)
    # should be okay (b_mat is not identity)

    b_mat = np.identity(2)
    b_con = [[1, 1], [-1, -1], [1, -1], [-1, 1]]
    b_rhs = [1, 0, 2, -2]
    mode.set_inputs(b_mat, b_con, b_rhs)
    # should be okay

    b_mat = np.identity(2)
    b_con = [[1, 1], [-1, -1], [1, -1], [-1, 1]]
    b_rhs = [1, -2, 2, -2]
    try:
        mode.set_inputs(b_mat, b_con, b_rhs)
        assert False, "expected unsat inputs to be rejected"
    except AssertionError:
        pass
Пример #3
0
def test_step_slow():
    'tests slow-step with non-one step size'

    mode = HybridAutomaton().new_mode('mode_name')
    mode.set_dynamics(np.identity(2))
    mode.set_inputs([[1, 0], [0, 2]], [[1, 0], [-1, 0], [0, 1], [0, -1]],
                    [10, -1, 10, -1])

    mode.init_time_elapse(0.5)

    # do step 1
    _, _ = mode.time_elapse.get_basis_matrix(1)

    # do step 2
    basis_mat, input_mat = mode.time_elapse.get_basis_matrix(2)

    # do step 3
    _, _ = mode.time_elapse.get_basis_matrix(3)

    # go back to step 2 (slow step) and make sure it matches
    slow_basis_mat, slow_input_mat = mode.time_elapse.get_basis_matrix(2)

    assert np.allclose(basis_mat, slow_basis_mat)
    assert np.allclose(input_mat, slow_input_mat)
Пример #4
0
def test_approx_lgg_inputs():
    'test lgg approximation model with inputs'

    # simple dynamics, x' = 1, y' = 0 + u, a' = 0, u in [0.1, 0.2]
    # step size (tau) 0.02
    # after one step, the input effect size should by tau*V \oplus beta*B
    # we'll manually assign beta to be 0.02, in order to be able to check that the constraints are correct
    # A norm is 1

    tau = 0.05

    a_matrix = [[0, 0, 1], [0, 0, 0], [0, 0, 0]]
    b_mat = [[0], [1], [0]]
    b_constraints = [[1], [-1]]
    b_rhs = [0.2, -0.1]

    mode = HybridAutomaton().new_mode('mode')
    mode.set_dynamics(a_matrix)
    mode.set_inputs(b_mat, b_constraints, b_rhs)

    init_lpi = lputil.from_box([[0, 0], [0, 0], [1, 1]], mode)
    assert lputil.compute_radius_inf(init_lpi) == 1

    ss = StateSet(init_lpi, mode)
    mode.init_time_elapse(tau)
    assert_verts_equals(lpplot.get_verts(ss.lpi), [(0, 0)])

    ss.apply_approx_model(HylaaSettings.APPROX_LGG)

    assert np.linalg.norm(a_matrix, ord=np.inf) == 1.0

    v_set = lputil.from_input_constraints(mode.b_csr, mode.u_constraints_csc,
                                          mode.u_constraints_rhs, mode)
    assert lputil.compute_radius_inf(v_set) == 0.2
    alpha = (math.exp(tau) - 1 - tau) * (1 + 0.2)

    assert_verts_equals(lpplot.get_verts(ss.lpi), \
                        [(0, 0), (tau-alpha, 0.2*tau + alpha), (tau+alpha, 0.2*tau+alpha), (tau+alpha, 0.1*tau-alpha)])

    # note: c gets bloated by alpha as well
    assert (ss.lpi.minimize(
        [0, 0, -1])[ss.lpi.cur_vars_offset + 2]) - (1 + alpha) < 1e-9
    assert (ss.lpi.minimize(
        [0, 0, 1])[ss.lpi.cur_vars_offset + 2]) - (1 - alpha) < 1e-9

    # c is actually growing, starting at (1,1) at x=0 and going to [1-alpha, 1+alpha] at x=tau
    assert_verts_equals(lpplot.get_verts(ss.lpi, xdim=0, ydim=2), \
                    [(0, 1), (tau-alpha, 1+alpha), (tau+alpha, 1+alpha), (tau+alpha, 1-alpha), (tau-alpha, 1-alpha)])

    # ready to start
    ss.step()

    beta = (math.exp(tau) - 1 - tau) * 0.2

    # note: c gets bloated as well! so now it's [1-epsilon, 1+epsilon], where epsilon=alpha
    # so x will grow by [tau * (1 - alpha), tau * (1 + alpha)]
    expected = [(tau + beta, -beta + tau * 0.1), \
             (tau - beta, -beta + tau * 0.1), \
             (tau - beta, beta + tau * 0.2), \
             ((tau - alpha) + tau * (1 - alpha) - beta, 2*0.2*tau + alpha + beta), \
             ((tau + alpha) + tau * (1 + alpha) + beta, 2*0.2*tau+alpha + beta), \
             ((tau + alpha) + tau * (1 + alpha) + beta, 2*0.1*tau-alpha - beta)]

    #xs, ys = zip(*expected)
    #plt.plot([x for x in xs] + [xs[0]], [y for y in ys] + [ys[0]], 'r-') # expected is red

    verts = lpplot.get_verts(ss.lpi)
    #xs, ys = zip(*verts)
    #plt.plot(xs, ys, 'k-+') # computed is black
    #plt.show()

    assert_verts_equals(verts, expected)

    # one more step should work without errors
    ss.step()
Пример #5
0
def test_box_inputs():
    'tests from_box with a simple input effects matrix'

    # x' = Ax + Bu
    # A = 0
    # B = [[1, 0], [0, 2]]
    # u1 and u2 are bounded between [1, 10]

    # (init) step 0: [0, 1] x [0, 1]
    # step 1: [1, 11] x [2, 21]
    # step 2: [2, 21] x [4, 41]

    mode = HybridAutomaton().new_mode('mode_name')
    mode.set_dynamics(np.zeros((2, 2)))
    mode.set_inputs([[1, 0], [0, 2]], [[1, 0], [-1, 0], [0, 1], [0, -1]],
                    [10, -1, 10, -1])

    init_box = [[0, 1], [0, 1]]
    lpi = lputil.from_box(init_box, mode)

    assert lpi.basis_mat_pos == (0, 0)
    assert lpi.dims == 2
    assert lpi.cur_vars_offset == 2
    assert lpi.input_effects_offsets == (
        6, 4)  # row 6, column 4 for total input effects offsets

    # step 0
    mat = lpi.get_full_constraints()
    types = lpi.get_types()
    rhs = lpi.get_rhs()
    names = lpi.get_names()

    expected_mat = np.array([\
        [1, 0, -1, 0, 1, 0], \
        [0, 1, 0, -1, 0, 1], \
        [-1, 0, 0, 0, 0, 0], \
        [1, 0, 0, 0, 0, 0], \
        [0, -1, 0, 0, 0, 0], \
        [0, 1, 0, 0, 0, 0], \
        [0, 0, 0, 0, -1, 0], \
        [0, 0, 0, 0, 0, -1]], dtype=float)

    expected_vec = np.array([0, 0, 0, 1, 0, 1, 0, 0], dtype=float)

    fx = glpk.GLP_FX
    up = glpk.GLP_UP
    expected_types = [fx, fx, up, up, up, up, fx, fx]

    expected_names = ["m0_i0", "m0_i1", "m0_c0", "m0_c1", "m0_ti0", "m0_ti1"]

    assert np.allclose(rhs, expected_vec)
    assert types == expected_types
    assert np.allclose(mat.toarray(), expected_mat)
    assert names == expected_names

    verts = lpplot.get_verts(lpi)
    assert_verts_is_box(verts, init_box)

    # do step 1
    mode.init_time_elapse(1.0)
    basis_mat, input_mat = mode.time_elapse.get_basis_matrix(1)

    lputil.set_basis_matrix(lpi, basis_mat)
    lputil.add_input_effects_matrix(lpi, input_mat, mode)

    mat = lpi.get_full_constraints()
    types = lpi.get_types()
    rhs = lpi.get_rhs()
    names = lpi.get_names()

    expected_mat = np.array([\
        [1, 0, -1, 0, 1, 0, 0, 0], \
        [0, 1, 0, -1, 0, 1, 0, 0], \
        [-1, 0, 0, 0, 0, 0, 0, 0], \
        [1, 0, 0, 0, 0, 0, 0, 0], \
        [0, -1, 0, 0, 0, 0, 0, 0], \
        [0, 1, 0, 0, 0, 0, 0, 0], \
        [0, 0, 0, 0, -1, 0, 1, 0], \
        [0, 0, 0, 0, 0, -1, 0, 2], \
        [0, 0, 0, 0, 0, 0, 1, 0], \
        [0, 0, 0, 0, 0, 0, -1, 0], \
        [0, 0, 0, 0, 0, 0, 0, 1], \
        [0, 0, 0, 0, 0, 0, 0, -1]], dtype=float)

    expected_vec = np.array([0, 0, 0, 1, 0, 1, 0, 0, 10, -1, 10, -1],
                            dtype=float)

    fx = glpk.GLP_FX
    up = glpk.GLP_UP
    expected_types = [fx, fx, up, up, up, up, fx, fx, up, up, up, up]

    expected_names = [
        "m0_i0", "m0_i1", "m0_c0", "m0_c1", "m0_ti0", "m0_ti1", "m0_I0",
        "m0_I1"
    ]

    assert np.allclose(rhs, expected_vec)
    assert types == expected_types
    assert np.allclose(mat.toarray(), expected_mat)
    assert names == expected_names

    verts = lpplot.get_verts(lpi)

    assert_verts_is_box(verts, [(1, 11), (2, 21)])

    # do step 2
    basis_mat, input_mat = mode.time_elapse.get_basis_matrix(2)
    lputil.set_basis_matrix(lpi, basis_mat)
    lputil.add_input_effects_matrix(lpi, input_mat, mode)

    verts = lpplot.get_verts(lpi)
    assert_verts_is_box(verts, [(2, 21), (4, 41)])