Ejemplo n.º 1
0
def test_minkowski_dif_twogen():
    'test the minkowski difference from a zonotope with two linearly dependent generators'

    z = lpset.from_centered_zonotope([[0, 1], [0, -1]])
    expected = [[-2, 0], [2, 0]]
    assert_verts_equals(z.verts(), expected)

    b = lpset.from_box([[-0.1, 0.1]])
    dif = z.clone().minkowski_difference(b)

    expected = [[-1.9, 0], [1.9, 0]]
    assert_verts_equals(dif.verts(), expected)
Ejemplo n.º 2
0
def test_matthias_zonotopes():
    'tests from_centered_zonotope constructor'

    # zonotopes from Figure 2 of "On Computing the Minkowski Difference of Zonotopes" by Matthias Althoff

    # Z_m (shifted due to lack of center in our constructor)
    m = lpset.from_centered_zonotope([[1, 0], [0, 1], [1, 1]])
    expected = [[-2, -2], [-2, 0], [0, 2], [2, 2], [2, 0], [0, -2]]
    assert_verts_equals(m.verts(), expected)

    # Z_{s,1}
    s1 = lpset.from_centered_zonotope([[0.5, -0.25], [0, 0.25]])
    expected = [[-0.5, 0], [-0.5, 0.5], [0.5, 0], [0.5, -0.5]]
    assert_verts_equals(s1.verts(), expected)

    # Z_{s,2}
    s2 = lpset.from_centered_zonotope([[0.5, -0.5], [0, 0.5]])

    #s2.plot()
    #plt.show()

    expected = [[-0.5, 0], [-0.5, 1.0], [0.5, 0], [0.5, -1.0]]
    assert_verts_equals(s2.verts(), expected)

    # Z_{s,3}
    s3 = lpset.from_centered_zonotope([[2.0, -0.5], [0, 0.5]])
    expected = [[-2.0, 0], [-2.0, 1.0], [2.0, 0], [2.0, -1.0]]
    assert_verts_equals(s3.verts(), expected)
Ejemplo n.º 3
0
def test_intersection():
    'test the lpset intersection'

    m = lpset.from_centered_zonotope([[1, 1, 1], [1, 0, 0], [0, 1, 0],
                                      [0, 0, 1]])
    s = lpset.from_centered_zonotope([[-1 / 3, 1 / 3, 1 / 3], [1 / 3, 0, 0],
                                      [0, 1 / 3, 0], [0, 0, 1 / 3]])

    inter = lpset.intersection(m, s)

    verts_s = s.verts3d()
    verts_inter = lpplot.get_verts3d(inter)

    assert_verts_equals(verts_s, verts_inter)
Ejemplo n.º 4
0
def test_simple_minkowski_difference():
    'test minkowski difference on box sets in 1 and 2d'

    a = lpset.from_box([[-10, 10]])
    b = lpset.from_box([[-1, 1]])
    dif = a.clone().minkowski_difference(b)

    # should be the interval [-9, 9]
    assert not lpset.contains_point(a, [-9.1])
    assert not lpset.contains_point(a, [9.1])
    assert lpset.contains_point(a, [-8.9])
    assert lpset.contains_point(a, [8.9])

    a = lpset.from_box([[-1, 1], [-1, 1]])
    b = lpset.from_box([[-0.2, 0.2], [-0.2, 0.2]])
    dif = a.clone().minkowski_difference(b)

    expected = [[-0.8, -0.8], [0.8, -0.8], [0.8, 0.8], [-0.8, 0.8]]
    assert_verts_equals(dif.verts(), expected)
Ejemplo n.º 5
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()