コード例 #1
0
def test_rotated_aggregate():
    'tests rotated aggregation'

    mode = HybridAutomaton().new_mode('mode_name')
    lpi1 = lputil.from_box([[0, 1], [0, 1]], mode)
    lpi2 = lputil.from_box([[1, 2], [1, 2]], mode)

    sq2 = math.sqrt(2) / 2.0

    agg_dirs = np.array([[sq2, sq2], [sq2, -sq2]], dtype=float)

    lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode)

    assert lputil.is_point_in_lpi([0, 0], lpi)
    assert lputil.is_point_in_lpi([2, 2], lpi)
    assert lputil.is_point_in_lpi([1, 2], lpi)
    assert lputil.is_point_in_lpi([2, 1], lpi)
    assert lputil.is_point_in_lpi([0, 1], lpi)
    assert lputil.is_point_in_lpi([1, 0], lpi)

    verts = lpplot.get_verts(lpi)

    assert len(verts) == 5

    for p in [(0.5, -0.5), (-0.5, 0.5), (2.5, 1.5), (1.5, 2.5)]:
        assert pair_almost_in(p, verts)

    assert verts[0] == verts[-1]
コード例 #2
0
def test_box_aggregate3():
    'tests box aggregation with 3 boxes'

    mode = HybridAutomaton().new_mode('mode_name')
    
    lpi1 = lputil.from_box([[-2, -1], [-0.5, 0.5]], mode)
    lpi2 = lpi1.clone()
    lpi3 = lpi1.clone()

    basis2 = np.array([[0, 1], [-1, 0]], dtype=float)
    lputil.set_basis_matrix(lpi2, basis2)

    basis3 = np.array([[-1, 0], [0, -1]], dtype=float)
    lputil.set_basis_matrix(lpi3, basis3)

    plot_vecs = lpplot.make_plot_vecs(256, offset=0.1) # use an offset to prevent LP dir from being aligned with axis

    # bounds for lpi1 should be [[-2, -1], [-0.5, 0.5]]
    verts = lpplot.get_verts(lpi1, plot_vecs=plot_vecs)
    assert_verts_is_box(verts, [[-2, -1], [-0.5, 0.5]])

    # bounds for lpi2 should be [[-0.5, 0.5], [1, 2]]
    verts = lpplot.get_verts(lpi2, plot_vecs=plot_vecs)
    assert_verts_is_box(verts, [[-0.5, 0.5], [1, 2]])

    # bounds for lpi3 should be [[2, 1], [-0.5, 0.5]]
    verts = lpplot.get_verts(lpi3, plot_vecs=plot_vecs)
    assert_verts_is_box(verts, [[2, 1], [-0.5, 0.5]])
 
    # box aggregation, bounds should be [[-2, 2], [-0.5, 2]]
    agg_dirs = np.identity(2)
    lpi = lputil.aggregate([lpi1, lpi2, lpi3], agg_dirs, mode)

    verts = lpplot.get_verts(lpi, plot_vecs=plot_vecs)
    assert_verts_is_box(verts, [[-2, 2], [-0.5, 2]])
コード例 #3
0
def test_box_aggregate2():
    'tests box aggregation'

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

    lpi1 = lputil.from_box([[0, 1], [0, 1]], mode)
    lpi2 = lputil.from_box([[1, 2], [1, 2]], mode)

    agg_dirs = np.identity(2)

    # box aggregation
    lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode)

    verts = lpplot.get_verts(lpi)
    assert_verts_is_box(verts, [[0, 2], [0, 2]])

    # test setting basis matrix after aggregation
    lputil.set_basis_matrix(lpi, np.identity(2))

    verts = lpplot.get_verts(lpi)
    assert_verts_is_box(verts, [[0, 2], [0, 2]])

    lputil.set_basis_matrix(lpi, -1 * np.identity(2))

    verts = lpplot.get_verts(lpi)
    assert_verts_is_box(verts, [[-2, 0], [-2, 0]])
コード例 #4
0
def test_aggregate_self():
    '''
    test aggregation on an identical set.
    '''

    mode = HybridAutomaton().new_mode('mode_name')
    lpi1 = lputil.from_box([[-2, -1], [-10, 20], [100, 200]], mode)
    lpi2 = lputil.from_box([[-2, -1], [-10, 20], [100, 200]], mode)

    agg_dirs = np.identity(3)

    # box aggregation
    lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode)
    
    assert lpi.is_feasible()

    verts = lpplot.get_verts(lpi, xdim=0, ydim=1)
    assert_verts_is_box(verts, [[-2, -1], [-10, 20]])

    verts = lpplot.get_verts(lpi, xdim=0, ydim=2)
    assert_verts_is_box(verts, [[-2, -1], [100, 200]])

    # make sure no extra variables in lp
    names = lpi.get_names()

    expected_names = ["m0_i0", "m0_i1", "m0_i2", "m0_c0", "m0_c1", "m0_c2"]

    assert names == expected_names

    assert lpi.get_num_rows() == 3 + 3*2
