Пример #1
0
    def test_neighbourhood(self):
        adjacency_matrix = [[1., .9, 0., 0., 1.], [1., 1., 1., 0., 0.],
                            [0., 1., 1., 1., 0.], [0., 0., 1., 1., 1.],
                            [1., 0., 0., 1., .8]]

        initial_conditions = [2., 3., 4., 5., 6.]

        def evaluate_neighbourhoods(ctx):
            c = ctx.node_index
            if c == 0:
                np.testing.assert_equal([2., 3., 6.], ctx.activities)
                np.testing.assert_equal([0, 1, 4], ctx.neighbour_indices)
                np.testing.assert_equal([1., 1., 1.], ctx.weights)
            elif c == 1:
                np.testing.assert_equal([2., 3., 4.], ctx.activities)
                np.testing.assert_equal([0, 1, 2], ctx.neighbour_indices)
                np.testing.assert_equal([.9, 1., 1.], ctx.weights)
            elif c == 2:
                np.testing.assert_equal([3., 4., 5.], ctx.activities)
                np.testing.assert_equal([1, 2, 3], ctx.neighbour_indices)
                np.testing.assert_equal([1., 1., 1.], ctx.weights)
            elif c == 3:
                np.testing.assert_equal([4., 5., 6.], ctx.activities)
                np.testing.assert_equal([2, 3, 4], ctx.neighbour_indices)
                np.testing.assert_equal([1., 1., 1.], ctx.weights)
            elif c == 4:
                np.testing.assert_equal([2., 5., 6.], ctx.activities)
                np.testing.assert_equal([0, 3, 4], ctx.neighbour_indices)
                np.testing.assert_equal([1., 1., .8], ctx.weights)

        ntm.evolve(initial_conditions,
                   adjacency_matrix,
                   timesteps=2,
                   activity_rule=evaluate_neighbourhoods)
Пример #2
0
    def test_evolution(self):
        points = [(0, 1), (0.23, 0.5), (0.6, 0.77), (0.33, 0.88)]
        A, B, C, D, n, dt, timesteps = 120, 120, 40, 120, 5, 1e-05, 1000
        tsp_net = HopfieldTankTSPNet(points, dt=dt, A=A, B=B, C=C, D=D, n=n)

        initial_conditions = [-0.022395203920575254, -0.023184407969001723, -0.022224769264670836,
                              -0.022411201286076467, -0.02308227809621827, -0.023463757363683353,
                              -0.0222625041883513, -0.0228662974775357, -0.023547421145956916,
                              -0.02142219621197953, -0.022375730795237334, -0.022534578294732176,
                              -0.021526161923257372, -0.02003505371915011, -0.023113647911417328,
                              -0.023001396844357286]

        activities, _ = evolve(initial_conditions, tsp_net.adjacency_matrix, tsp_net.activity_rule,
                               timesteps=timesteps, parallel=True)

        permutation_matrix = tsp_net.get_permutation_matrix(activities)

        expected_permutation_matrix = [[4.81578032e-08, 0.0, 0.0, 0.0],
                                       [0.0, 0.0, 0.0, 1.0],
                                       [0.0, 0.0, 7.50011973e-01, 0.0],
                                       [0.0, 1.0, 0.0, 0.0]]
        np.testing.assert_almost_equal(expected_permutation_matrix, permutation_matrix)

        _, _, tour_length = tsp_net.get_tour_graph(points, permutation_matrix)
        self.assertEqual(1.6510914079204857, tour_length)
Пример #3
0
    def test_past_activities_multiple_past(self):
        adjacency_matrix = [[1, 1], [1, 1]]

        initial_conditions = [1, 1]

        past_conditions = [[-1, -1], [0, 0]]

        def activity_rule(ctx):
            p = ctx.past_activities
            t = ctx.timestep
            if t == 1:
                self.assertEqual(p, [[-1, -1], [0, 0]])
            if t == 2:
                self.assertEqual(p, [[0, 0], [1, 1]])
            if t == 3:
                self.assertEqual(p, [[1, 1], [2, 2]])
            return ctx.current_activity + 1

        activities, _ = ntm.evolve(initial_conditions,
                                   adjacency_matrix,
                                   activity_rule,
                                   timesteps=4,
                                   past_conditions=past_conditions)

        np.testing.assert_equal(activities, [[1, 1], [2, 2], [3, 3], [4, 4]])
