Cellular automata

There are several

In this section we run some of the cellular automata rules from the book using Python code. Download the code and run it yourself to investigate how these models work.

The domino rule

In Santa Fe, Chris describes the domino rule as follows.

../../_images/Domino.png

We start by writing code to apply the rule to a binary string.

def apply_domino(string):

    # Convert the strong to cells
    cells=list(map(int, [*string]))
    new_cells=cells.copy()
    N=len(cells)

    # Loop over every cell and update its state based on the neighboring cells
    for j in range(N):
        # Get the neighbors left, above and right.
        # The %N is to take mod, to deal with the edge cases
        left = cells[(j-1)%N]
        above = cells[j]
        right= cells[(j+1)%N]


        # If the cell to the left is a 1 then the cell becomes a 1
        # Otherwise it remains the same.
        if left==1:
            new_cells[j] = 1
        else:
            new_cells[j]=cells[j]

    # Convert back to a new string
    string=''.join([str(item) for item in new_cells])

    return string

Let’s now apply the rule

string='11101100001111000011111111101'
print('Before applying rule: ' + string)
string=apply_domino(string)
print('After applying rule : ' + string)
Before applying rule: 11101100001111000011111111101
After applying rule : 11111110001111100011111111111

We can repeadtedly apply it as follows:

steps = 5
string='11101100001111000011111111101'

for i in range(steps):
    print('Time step %d:'%i + string)
    string=apply_domino(string)


# .. admonition:: Think yourself!
#
#       Look at a starting string with all zeros, apart from one one. Run the
#       cellular automata for enough steps so that all the zeros turn to one.
#       Notice how the domino rally travels from one side to the other.
Time step 0:11101100001111000011111111101
Time step 1:11111110001111100011111111111
Time step 2:11111111001111110011111111111
Time step 3:11111111101111111011111111111
Time step 4:11111111111111111111111111111

The politics rule

Chris goes on to describe a new set of the following three rules.

../../_images/Politics.png

Let’s implement these in Python

def apply_political(string):

    # Convert the strong to cells
    cells=list(map(int, [*string]))
    new_cells=cells.copy()
    N=len(cells)

    # Loop over every cell and update its state based on the neighboring cells
    for j in range(N):
        # Get the neighbors left, above and right.
        # The %N is to take mod, to deal with the edge cases
        left = cells[(j-1)%N]
        above = cells[j]
        right= cells[(j+1)%N]

        # If the cell to the left is a 1 then the cell becomes a 1
        # Otherwise it remains the same.
        if ((left==0) & (right==0)):
            new_cells[j] = 0
        elif ((left==1) & (right==1)):
            new_cells[j] = 1
        else:
            new_cells[j]=cells[j]

    # Convert back to a new string
    string=''.join([str(item) for item in new_cells])

    return string

Let’s now apply the rule

string='0100011011110101011010'
print('Before applying rule: ' + string)
string=apply_political(string)
print('After applying rule : ' + string)
Before applying rule: 0100011011110101011010
After applying rule : 0000011111111010111100

We can repeadtedly apply the rule as follows:

steps = 5
string='0100011011110101011010'

for i in range(steps):
    print('Time step %d:'%i + string)
    string=apply_political(string)

# All the isolated 0's or 1's are replaced
# by their majority neighbours (we assume that the bits form a loop, so
# the 1 on the end of the string has neighbour 0 to its left and adopts its
# right neighbour as the 0 at the start of the string and thus becomes a 0).
Time step 0:0100011011110101011010
Time step 1:0000011111111010111100
Time step 2:0000011111111101111100
Time step 3:0000011111111111111100
Time step 4:0000011111111111111100

The alternate rule

In the book, Esther and I find rules which create alternating lines like these.

../../_images/TransitionAlternate.png

Let’s implement these rules in Python.

def apply_alternate(string):

    # Convert the strong to cells
    cells=list(map(int, [*string]))
    new_cells=cells.copy()
    N=len(cells)

    # Loop over every cell and update its state based on the neighboring cells
    for j in range(N):
        # Get the previous value

        above = cells[j]

        # Switch the value of the cell on every time step
        if (above==1):
            new_cells[j] = 0
        else:
            new_cells[j] = 1

    # Convert back to a new string
    string=''.join([str(item) for item in new_cells])

    return string

We can repeadtedly apply the rule as follows:

steps = 20
string='01110111001100110110'


for i in range(steps):
    print(string)
    string=apply_alternate(string)
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001
01110111001100110110
10001000110011001001

The checquerboard rule

Esther and I also found a rule which makes the following pattern.

../../_images/TransitionCheck.png

Let’s look at a Python implementation.

def apply_checquerboard(string):

    # Convert the strong to cells
    cells=list(map(int, [*string]))
    new_cells=cells.copy()
    N=len(cells)

    # Loop over every cell and update its state based on the neighboring cells
    for j in range(N):
        # Get the previous value

        left = cells[(j-1)%N]
        above = cells[j]
        right= cells[(j+1)%N]

        # Switch the value of the cell on every time step
        if (above==1):
            if ((left==1) & (right==1)):
                new_cells[j] = 1
            else:
                new_cells[j] = 0
        else:
            if ((left==0) & (right==0)):
                new_cells[j] = 0
            else:
                new_cells[j] = 1


    # Convert back to a new string
    string=''.join([str(item) for item in new_cells])

    return string

We can repeadtedly apply the rule as follows:

steps = 20
string='10000001110000000011'

for i in range(steps):
    print(string)
    string=apply_checquerboard(string)
10000001110000000011
01000010101000000101
10100101010100001010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101
10100101010101101010
01011010101010010101

We will look again at these last two rules in the section on cellular chaos where we implement a model which takes a set of rules as input and produces a cellular automata as output.

Total running time of the script: (0 minutes 0.005 seconds)

Gallery generated by Sphinx-Gallery