コード例 #5
0
def test_aggregate3():
    'tests aggregation of 3 sets, inspired by the harmonic oscillator system'

    mode = HybridAutomaton().new_mode('mode_name')
    lpi1 = lputil.from_box([[0, 1], [0, 1]], mode)

    # middle set is a diamond
    mat = [[1, 1], [-1, -1], [1, -1], [-1, 1]]
    s = 3.5
    rhs = [6+s, -(6-s), s, s]
    lpi2 = lputil.from_constraints(mat, rhs, mode)
    
    lpi3 = lputil.from_box([[5, 6], [5, 6]], mode)

    lpi_list = [lpi1, lpi2, lpi3]
    verts = []

    for lpi in lpi_list:
        verts += lpplot.get_verts(lpi)

        #xs, ys = zip(*lpplot.get_verts(lpi))
        #plt.plot(xs, ys, 'k-')

    random.seed(0)

    for _ in range(10):
        random_mat = np.random.rand(2, 2)
        agg_dirs = lputil.reorthogonalize_matrix(random_mat, 2)

        lpi = lputil.aggregate(lpi_list, agg_dirs, mode)

        #xs, ys = zip(*lpplot.get_verts(lpi))
        #plt.plot(xs, ys, 'r--')

        for vert in verts:
            assert lputil.is_point_in_lpi(vert, lpi)
コード例 #6
0
def test_aggregate_on_subspace():
    '''
    test aggregation when the dynamics and sets are only on a subspace. 
    '''

    # dynamics are x' == 1, y' == 0, a' == 0
    # lpi1 is [0, 1] x [0, 1] x [1, 1]
    # lpi2 is [3, 4] x [0, 1] x [1, 1]

    # aggregation shouldn't need to introduce a variable along the y direction

    mode = HybridAutomaton().new_mode('mode_name')
    lpi1 = lputil.from_box([[0, 1], [0, 1], [1, 1]], mode)
    lpi2 = lputil.from_box([[4, 5], [0, 1], [1, 1]], mode)

    #a_csr = csr_matrix(np.array([[0, 0, 1], [0, 0, 0], [0, 0, 0]], dtype=float))
    sqr = math.sqrt(2) / 2
    agg_dirs = np.array([[1, 0, 0], [0, sqr, sqr], [0, sqr, -sqr]], dtype=float)

    # box aggregation
    lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode)

    # lpi1 corners
    for pt in [(0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 1)]:
        assert lputil.is_point_in_lpi(pt, lpi)

    # lpi2 corners
    for pt in [(4, 0, 1), (4, 1, 1), (5, 0, 1), (5, 1, 1)]:
        assert lputil.is_point_in_lpi(pt, lpi)

    # make sure we have new variable names
    names = lpi.get_names()

    expected_names = ["m0_i0", "m0_i1", "m0_i2", "m0_c0", "m0_c1", "m0_c2"]

    assert names == expected_names
コード例 #7
0
ファイル: aggregate.py プロジェクト: manishgcs/control-hylaa
def aggregate_box_arnoldi(agg_list, op_list, is_box, is_arnoldi, add_guard, print_func):
    '''
    perform template-based aggregation on the passed-in list of states

    Currently, this can either use box template directions or arnoldi (+box) template directions
    '''

    assert is_box or is_arnoldi

    min_step = min([state.cur_steps_since_start[0] for state in agg_list])
    max_step = max([state.cur_steps_since_start[1] for state in agg_list])
    step_interval = [min_step, max_step]

    print_func("Aggregation time step interval: {}".format(step_interval))

    # create a new state from the aggregation
    postmode = agg_list[0].mode
    postmode_dims = postmode.a_csr.shape[0]
    mid_index = len(agg_list) // 2

    op = op_list[mid_index]

    if is_box or op is None:
        agg_dir_mat = np.identity(postmode_dims)
    elif is_arnoldi:
        # aggregation with a predecessor, use arnoldi directions in predecessor mode in center of
        # middle aggregagted state, then project using the reset, and reorthogonalize

        premode = op.parent_node.stateset.mode
        t = op.transition
        print_func("aggregation point: {}".format(op.premode_center))

        premode_dir_mat = lputil.make_direction_matrix(op.premode_center, premode.a_csr)
        print_func("premode dir mat:\n{}".format(premode_dir_mat))

        if t.reset_csr is None:
            agg_dir_mat = premode_dir_mat
        else:
            projected_dir_mat = premode_dir_mat * t.reset_csr.transpose()

            print_func("projected dir mat:\n{}".format(projected_dir_mat))

            # re-orthgohonalize (and create new vectors if necessary)
            agg_dir_mat = lputil.reorthogonalize_matrix(projected_dir_mat, postmode_dims)

        # also add box directions in target mode (if they don't already exist)
        box_dirs = []
        for dim in range(postmode_dims):
            direction = [0 if d != dim else 1 for d in range(postmode_dims)]
            exists = False

            for row in agg_dir_mat:
                if np.allclose(direction, row):
                    exists = True
                    break

            if not exists:
                box_dirs.append(direction)

        if box_dirs:
            agg_dir_mat = np.concatenate((agg_dir_mat, box_dirs), axis=0)

    if op and add_guard:
        # add all the guard conditions to the agg_dir_mat
        
        t = op.transition

        if t.reset_csr is None: # identity reset
            guard_dir_mat = t.guard_csr
        else:
            # multiply each direction in the guard by the reset
            guard_dir_mat = t.guard_csr * t.reset_csr.transpose()

        if guard_dir_mat.shape[0] > 0:
            agg_dir_mat = np.concatenate((agg_dir_mat, guard_dir_mat.toarray()), axis=0)

    print_func("agg dir mat:\n{}".format(agg_dir_mat))
    lpi_list = [state.lpi for state in agg_list]

    new_lpi = lputil.aggregate(lpi_list, agg_dir_mat, postmode)

    return StateSet(new_lpi, agg_list[0].mode, step_interval, op_list, is_concrete=False)