Пример #4
0
 def test_sequential_left_to_right(self):
     expected = self._convert_to_matrix("rule60_sequential_simple_init.ca")
     adjacency_matrix = adjacency.cellular_automaton(n=21)
     initial_conditions = [0]*10 + [1] + [0]*10
     r = AsynchronousRule(activity_rule=lambda ctx: rules.nks_ca_rule(ctx, 60), update_order=range(1, 20))
     activities, adjacencies = evolve(initial_conditions, adjacency_matrix, timesteps=19*20,
                                      activity_rule=r.activity_rule)
     np.testing.assert_equal(expected, activities[::19])
Пример #5
0
 def test_sequential_random(self):
     expected = self._convert_to_matrix("rule90_sequential_simple_init.ca")
     adjacency_matrix = adjacency.cellular_automaton(n=21)
     initial_conditions = [0]*10 + [1] + [0]*10
     update_order = [19, 11, 4, 9, 6, 16, 10, 2, 17, 1, 12, 15, 5, 3, 8, 18, 7, 13, 14]
     r = AsynchronousRule(activity_rule=lambda ctx: rules.nks_ca_rule(ctx, 90), update_order=update_order)
     activities, adjacencies = evolve(initial_conditions, adjacency_matrix, timesteps=19*20,
                                      activity_rule=r.activity_rule)
     np.testing.assert_equal(expected, activities[::19])
Пример #6
0
    def test_fsm(self):

        states = {'locked': 0, 'unlocked': 1}
        transitions = {'PUSH': 'p', 'COIN': 'c'}

        adjacency_matrix = [[1]]

        initial_conditions = [states['locked']]

        events = "cpcpp"

        def fsm_rule(ctx):
            if ctx.input == transitions['PUSH']:
                return states['locked']
            else:
                # COIN event
                return states['unlocked']

        activities, _ = ntm.evolve(initial_conditions, adjacency_matrix, input=events, activity_rule=fsm_rule)

        np.testing.assert_equal([[0], [1], [0], [1], [0], [0]], activities)
import netomaton as ntm
import numpy as np


if __name__ == '__main__':
    """
    This demo is inspired by "Collective dynamics of ‘small-world’ networks", by Duncan J. Watts and 
    Steven H. Strogatz (Nature 393, no. 6684 (1998): 440). Towards the end of the paper, they state: 
    "For cellular automata charged with the computational task of density classification, we find that a simple 
    ‘majority-rule’ running on a small-world graph can outperform all known human and genetic algorithm-generated rules 
    running on a ring lattice." The code below attempts to reproduce the experiment they are referring to.
    """

    adjacency_matrix = ntm.network.watts_strogatz_graph(n=149, k=8, p=0.5)

    initial_conditions = np.random.randint(0, 2, 149)

    print("density of 1s: %s" % (np.count_nonzero(initial_conditions) / 149))

    activities, adjacencies = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=149,
                                         activity_rule=lambda ctx: ntm.rules.majority_rule(ctx))

    ntm.plot_grid(activities)
import netomaton as ntm

if __name__ == '__main__':
    rule_table, actual_lambda, quiescent_state = ntm.random_rule_table(lambda_val=0.0, k=4, r=2,
                                                                       strong_quiescence=True, isotropic=True)

    lambda_vals = [0.15, 0.37, 0.75]
    ca_list = []
    titles = []
    for i in range(0, 3):
        adjacency_matrix = ntm.network.cellular_automaton(n=128, r=2)

        initial_conditions = ntm.init_random(128, k=4)

        rule_table, actual_lambda = ntm.table_walk_through(rule_table, lambda_vals[i], k=4, r=2,
                                                           quiescent_state=quiescent_state, strong_quiescence=True)
        print(actual_lambda)

        # evolve the cellular automaton for 200 time steps
        activities, _ = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=200,
                                   activity_rule=lambda ctx: ntm.table_rule(ctx, rule_table))

        ca_list.append(activities)
        avg_node_entropy = ntm.average_node_entropy(activities)
        avg_mutual_information = ntm.average_mutual_information(activities)
        titles.append(r'$\lambda$ = %s, $\widebar{H}$ = %s, $\widebar{I}$ = %s' %
                      (lambda_vals[i], "{:.4}".format(avg_node_entropy), "{:.4}".format(avg_mutual_information)))

    ntm.plot_grid_multiple(ca_list, titles=titles)
