run black on everything

autoformatting
This commit is contained in:
Tom Hodson 2022-06-09 09:57:58 +02:00
parent 9de5c8c303
commit 9eb933cb14
12 changed files with 183 additions and 119 deletions

View File

@ -7,14 +7,17 @@ States are represented by NxM numpy arrays with values +/-1. These functions are
import numpy as np import numpy as np
from numba import jit from numba import jit
def all_up_state(N): def all_up_state(N):
"The NxN all up state of the Ising model." "The NxN all up state of the Ising model."
return np.ones([N, N]) return np.ones([N, N])
def all_down_state(N): def all_down_state(N):
"The NxN all down state of the Ising model." "The NxN all down state of the Ising model."
return -np.ones([N, N]) return -np.ones([N, N])
def random_state(N, magnetisation=0.5, rng=np.random.default_rng()): def random_state(N, magnetisation=0.5, rng=np.random.default_rng()):
r"""Return the a random NxN state of the Ising model. r"""Return the a random NxN state of the Ising model.
@ -65,6 +68,7 @@ def energy(state):
return 2 * E / (N * M) return 2 * E / (N * M)
def energy_numpy(state): def energy_numpy(state):
r"""Compute the energy of a state of the Ising Model with open boundary conditions. r"""Compute the energy of a state of the Ising Model with open boundary conditions.
@ -81,4 +85,3 @@ def energy_numpy(state):
""" """
E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:]) E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:])
return 2 * E / np.product(state.shape) return 2 * E / np.product(state.shape)

View File

@ -3,6 +3,7 @@
""" """
def mcmc(initial_state, steps, T, rng=np.random.default_rng()): def mcmc(initial_state, steps, T, rng=np.random.default_rng()):
r"""Return the state after performing `steps` monte carlo steps starting from `initial_state` at temperature `T`. r"""Return the state after performing `steps` monte carlo steps starting from `initial_state` at temperature `T`.

View File

@ -9,19 +9,24 @@ from MCFF.ising_model import energy, energy_numpy
all_up = np.ones([100, 100]) all_up = np.ones([100, 100])
all_down = -np.ones([100, 100]) all_down = -np.ones([100, 100])
random = np.random.choice([-1, 1], size=(100, 100)) random = np.random.choice([-1, 1], size=(100, 100))
custom = (1 - 2*imread(Path(__file__).parents[2]/'learning/data/test_state.png')[:, :, 0]) #load a 100x100 png, take the red channel, remap 0,1 to -1,1 custom = (
1 - 2 * imread(Path(__file__).parents[2] / "learning/data/test_state.png")[:, :, 0]
) # load a 100x100 png, take the red channel, remap 0,1 to -1,1
states = [all_up, all_down, random, custom] states = [all_up, all_down, random, custom]
def E_prediction_all_the_same(L): def E_prediction_all_the_same(L):
"The exact energy in for the case where all spins are up or down" "The exact energy in for the case where all spins are up or down"
return -(4 * (L - 2) ** 2 + 12 * (L - 2) + 8) / L**2 return -(4 * (L - 2) ** 2 + 12 * (L - 2) + 8) / L**2
def test_exact_energies(): def test_exact_energies():
for state in [all_up, all_down]: for state in [all_up, all_down]:
L = state.shape[0] L = state.shape[0]
assert energy(state) == E_prediction_all_the_same(L) assert energy(state) == E_prediction_all_the_same(L)
def test_energy_implementations(): def test_energy_implementations():
for state in states: for state in states:
assert np.allclose(energy(state), energy_numpy(state)) assert np.allclose(energy(state), energy_numpy(state))

View File

@ -5,8 +5,13 @@ from hypothesis.extra import numpy as hnp
from MCFF.ising_model import energy, energy_numpy from MCFF.ising_model import energy, energy_numpy
@given(hnp.arrays(dtype = int,
@given(
hnp.arrays(
dtype=int,
shape=hnp.array_shapes(min_dims=2, max_dims=2), shape=hnp.array_shapes(min_dims=2, max_dims=2),
elements = st.sampled_from([1, -1]))) elements=st.sampled_from([1, -1]),
)
)
def test_generated_states(state): def test_generated_states(state):
assert np.allclose(energy(state), energy_numpy(state)) assert np.allclose(energy(state), energy_numpy(state))

View File

