Beispiel #1
0
def test_solution():
    for i in range(100):
        T1 = random_shape(3)
        T2 = random_shape(3)

        target, r1, refl, perm = triangle_solution(T1, T2)
        r2 = TriangleMMD(T1, T2)

        assert(np.isclose(r1, r2))
Beispiel #2
0
def test_metric():
    for i in range(1000):
        T1 = random_shape(3)
        T2 = random_shape(3)
        T3 = random_shape(3)

        TriangleMetric(T1, T2)
        
        _T1 = np.copy(T1)
        _T2 = np.copy(T2)
        _T3 = np.copy(T3)

        fail = False
        #non-negativity
        T1T2 = TriangleMetric(T1, T2)
        if T1T2 >= 0.0:
            print(f'non-negativity: PASS')
        else:
            fail = True
            print(f'non-negativity: FAIL - {T1T2}')
        
        # identity
        T1T1 = TriangleMetric(T1, T1)
        if np.isclose(T1T1, 0.0):
            print(f'identity: PASS')
        else:
            fail = True
            print(f'identity: FAIL - {T1T1}')
        
        # symmetry
        T2T1 = TriangleMetric(T2, T1)
        if np.isclose(T1T2, T2T1):
            print(f'symmetry: PASS')
        else:
            fail = True
            print(f'symmetry: FAIL - {T1T2} != {T2T1}')
        
        # triangle inequality
        T2T3 = TriangleMetric(T2, T3)
        T1T3 = TriangleMetric(T1, T3)
        if np.isclose(T1T3, T1T2 + T2T3) or T1T3 < T1T2 + T2T3:
            print(f'triangle inequality: PASS')
        else:
            fail = True
            print(f'triangle inequality: FAIL - {T1T3} !<= {T1T2} + {T2T3} ({T1T2 + T2T3})')

        if fail:
            print(f'T1: {T1}')
            print(f'T2: {T2}')
            print(f'T3: {T3}')
            break
Beispiel #3
0
	def test_less_equals(self):
		'''This test generates a random shape, extends it, and asserts that the random shape is <= the extension'''
		for x in range(0,n):
			random_shape = shapes.random_shape()
			extension = random_shape.extend()
			self.assertTrue(random_shape <= extension)
			if x % 100 == 0:
				print(x)
Beispiel #4
0
def test_four_circles():
    """Tests the conjecture that at most four must travel the solution"""
    pos = random_shape(4, 0.0, 1.0)
    shp = random_shape(4, 0.0, 1.0)
    shp = regular_shape(4)

    rep, radiuses = replication_spanner_circles(shp, pos[0], pos[1], 0.1)

    ax: plt.Axes
    fig, ax = plt.subplots()
    ax.set_aspect('equal', 'box')
    ax.scatter(*zip(*pos), color='black')
    ax.scatter(*zip(*rep), color='blue')

    patches = [plt.Circle(c, radius) for c, radius in zip(rep[2:], radiuses[2:])]
    ax.add_collection(PatchCollection(patches, alpha=0.4))

    plt.show()
Beispiel #5
0
	def test_equals(self):
		'''This test generates a random shape, creates a random example of it, retraces the example and asserts that the two shapes are equal.'''
		for x in range(0,n):
			random_shape = shapes.random_shape()
			imprint = random_shape.generate()
			imprint_shape = shapes.factory(imprint)
			self.assertEqual(random_shape, imprint_shape)
			if x % 100 == 0:
				print(x)
Beispiel #6
0
def random_positions(plot_radius: bool = False):
    fig: plt.Figure
    ax: plt.Axes
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.25)
    ax.axis('equal')
    
    axslider = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    axbutton = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    bnew = Button(axbutton, 'New')
    num_slider = Slider(axslider, 'Robots', 3, 7, valinit=3, valstep=1)

    # Initalize
    formation = regular_shape(int(num_slider.val))
    positions = random_shape(len(formation))
    target, radius = approximation(positions, formation)

    colors = get_colors(len(formation))
    arr = np.arange(positions.shape[0])
    srcs = ax.scatter(positions[:,0], positions[:,1], marker='o', color=colors)
    dsts = ax.scatter(target[:,0], target[:,1], marker='x', color=colors)

    def get_circles(positions: np.array, radius: float) -> List[plt.Circle]:
        return [plt.Circle(position, radius) for position in positions]

    circles = PatchCollection(get_circles(positions, radius), alpha=0.4)
    circles.set_color(colors)
    ax.add_collection(circles)

    def update(event):
        formation = regular_shape(int(num_slider.val))
        positions = random_shape(len(formation))
        target, radius = approximation(positions, formation)
        srcs.set_offsets(positions)
        dsts.set_offsets(target)
        circles.set_paths(get_circles(positions, radius))

        colors = get_colors(positions.shape[0])
        srcs.set_color(colors)
        dsts.set_color(colors)
        circles.set_color(colors)

        # Set Axis Scale
        points = np.concatenate([positions, target])
        llim, hlim = points.min() - radius, points.max() + radius
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()
        fig.canvas.draw_idle()

    bnew.on_clicked(update)
    num_slider.on_changed(update)

    ax.autoscale_view()
    plt.show()