Пример #9
0
    # NKS page 443 - Rule 122R
    adjacency_matrix = ntm.network.cellular_automaton(n=100)

    # carefully chosen initial conditions
    previous_state = [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1,
                      0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0,
                      1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1,
                      0, 0, 1, 1]
    initial_conditions = [1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
                          0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
                          1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
                          1, 1, 1, 0, 1, 1, 1]

    r = ntm.ReversibleRule(lambda ctx: ntm.rules.nks_ca_rule(ctx, 122))
    activities, _ = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=1002, activity_rule=r.activity_rule,
                               past_conditions=[previous_state])

    timestep = []
    average_node_entropies = []

    for i, c in enumerate(activities):
        timestep.append(i)
        bit_string = ''.join([str(x) for x in c])
        average_node_entropies.append(ntm.average_node_entropy(activities[:i+1]))
        print("%s, %s" % (i, average_node_entropies[-1]))

    plt.subplot(3, 1, (1, 2))
    plt.title("Avg. Node (Shannon) Entropy")
    plt.gca().set_xlim(0, 1002)
    plt.gca().axes.xaxis.set_ticks([])
    plt.plot(timestep, average_node_entropies)
Пример #10
0
import netomaton as ntm

if __name__ == '__main__':
    adjacency_matrix = ntm.network.cellular_automaton2d(
        rows=60, cols=60, r=1, neighbourhood='von Neumann')
    initial_conditions = ntm.init_simple2d(60, 60)
    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=30,
        activity_rule=lambda ctx: ntm.rules.totalistic_ca(ctx, k=2, rule=26))
    # the evolution of a 2D cellular automaton can be animated
    ntm.animate(activities, shape=(60, 60), interval=150)

    adjacency_matrix = ntm.network.cellular_automaton(n=200)
    initial_conditions = [0] * 100 + [1] + [0] * 99
    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=100,
        activity_rule=lambda ctx: ntm.rules.nks_ca_rule(ctx, 30))
    # the evolution of a 1D cellular automaton can be animated
    ntm.animate(activities, shape=(200, ))

    adjacency_matrix = ntm.network.cellular_automaton(n=225)
    initial_conditions = [0] * 112 + [1] + [0] * 112
    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=100,
        activity_rule=lambda ctx: ntm.rules.nks_ca_rule(ctx, 30))
    A, B, C, D, n, dt, timesteps = 300, 300, 100, 300, 12, 1e-05, 1000  # avg. 2.9605078829924527, 70% convergence
    # A, B, C, D, n, dt, timesteps = 400, 400, 150, 400, 12, 1e-05, 1000  # avg. 3.1818680173024543, 80% convergence
    # A, B, C, D, n, dt, timesteps = 500, 500, 150, 300, 12, 1e-05, 1000  # avg. 3.4807220504123797, 100% convergence

    tsp_net = ntm.HopfieldTankTSPNet(points, dt=dt, A=A, B=B, C=C, D=D, n=n)

    adjacency_matrix = tsp_net.adjacency_matrix

    # -0.022 was chosen so that the sum of V for all nodes is 10; some noise is added to break the symmetry
    initial_conditions = [
        -0.022 + np.random.uniform(-0.1 * 0.02, 0.1 * 0.02)
        for _ in range(len(adjacency_matrix))
    ]

    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               tsp_net.activity_rule,
                               timesteps=timesteps,
                               parallel=True)

    ntm.animate(activities, shape=(10, 10))

    permutation_matrix = tsp_net.get_permutation_matrix(activities)
    print(permutation_matrix)

    G, pos, length = tsp_net.get_tour_graph(points, permutation_matrix)

    print(length)

    tsp_net.plot_tour(G, pos)
Пример #12
0
import matplotlib.pyplot as plt
import netomaton as ntm
import numpy as np


if __name__ == '__main__':

    # NKS page 442 - Rule 122R
    adjacency_matrix = ntm.network.cellular_automaton(n=100)
    initial_conditions = [0]*40 + [1]*20 + [0]*40
    r = ntm.ReversibleRule(lambda ctx: ntm.rules.nks_ca_rule(ctx, 122))
    activities, _ = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=1000, activity_rule=r.activity_rule,
                               past_conditions=[initial_conditions])

    timestep = []
    average_node_entropies = []

    for i, c in enumerate(activities):
        timestep.append(i)
        bit_string = ''.join([str(x) for x in c])
        average_node_entropies.append(ntm.average_node_entropy(activities[:i+1]))
        print("%s, %s" % (i, average_node_entropies[-1]))

    plt.subplot(3, 1, (1, 2))
    plt.title("Avg. Node (Shannon) Entropy")
    plt.gca().set_xlim(0, 1000)
    plt.gca().axes.xaxis.set_ticks([])
    plt.plot(timestep, average_node_entropies)

    plt.subplot(3, 1, 3)
    plt.gca().axes.yaxis.set_ticks([])