@ -51,9 +51,13 @@
"\n", "\n",
"# This loads some custom styles for matplotlib\n", "# This loads some custom styles for matplotlib\n",
"import json, matplotlib\n", "import json, matplotlib\n",
"with open(\"assets/matplotlibrc.json\") as f: matplotlib.rcParams.update(json.load(f))\n",
"\n", "\n",
"np.random.seed(42) #This makes our random numbers reproducable when the notebook is rerun in order" "with open(\"assets/matplotlibrc.json\") as f:\n",
" matplotlib.rcParams.update(json.load(f))\n",
"\n",
"np.random.seed(\n",
" 42\n",
") # This makes our random numbers reproducable when the notebook is rerun in order"
] ]
}, },
{ {
@ -86,11 +90,14 @@
"source": [ "source": [
"state = np.random.choice([-1, 1], size=(100, 100))\n", "state = np.random.choice([-1, 1], size=(100, 100))\n",
"\n", "\n",
"\n",
"def show_state(state, ax=None):\n", "def show_state(state, ax=None):\n",
" if ax is None: f, ax = plt.subplots()\n", " if ax is None:\n",
" f, ax = plt.subplots()\n",
" ax.matshow(state, cmap=\"Greys\", vmin=-1, vmax=1)\n", " ax.matshow(state, cmap=\"Greys\", vmin=-1, vmax=1)\n",
" ax.set(xticks=[], yticks=[])\n", " ax.set(xticks=[], yticks=[])\n",
"\n", "\n",
"\n",
"show_state(state)" "show_state(state)"
] ]
}, },
@ -137,7 +144,10 @@
"random = np.random.choice([-1, 1], size=(100, 100))\n", "random = np.random.choice([-1, 1], size=(100, 100))\n",
"\n", "\n",
"from matplotlib.image import imread\n", "from matplotlib.image import imread\n",
"custom = (1 - 2*imread('data/test_state.png')[:, :, 0]) #load a 100x100 png, take the red channel, remap 0,1 to -1,1\n", "\n",
"custom = (\n",
" 1 - 2 * imread(\"data/test_state.png\")[:, :, 0]\n",
") # load a 100x100 png, take the red channel, remap 0,1 to -1,1\n",
"\n", "\n",
"states = [all_up, all_down, random, custom]\n", "states = [all_up, all_down, random, custom]\n",
"\n", "\n",
@ -183,6 +193,7 @@
"def E_prediction_all_the_same(L):\n", "def E_prediction_all_the_same(L):\n",
" return -(4 * (L - 2) ** 2 + 12 * (L - 2) + 8) / L**2\n", " return -(4 * (L - 2) ** 2 + 12 * (L - 2) + 8) / L**2\n",
"\n", "\n",
"\n",
"L = 100\n", "L = 100\n",
"print(f\"For L = {L}, We predict E = {E_prediction_all_the_same(L)}\")" "print(f\"For L = {L}, We predict E = {E_prediction_all_the_same(L)}\")"
] ]
@ -225,13 +236,24 @@
" pass\n", " pass\n",
" return E / (N * M)\n", " return E / (N * M)\n",
"\n", "\n",
"expected_values = [E_prediction_all_the_same(100), E_prediction_all_the_same(100), 0, '???'] \n", "\n",
"expected_values = [\n",
" E_prediction_all_the_same(100),\n",
" E_prediction_all_the_same(100),\n",
" 0,\n",
" \"???\",\n",
"]\n",
"\n", "\n",
"f, axes = plt.subplots(ncols=2, nrows=2, figsize=(10, 10))\n", "f, axes = plt.subplots(ncols=2, nrows=2, figsize=(10, 10))\n",
"axes = axes.flatten()\n", "axes = axes.flatten()\n",
"for ax, state, exp_value in zip(axes, states, expected_values):\n", "for ax, state, exp_value in zip(axes, states, expected_values):\n",
" show_state(state, ax=ax)\n", " show_state(state, ax=ax)\n",
" ax.text(0,-0.1, f\"Expected Value: {exp_value}, Your value: {energy(state)}\", transform = ax.transAxes)" " ax.text(\n",
" 0,\n",
" -0.1,\n",
" f\"Expected Value: {exp_value}, Your value: {energy(state)}\",\n",
" transform=ax.transAxes,\n",
" )"
] ]
}, },
{ {
@ -254,6 +276,7 @@
"source": [ "source": [
"## Solution\n", "## Solution\n",
"\n", "\n",
"\n",
"def energy(state):\n", "def energy(state):\n",
" E = 0\n", " E = 0\n",
" N, M = state.shape\n", " N, M = state.shape\n",
@ -271,13 +294,24 @@
"\n", "\n",
" return E / (N * M)\n", " return E / (N * M)\n",
"\n", "\n",
"expected_values = [E_prediction_all_the_same(100), E_prediction_all_the_same(100), 0, '???'] \n", "\n",
"expected_values = [\n",
" E_prediction_all_the_same(100),\n",
" E_prediction_all_the_same(100),\n",
" 0,\n",
" \"???\",\n",
"]\n",
"\n", "\n",
"f, axes = plt.subplots(ncols=2, nrows=2, figsize=(10, 10))\n", "f, axes = plt.subplots(ncols=2, nrows=2, figsize=(10, 10))\n",
"axes = axes.flatten()\n", "axes = axes.flatten()\n",
"for ax, state, exp_value in zip(axes, states, expected_values):\n", "for ax, state, exp_value in zip(axes, states, expected_values):\n",
" show_state(state, ax=ax)\n", " show_state(state, ax=ax)\n",
" ax.text(0,-0.1, f\"Expected Value: {exp_value}, Your value: {energy(state)}\", transform = ax.transAxes)" " ax.text(\n",
" 0,\n",
" -0.1,\n",
" f\"Expected Value: {exp_value}, Your value: {energy(state)}\",\n",
" transform=ax.transAxes,\n",
" )"
] ]
}, },
{ {
@ -391,14 +425,21 @@
"def test_energy_function(energy_function):\n", "def test_energy_function(energy_function):\n",
" assert np.all(energy_function(state) == energy(state) for state in states)\n", " assert np.all(energy_function(state) == energy(state) for state in states)\n",
"\n", "\n",
"\n",
"def time_energy_function(energy_function):\n", "def time_energy_function(energy_function):\n",
" return [energy_function(state) for state in states]\n", " return [energy_function(state) for state in states]\n",
"\n", "\n",
"\n",
"def your_faster_energy_function(state):\n", "def your_faster_energy_function(state):\n",
" return energy(state) # <-- replace this with your implementation and compare how fast it runs!\n", " return energy(\n",
" state\n",
" ) # <-- replace this with your implementation and compare how fast it runs!\n",
"\n",
"\n", "\n",
"print(\"Naive baseline implementation\")\n", "print(\"Naive baseline implementation\")\n",
"test_energy_function(energy) #this should always pass because it's just comparing to itself!\n", "test_energy_function(\n",
" energy\n",
") # this should always pass because it's just comparing to itself!\n",
"naice = %timeit -o time_energy_function(energy)\n", "naice = %timeit -o time_energy_function(energy)\n",
"\n", "\n",
"print(\"\\nYour version\")\n", "print(\"\\nYour version\")\n",
@ -443,11 +484,11 @@
} }
], ],
"source": [ "source": [
"\n",
"\n",
"def numpy_energy(state):\n", "def numpy_energy(state):\n",
" E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:])\n", " E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:])\n",
" return 2 * E / np.product(state.shape)\n", " return 2 * E / np.product(state.shape)\n",
"\n",
"\n",
"test_energy_function(numpy_energy)\n", "test_energy_function(numpy_energy)\n",
"\n", "\n",
"states[0][0, 5] = -1\n", "states[0][0, 5] = -1\n",
@ -487,8 +528,10 @@
"def test_energy_function(energy_function):\n", "def test_energy_function(energy_function):\n",
" return [energy_function(state) for state in states]\n", " return [energy_function(state) for state in states]\n",
"\n", "\n",
"\n",
"from numba import jit\n", "from numba import jit\n",
"\n", "\n",
"\n",
"@jit(nopython=True)\n", "@jit(nopython=True)\n",
"def numba_energy(state):\n", "def numba_energy(state):\n",
" E = 0\n", " E = 0\n",
@ -507,6 +550,7 @@
"\n", "\n",
" return E / (N * M)\n", " return E / (N * M)\n",
"\n", "\n",
"\n",
"def numpy_energy(state):\n", "def numpy_energy(state):\n",
" E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:])\n", " E = -np.sum(state[:-1, :] * state[1:, :]) - np.sum(state[:, :-1] * state[:, 1:])\n",
" return 2 * E / np.product(state.shape)\n", " return 2 * E / np.product(state.shape)\n",
@ -581,6 +625,7 @@
"\n", "\n",
" return 2 * E / (N * M)\n", " return 2 * E / (N * M)\n",
"\n", "\n",
"\n",
"print(\"\\nImproved Naive version\")\n", "print(\"\\nImproved Naive version\")\n",
"energy2(states[0]) # run the function once to let numba compile it before timing it\n", "energy2(states[0]) # run the function once to let numba compile it before timing it\n",
"e2 = %timeit -o test_energy_function(energy2)\n", "e2 = %timeit -o test_energy_function(energy2)\n",
@ -619,8 +664,10 @@
], ],
"source": [ "source": [
"from numpy.random import default_rng\n", "from numpy.random import default_rng\n",
"\n",
"rng = default_rng(42)\n", "rng = default_rng(42)\n",
"\n", "\n",
"\n",
"def mcmc(initial_state, steps, T, energy=numba_energy):\n", "def mcmc(initial_state, steps, T, energy=numba_energy):\n",
" N, M = initial_state.shape\n", " N, M = initial_state.shape\n",
" assert N == M\n", " assert N == M\n",
@ -640,6 +687,7 @@
"\n", "\n",
" return current_state\n", " return current_state\n",
"\n", "\n",
"\n",
"Ts = [4, 5, 50]\n", "Ts = [4, 5, 50]\n",
"\n", "\n",
"ncols = 1 + len(Ts)\n", "ncols = 1 + len(Ts)\n",

View File

@ -21,7 +21,9 @@
"\n", "\n",
"# This loads some custom styles for matplotlib\n", "# This loads some custom styles for matplotlib\n",
"import json, matplotlib\n", "import json, matplotlib\n",
"with open(\"assets/matplotlibrc.json\") as f: matplotlib.rcParams.update(json.load(f))" "\n",
"with open(\"assets/matplotlibrc.json\") as f:\n",
" matplotlib.rcParams.update(json.load(f))"
] ]
}, },
{ {