Beispiel #7
0
    def update(event=None):
        p = random_shape(n, 0.0, 1.0)
        # print('pos:', p)
        scatter_p.set_offsets(p)

        formation = random_shape(n, 0.0, 1.0)

        q_sol = solution(p, formation)
        # print('sol:', np.linalg.norm(p - q_sol, axis=1))
        scatter_sol.set_offsets(q_sol)

        q_opt, _, _ = convex_solution(p, formation)
        r_opt = np.linalg.norm(p - q_opt, axis=1)

        print(f'Ours: {is_similar(q_sol, formation)}')
        print(f'Theirs: {is_similar(q_opt, formation)}')
        # print('opt:', r_opt)

        scatter_opt.set_offsets(q_opt)
        fig.canvas.draw_idle()
Beispiel #8
0
	def test_greater_equals(self):
		for x in range(0,n):
			random_shape = shapes.random_shape()
			reduction = random_shape.shrink()
			try:
				self.assertTrue(random_shape >= reduction)
			except AssertionError:
				print(random_shape, '\n', reduction)
				raise
			if x % 100 == 0:
				print(x)
Beispiel #9
0
def test_assignment():
    import matplotlib.pyplot as plt
    from matplotlib import collections as mc
    for i in range(100):
        T1 = random_shape(3)
        T2 = random_shape(3)

        # Assignment
        T1 = T1[np.argsort(to_angles(T1))]
        T2 = T2[np.argsort(to_angles(T2))]

        target, r1, refl, perm = triangle_solution(T1, T2)

        _target, _r1, _refl = triangle_solution(T1, T2, do_perm=False)

        if not np.isclose(r1, _r1):
            print(f'r1: {r1}, _r1: {_r1}')
            fig: plt.Figure
            ax: plt.Axes
            fig, ax = plt.subplots()
            ax.axis('equal')
            
            colors = np.array(list('rgb'))
            ax.scatter(T1[:,0], T1[:,1], c=colors, marker='o')
            ax.scatter(target[:,0], target[:,1], c=colors[np.argsort(to_angles(target))], marker='x')
            ax.scatter(_target[:,0], _target[:,1], c=colors, marker='.')

            lines = mc.LineCollection(
                [ 
                    *zip(T1.tolist(), np.roll(T1, 1, axis=0).tolist()),
                    *zip(target.tolist(), np.roll(target, 1, axis=0).tolist()),
                    *zip(_target.tolist(), np.roll(_target, 1, axis=0).tolist()),
                ],
                # linewidths=2,
                colors='black'
            )
            ax.add_collection(lines)

            plt.show()
Beispiel #10
0
    def new_positions(val=None):
        nonlocal positions, formation
        positions = random_shape(number)
        formation = regular_shape(number)
        scatter_positions.set_offsets(positions)

        # Set Axis Scale
        points = np.concatenate([positions, formation])
        llim, hlim = points.min() - 1, points.max() + 1
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()

        update()
Beispiel #11
0
    def update(event):
        formation = regular_shape(int(num_slider.val))
        positions = random_shape(len(formation))
        target, radius = approximation(positions, formation)
        srcs.set_offsets(positions)
        dsts.set_offsets(target)
        circles.set_paths(get_circles(positions, radius))

        colors = get_colors(positions.shape[0])
        srcs.set_color(colors)
        dsts.set_color(colors)
        circles.set_color(colors)

        # Set Axis Scale
        points = np.concatenate([positions, target])
        llim, hlim = points.min() - radius, points.max() + radius
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()
        fig.canvas.draw_idle()
Beispiel #12
0
 def new_positions(event):
     nonlocal positions, focuses, target
     positions = random_shape(3)
     target, radius = triangle_solution(positions, formation)
     focus = get_intersect(positions[0], target[0], positions[1], target[1])
     focuses = [focus]