Пример #13
0
    # Light Weight Space Ship (LWSS)
    initial_conditions[1125] = 1
    initial_conditions[1128] = 1
    initial_conditions[1184] = 1
    initial_conditions[1244] = 1
    initial_conditions[1248] = 1
    initial_conditions[1304] = 1
    initial_conditions[1305] = 1
    initial_conditions[1306] = 1
    initial_conditions[1307] = 1

    # Glider
    initial_conditions[1710] = 1
    initial_conditions[1771] = 1
    initial_conditions[1829] = 1
    initial_conditions[1830] = 1
    initial_conditions[1831] = 1

    # Blinker
    initial_conditions[2415] = 1
    initial_conditions[2416] = 1
    initial_conditions[2417] = 1

    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=60,
        activity_rule=lambda ctx: ntm.rules.game_of_life_rule(ctx))

    ntm.animate(activities, shape=(60, 60))
Пример #14
0
import netomaton as ntm

if __name__ == '__main__':
    adjacency_matrix = ntm.network.cellular_automaton2d(60,
                                                        60,
                                                        r=1,
                                                        neighbourhood="Hex")

    initial_conditions = ntm.init_simple2d(60, 60)

    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=31,
        activity_rule=lambda ctx: 1
        if sum(ctx.activities) == 1 else ctx.current_activity)

    ntm.animate_hex(activities, shape=(60, 60), interval=150)
import math
import netomaton as ntm


if __name__ == '__main__':

    adjacency_matrix = ntm.network.cellular_automaton(n=200)

    initial_conditions = [0.0]*100 + [1.0] + [0.0]*99

    # NKS page 157
    def activity_rule(ctx):
        activities = ctx.activities
        result = (sum(activities) / len(activities)) * (3 / 2)
        frac, whole = math.modf(result)
        return frac

    activities, adjacencies = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=150,
                                         activity_rule=activity_rule)

    ntm.plot_grid(activities)
import netomaton as ntm
import numpy as np

if __name__ == '__main__':
    # set r to 3, for a neighbourhood size of 7
    adjacency_matrix = ntm.network.cellular_automaton(149, r=3)

    initial_conditions = np.random.randint(0, 2, 149)

    # Mitchell et al. discovered this rule using a Genetic Algorithm
    rule_number = 6667021275756174439087127638698866559

    print("density of 1s: %s" % (np.count_nonzero(initial_conditions) / 149))

    activities, adjacencies = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=149,
        activity_rule=lambda ctx: ntm.rules.binary_ca_rule(ctx, rule_number))

    ntm.plot_grid(activities)
Пример #17
0
import netomaton as ntm
import numpy as np


if __name__ == '__main__':

    sandpile = ntm.Sandpile(rows=60, cols=60)

    initial_conditions = np.random.randint(5, size=3600)

    def perturb(pctx):
        # drop a grain on some node at the 85th timestep
        if pctx.timestep == 85 and pctx.node_index == 1034:
            return pctx.node_activity + 1
        return pctx.node_activity

    activities, _ = ntm.evolve(initial_conditions, sandpile.adjacency_matrix, timesteps=110,
                               activity_rule=sandpile.activity_rule, perturbation=perturb)

    ntm.animate(activities, shape=(60, 60), interval=150)
Пример #18
0
    # If a coin is given in the Locked state, it transitions to Unlocked.
    # If a push is given in the Unlocked state, it transitions to Locked.
    # If a coin is given in the Unlocked state, it remains Unlocked.

    states = {'locked': 0, 'unlocked': 1}
    transitions = {'PUSH': 'p', 'COIN': 'c'}

    # a FSM can be thought of as a Network Automaton with a single node
    adjacency_matrix = [[1]]

    # the FSM starts off in the Locked state
    initial_conditions = [states['locked']]

    events = "cpcpp"

    def fsm_rule(ctx):
        if ctx.input == transitions['PUSH']:
            return states['locked']
        else:
            # COIN event
            return states['unlocked']

    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               input=events,
                               activity_rule=fsm_rule)

    print("final state: %s" % activities[-1][0])

    ntm.plot_grid(activities)
