Skip to content

Commit

Permalink
added asserts, model descriptions, MEM.R done
Browse files Browse the repository at this point in the history
  • Loading branch information
surabhinath committed Jun 15, 2023
1 parent c065592 commit 87db174
Show file tree
Hide file tree
Showing 23 changed files with 154 additions and 145 deletions.
15 changes: 11 additions & 4 deletions measures/Kolmogorov complexity/calculate_Kolmogorov_complexity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import sys
from pybdm import BDM

"""
This module implements the Kolmogorov complexity measure. Refer to Section 2.2 (4) for details.
"""

def calculate_Kolmogorov_complexity(pattern, grid_size):
"""
This function calculates the approximate Kolmogorov Complexity of a pattern using Block Decomposition Method.
Expand All @@ -24,19 +28,22 @@ def calculate_Kolmogorov_complexity(pattern, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_Kolmogorov_complexity(all_black, grid_size) == 25.176631293734488
print(calculate_Kolmogorov_complexity(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_Kolmogorov_complexity(grid_with_one_centre, grid_size) == 48.354642249885316
print(calculate_Kolmogorov_complexity(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_Kolmogorov_complexity(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_Kolmogorov_complexity(checkerboard, grid_size) == 33.43569202047461
print(calculate_Kolmogorov_complexity(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_Kolmogorov_complexity(random, grid_size))
17 changes: 12 additions & 5 deletions measures/asymmetry/calculate_asymmetry.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
author = 'Surabhi S Nath'
import numpy as np

'''
This module implememts the asymmetry measure. Refer to Section 2.2 (6) and AII for details.
'''

def get_coords(grid):
"""
This function returns the indices and count of black pixels in the pattern
Expand Down Expand Up @@ -67,19 +71,22 @@ def calculate_asymmetry(grid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size)
assert calculate_asymmetry(all_black, grid_size) == (0.0, 0.0)
print(calculate_asymmetry(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_asymmetry(grid_with_one_centre, grid_size) == (0.0, 0.0)
print(calculate_asymmetry(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size)
checkarboard[1::2] = 1
print(calculate_asymmetry(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size)
checkerboard[1::2] = 1
assert calculate_asymmetry(checkerboard, grid_size) == (0.0, 0.0)
print(calculate_asymmetry(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_asymmetry(random, grid_size))
15 changes: 11 additions & 4 deletions measures/density/calculate_density.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
author = 'Surabhi S Nath'
import numpy as np

"""
This module implements the density measure. Refer to Section 2.2 (1) and AII for details.
"""

def calculate_density(grid, grid_size):
"""
This function caclulates the density of black pixels in a pattern
Expand All @@ -19,19 +23,22 @@ def calculate_density(grid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size)
assert calculate_density(all_black, grid_size) == 1.0
print(calculate_density(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_density(grid_with_one_centre, grid_size) == 0.0044444444444444444
print(calculate_density(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size)
checkarboard[1::2] = 1
print(calculate_density(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size)
checkerboard[1::2] = 1
assert calculate_density(checkerboard, grid_size) == 0.49777777777777776
print(calculate_density(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_density(random, grid_size))
15 changes: 11 additions & 4 deletions measures/entropy/calculate_entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import numpy as np
import math

"""
This module implements the entropy measure. Refer to Section 2.2 (2i) and AII for details.
"""

def calculate_entropy(gridorflatgrid, grid_size):
"""
This function calculates the singlescale entropy of the pattern
Expand Down Expand Up @@ -33,19 +37,22 @@ def calculate_entropy(gridorflatgrid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_entropy(all_black, grid_size) == 0
print(calculate_entropy(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_entropy(grid_with_one_centre, grid_size) == 0.041125624368577904
print(calculate_entropy(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_entropy(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_entropy(checkerboard, grid_size) == 0.99998575111318
print(calculate_entropy(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_entropy(random, grid_size))
17 changes: 11 additions & 6 deletions measures/entropy_of_means/calculate_entropy_of_means.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""
This module implements the entropy of means measure based on:
https://www.geeksforgeeks.org/program-to-count-number-of-connected-components-in-an-undirected-graph/
Python implementation of the matrix information measurement examples from the
StackExchange answer written by WilliamAHuber for
"Measuring entropy/ information/ patterns of a 2d binary matrix"
http://stats.stackexchange.com/a/17556/43909
Copyright 2014 Cosmo Harrigan
This program is free software, distributed under the terms of the GNU LGPL v3.0
Refer to Section 2.2 (2iii) and AII for details.
"""

author = 'Cosmo Harrigan'
Expand Down Expand Up @@ -35,7 +38,6 @@ def calculate_entropy_of_means(flatgrid, grid_size):
matrices.append(output_matrix)

prof = profile(matrices)
print(prof)
return np.mean(prof)

if __name__ == "__main__":
Expand All @@ -44,19 +46,22 @@ def calculate_entropy_of_means(flatgrid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_entropy_of_means(all_black, grid_size) == 0.0
print(calculate_entropy_of_means(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_entropy_of_means(grid_with_one_centre, grid_size) == 0.25
print(calculate_entropy_of_means(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_entropy_of_means(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_entropy_of_means(checkerboard, grid_size) == 0.5
print(calculate_entropy_of_means(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_entropy_of_means(random, grid_size))
2 changes: 0 additions & 2 deletions measures/entropy_of_means/calculate_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,4 @@ def profile(matrices):
@input matrices The set of scaled filtered matrices
"""
print("hi")
print(matrices[1])
return [matrix_entropy(scale) for scale in matrices]
16 changes: 11 additions & 5 deletions measures/intricacy/calculate_intricacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import numpy as np
import sys

# Code based on GeeksforGeeks: https://www.geeksforgeeks.org/program-to-count-number-of-connected-components-in-an-undirected-graph/
"""
This module implements the intricacy measure using https://www.geeksforgeeks.org/program-to-count-number-of-connected-components-in-an-undirected-graph/.
Refer to Section 2.2 (5) and AII for details.
"""

class Graph:
"""
Expand Down Expand Up @@ -126,19 +129,22 @@ def calculate_intricacy(grid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size)
assert calculate_intricacy(all_black, grid_size) == (1, 1)
print(calculate_intricacy(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_intricacy(grid_with_one_centre, grid_size) == (2, 2)
print(calculate_intricacy(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size)
checkarboard[1::2] = 1
print(calculate_intricacy(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size)
checkerboard[1::2] = 1
assert calculate_intricacy(checkerboard, grid_size) == (225, 2)
print(calculate_intricacy(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_intricacy(random, grid_size))
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
author = 'Surabhi S Nath'
import numpy as np

"""
This module implements the local spatial complexity measure based on Javaheri Javid, M. A. (2019). Aesthetic Automata: Synthesis and Simulation of Aesthetic Behaviour in Cellular Automata (Doctoral dissertation, Goldsmiths, University of London).
Refer to Section 2.2 (3) and AII for details.
"""

def get_tuples(col1, col2, dirn, grid, grid_size):
"""
This function calculates the numerator of the conditional and joint distributions and the denominator of the conditional distribution
Expand Down Expand Up @@ -132,22 +137,22 @@ def calculate_local_spatial_complexity(pattern, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_local_spatial_complexity(all_black, grid_size) == (0.0, 0.0)
print(calculate_local_spatial_complexity(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_local_spatial_complexity(grid_with_one_centre, grid_size) == (0.04331646911530629, 0.0)
print(calculate_local_spatial_complexity(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_local_spatial_complexity(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_local_spatial_complexity(checkerboard, grid_size) == (0.0, 0.0)
print(calculate_local_spatial_complexity(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_local_spatial_complexity(random, grid_size))

# Ref:
# Javaheri Javid, M. A. (2019). Aesthetic Automata: Synthesis and Simulation of Aesthetic Behaviour in Cellular Automata (Doctoral dissertation, Goldsmiths, University of London).
print(calculate_local_spatial_complexity(random, grid_size))
15 changes: 11 additions & 4 deletions measures/mean_entropy/calculate_mean_entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
sys.path.insert(1, '../entropy/')
from calculate_entropy import *

"""
This module implements the mean entropy measure. Refer to Section 2.2 (2ii) and AII for details.
"""

def calculate_mean_entropy(gridorflatgrid, grid_size):
"""
This function calculates the mean entropy of a pattern across all scales
Expand Down Expand Up @@ -36,19 +40,22 @@ def calculate_mean_entropy(gridorflatgrid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_mean_entropy(all_black, grid_size) == 0.0
print(calculate_mean_entropy(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_mean_entropy(grid_with_one_centre, grid_size) == 0.0563395650797406
print(calculate_mean_entropy(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_mean_entropy(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_mean_entropy(checkerboard, grid_size) == 0.9326281610774253
print(calculate_mean_entropy(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_mean_entropy(random, grid_size))
15 changes: 11 additions & 4 deletions measures/quadtree/calculate_quadtree.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
author = 'Surabhi S Nath'
import numpy as np

"""
This module implements the quadtree measure. Refer to AII for details.
"""

def all_same(grid):
"""
Checks if all pixels of the subgrid are the same state
Expand Down Expand Up @@ -60,19 +64,22 @@ def calculate_quadtree(grid, grid_size):
# calculate density for some example patterns:
# 1) Full black pattern
# 2) White grid with one central black CellType
# 3) Checkarboard
# 3) checkerboard
# 4) Random pattern

all_black = np.ones(grid_size * grid_size, dtype=int)
assert calculate_quadtree(all_black, grid_size) == 0
print(calculate_quadtree(all_black, grid_size))

grid_with_one_centre = np.zeros(grid_size * grid_size, dtype=int)
grid_with_one_centre[(grid_size * grid_size) //2] = 1
assert calculate_quadtree(grid_with_one_centre, grid_size) == 4
print(calculate_quadtree(grid_with_one_centre, grid_size))

checkarboard = np.zeros(grid_size * grid_size, dtype=int)
checkarboard[1::2] = 1
print(calculate_quadtree(checkarboard, grid_size))
checkerboard = np.zeros(grid_size * grid_size, dtype=int)
checkerboard[1::2] = 1
assert calculate_quadtree(checkerboard, grid_size) == 84
print(calculate_quadtree(checkerboard, grid_size))

random = np.random.choice([0, 1], size=(grid_size, grid_size))
print(calculate_quadtree(random, grid_size))
Loading

0 comments on commit 87db174

Please sign in to comment.