Beispiel #13
0
def test_same_solution(positions: Optional[np.array] = None,
                       formation: Optional[np.array] = None,
                       speed: float = 0.002):
    if positions is None:
        positions = random_shape(3)
        print(positions)
    if formation is None:
        formation = regular_shape(3)

    fig: plt.Figure
    ax: plt.Axes
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.25)
    ax.axis('equal')
    
    axslider = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    axbutton = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    bnew = Button(axbutton, 'New')
    speed_slider = Slider(axslider, 'Speed', 0, 0.05, valinit=speed)

    # Intial computation
    target, radius = triangle_solution(positions, formation)
    directions = (target - positions) / np.linalg.norm(target -
                                                       positions, axis=1)[:, np.newaxis] * speed
    focuses = []
    focus = get_intersect(positions[0], target[0], positions[1], target[1])
    focuses.append(focus)

    # Create scatter plots
    pos_scatter = ax.scatter(positions[:, 0], positions[:, 1], c='red')
    tar_scatter = ax.scatter(target[:, 0], target[:, 1], c='blue')
    foc_scatter = ax.scatter([focus[0]], [focus[1]], c='green')

    def init():
        ax.set_xlim(-2, 2)
        ax.set_ylim(-2, 2)
        return pos_scatter, tar_scatter, foc_scatter

    def new_positions(event):
        nonlocal positions, focuses, target
        positions = random_shape(3)
        target, radius = triangle_solution(positions, formation)
        focus = get_intersect(positions[0], target[0], positions[1], target[1])
        focuses = [focus]

    bnew.on_clicked(new_positions)

    def new_speed(event):
        nonlocal speed, directions
        speed = speed_slider.val
        directions = np.linalg.norm(directions, axis=0) * speed


    speed_slider.on_changed(new_speed)

    def update(frame):  # Gets called for every frame in animation
        nonlocal target, positions, directions, speed
        _target, _ = triangle_solution(positions, formation)

        # switch direction only when a new target is found
        if not np.allclose(_target, target):
            target = _target
            directions = (target - positions) / np.linalg.norm(target - positions, axis=1)[:, np.newaxis] * speed

            focus = get_intersect(positions[0], target[0], positions[1], target[1])
            # foc_scatter.set_offsets([focus])
            focuses.append(focus)
            foc_scatter.set_offsets(focuses)

        positions += directions
        pos_scatter.set_offsets(positions)
        tar_scatter.set_offsets(target)

        return pos_scatter, tar_scatter, foc_scatter

    ani = FuncAnimation(fig, update, frames=None,
                        init_func=init, blit=True, repeat=False, interval=1, cache_frame_data=False)
    plt.show()
Beispiel #14
0
def test_replications(
        formation: Optional[np.array] = None,
        radius_range: Tuple[float, float] = (0.0, 0.5)) -> None:
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.3)
    ax.axis('equal')

    number = 3
    positions = random_shape(number)
    if not formation:
        formation = regular_shape(number)


    init_radius = radius_range[1]
    ax_radius = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    ax_button = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    ax_number = plt.axes([0.25, 0.2, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    num_slider = Slider(ax_number, 'Robots', 3, 7, valinit=3, valstep=1)
    s_radius = Slider(ax_radius, 'Radius', *radius_range, valinit=init_radius)
    b_random = Button(ax_button, 'New')
    scatter_positions = ax.scatter(x=positions[:, 0], y=positions[:, 1], color='black')


    def get_shapes(radius):
        c_positions = list(combinations(range(len(positions)), 2))
        c_formations = list(combinations(range(len(formation)), 2))
        combs = list(product(c_positions, c_formations))
        patches = []
        colors = get_colors(len(combs))
        for color, ((i_pos1, i_pos2), (i_for1, i_for2) )in zip(colors, combs):
            repl, radiuses = replication_spanner_circles(
                formation,
                positions[i_pos1], positions[i_pos2],
                radius,
                *sorted([i_for1, i_for2])
            )

            patches.append(plt.Polygon(repl, color=color, fill=False))
            for i, _radius in enumerate(radiuses):
                # if i in (i_pos1, i_pos2):
                #     continue
                patches.append(plt.Circle(repl[i], _radius, color=color, fill=False))

        for position in positions:
            patches.append(plt.Circle(position, radius, color='black', fill=False))

        return patches

    collection = PatchCollection(get_shapes(init_radius), match_original=True)
    ax.add_collection(collection)

    def update(val=None):
        collection.set_paths(get_shapes(s_radius.val))
        # collection.set_edgecolor(get_colors(len(positions) * (len(positions) - 1)))
        # collection.set_array(np.array(list(range(len(positions)))))
        
        fig.canvas.draw_idle()

    def new_positions(val=None):
        nonlocal positions, formation
        positions = random_shape(number)
        formation = regular_shape(number)
        scatter_positions.set_offsets(positions)

        # Set Axis Scale
        points = np.concatenate([positions, formation])
        llim, hlim = points.min() - 1, points.max() + 1
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()

        update()

    def update_number(val=None):
        nonlocal number
        number = int(num_slider.val)
        new_positions()

    s_radius.on_changed(update)
    b_random.on_clicked(new_positions)
    num_slider.on_changed(update_number)

    ax.autoscale_view()
    plt.show()