Пример #19
0
import netomaton as ntm

if __name__ == '__main__':
    adjacency_matrix = ntm.network.cellular_automaton(n=200)

    initial_conditions = ntm.init_random(200)

    activities, _ = ntm.evolve(
        initial_conditions,
        adjacency_matrix,
        timesteps=1000,
        activity_rule=lambda ctx: ntm.rules.nks_ca_rule(ctx, 30))

    # calculate the average node entropy; the value will be ~0.999 in this case
    avg_node_entropy = ntm.average_node_entropy(activities)

    print(avg_node_entropy)
Пример #20
0
import netomaton as ntm


if __name__ == '__main__':

    adjacency_matrix = ntm.network.cellular_automaton(n=200)

    initial_conditions = [0]*100 + [1] + [0]*99

    activities, adjacencies = ntm.evolve(initial_conditions, adjacency_matrix, timesteps=100,
                                         activity_rule=lambda ctx: ntm.rules.totalistic_ca(ctx, k=3, rule=777))

    ntm.plot_grid(activities)
Пример #21
0
        0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0
    ]
    half_one = [
        0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0
    ]
    half_two = [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0,
        0, 1, 1, 1, 1, 1
    ]
    half_zero = [-1 if x == 0 else x for x in half_zero]
    half_one = [-1 if x == 0 else x for x in half_one]
    half_two = [-1 if x == 0 else x for x in half_two]

    initial_conditions = half_two

    activities, adjacencies = ntm.evolve(
        initial_conditions,
        hopfield_net.adjacency_matrix,
        timesteps=hopfield_net.num_nodes * 7,
        activity_rule=hopfield_net.activity_rule)

    # view the weights, stored in the adjacency matrix
    # plot_grid(hopfield_net.adjacency_matrix)

    # view the time evolution of the Hopfield net as it completes the given pattern
    ntm.animate(activities[::hopfield_net.num_nodes],
                shape=(6, 5),
                interval=150)
Пример #22
0
        ]
        neighbourhood_v = [
            ctx.activities[i][1] for i, idx in enumerate(ctx.neighbour_indices)
            if idx != ctx.node_index
        ]

        diffusion_u = sum(neighbourhood_u) - (4 * prev_u)
        diffusion_v = sum(neighbourhood_v) - (4 * prev_v)

        inter_u = (-prev_u * prev_v**2) + f * (1 - prev_u)
        inter_v = (prev_u * prev_v**2) - (k) * prev_v

        new_u = prev_u + (r_u * diffusion_u) + inter_u
        new_v = prev_v + (r_v * diffusion_v) + inter_v

        return new_u, new_v

    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               timesteps=3000,
                               activity_rule=react_diffuse)

    # we want to visualize the concentrations of U only
    activities = [[j[0] for j in i] for i in activities]

    ntm.animate(activities,
                shape=(100, 100),
                colormap='RdYlBu',
                vmin=0.2,
                interval=25)
Пример #23
0
    def noisy_rule_90(ctx):
        """
        This rule implements the continuous cellular automaton with generalization of Rule 90, described on
        pages 325 and 976 of Stephen Wolfram's "A New Kind of Science".
        """
        x = ctx.activities[0] + ctx.activities[2]
        # λ[x_] := Exp[-10 (x - 1)^2] + Exp[-10 (x - 3)^2]
        result = np.exp(-10 * ((x - 1)**2)) + np.exp(-10 * ((x - 3)**2))

        return result

    def noisy_rule_30(ctx):
        """
        This rule implements the continuous cellular automaton with generalization of Rule 30, described on
        pages 325 and 976 of Stephen Wolfram's "A New Kind of Science".
        """
        x = ctx.activities[0] + ctx.activities[1] + ctx.activities[2] + (
            ctx.activities[1] * ctx.activities[2])
        # λ[x_] := Exp[-10 (x - 1)^2] + Exp[-10 (x - 3)^2]
        result = np.exp(-10 * ((x - 1)**2)) + np.exp(-10 * ((x - 3)**2))

        return result

    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               timesteps=100,
                               activity_rule=noisy_rule_30,
                               perturbation=perturbation)

    ntm.plot_grid(activities)
Пример #24
0
        HEAD['q6']: {
            CELL[' ']: [HEAD['q6'], CELL[' '], TuringMachine.STAY],
            CELL['a']: [HEAD['q6'], CELL['a'], TuringMachine.STAY],
            CELL['b']: [HEAD['q6'], CELL['b'], TuringMachine.STAY],
            CELL['c']: [HEAD['q6'], CELL['c'], TuringMachine.STAY],
            CELL['x']: [HEAD['q6'], CELL['x'], TuringMachine.STAY],
            CELL['y']: [HEAD['q6'], CELL['y'], TuringMachine.STAY],
            CELL['z']: [HEAD['q6'], CELL['z'], TuringMachine.STAY]
        }
    }

    tape = "  aabbcc  "

    tm = HeadCentricTuringMachine(tape=[CELL[t] for t in tape],
                                  rule_table=rule_table,
                                  initial_head_state=HEAD['q0'],
                                  initial_head_position=2,
                                  terminating_state=HEAD['q6'],
                                  max_timesteps=50)

    activities, _ = ntm.evolve(tm.initial_conditions,
                               tm.adjacency_matrix,
                               activity_rule=tm.activity_rule,
                               input=tm.input_function)

    tape_history, head_activities = tm.activities_for_plotting(activities)

    ntm.plot_grid(tape_history,
                  node_annotations=head_activities,
                  show_grid=True)
Пример #25
0
            CELL['d']: [HEAD['down'], CELL['e'], TuringMachine.RIGHT],
            CELL['e']: [HEAD['down'], CELL['c'], TuringMachine.LEFT]
        }
    }

    tape = "bbbbbbaeaaaaaaa"

    tm = TapeCentricTuringMachine(n=len(tape),
                                  rule_table=rule_table,
                                  initial_head_state=HEAD['up'],
                                  initial_head_position=8)

    initial_conditions = [CELL[t] for t in tape]

    activities, _ = ntm.evolve(initial_conditions,
                               tm.adjacency_matrix,
                               activity_rule=tm.activity_rule,
                               timesteps=58)

    ntm.plot_grid(activities,
                  node_annotations=tm.head_activities(activities),
                  show_grid=True)

    # The following is a longer evolution, to show that ECA Rule 110 is emulated;
    #  it will start when the plot rendered above is closed.

    tape = "b" * 50 + "ae" + "a" * 51

    initial_conditions = [CELL[t] for t in tape]

    tm = TapeCentricTuringMachine(n=len(tape),
                                  rule_table=rule_table,
Пример #26
0
    
    Each of the 120 nodes represents a body that can contain some amount of heat. Reproduces the plot at the top of 
    Wolfram's NKS, page 163. 
    
    See: https://www.wolframscience.com/nks/p163--partial-differential-equations/
    See: http://hplgit.github.io/num-methods-for-PDEs/doc/pub/diffu/sphinx/._main_diffu001.html
    """

    space = np.linspace(25, -25, 120)
    initial_conditions = [np.exp(-x**2) for x in space]

    adjacency_matrix = ntm.network.cellular_automaton(120)

    a = 0.25
    dt = .5
    dx = .5
    F = a * dt / dx**2

    def activity_rule(ctx):
        current = ctx.current_activity
        left = ctx.activities[0]
        right = ctx.activities[2]
        return current + F * (right - 2 * current + left)

    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               activity_rule,
                               timesteps=75)

    ntm.plot_grid(activities)
Пример #27
0
import netomaton as ntm

if __name__ == '__main__':

    # NKS page 437 - Rule 214R

    adjacency_matrix = ntm.network.cellular_automaton(n=63)

    # run the CA forward for 32 steps to get the initial condition for the next evolution
    initial_conditions = [0] * 31 + [1] + [0] * 31
    r = ntm.ReversibleRule(lambda ctx: ntm.rules.nks_ca_rule(ctx, 214))
    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               timesteps=32,
                               activity_rule=r.activity_rule,
                               past_conditions=[initial_conditions])

    # use the last state of the CA as the initial, previous state for this evolution
    r = ntm.ReversibleRule(lambda ctx: ntm.rules.nks_ca_rule(ctx, 214))
    initial_conditions = activities[-2]
    activities, _ = ntm.evolve(initial_conditions,
                               adjacency_matrix,
                               timesteps=62,
                               activity_rule=r.activity_rule,
                               past_conditions=[activities[-1]])

    ntm.plot_grid(activities)