Material for ASPP 2024
This commit is contained in:
commit
849682b13b
97 changed files with 8170 additions and 0 deletions
|
@ -0,0 +1,46 @@
|
|||
""" CONTEXT MAP BUILDERS """
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
def flat_context_map_builder(size):
|
||||
""" A context map where all positions are equally likely. """
|
||||
return np.ones((size, size))
|
||||
|
||||
|
||||
def hills_context_map_builder(size):
|
||||
""" A context map with bumps and valleys. """
|
||||
grid_ii, grid_jj = np.mgrid[0:size, 0:size]
|
||||
i_waves = np.sin(grid_ii / 130) + np.sin(grid_ii / 10)
|
||||
i_waves /= i_waves.max()
|
||||
j_waves = np.sin(grid_jj / 100) + np.sin(grid_jj / 50) + \
|
||||
np.sin(grid_jj / 10)
|
||||
j_waves /= j_waves.max()
|
||||
context_map = j_waves + i_waves
|
||||
return context_map
|
||||
|
||||
|
||||
def labyrinth_context_map_builder(size):
|
||||
""" A context map that looks like a labyrinth. """
|
||||
context_map = np.ones((size, size))
|
||||
context_map[50:100, 50:60] = 0
|
||||
context_map[20:89, 80:90] = 0
|
||||
context_map[90:120, 0:10] = 0
|
||||
context_map[120:size, 30:40] = 0
|
||||
context_map[180:190, 50:60] = 0
|
||||
|
||||
context_map[50:60, 50:200] = 0
|
||||
context_map[179:189, 80:130] = 0
|
||||
context_map[110:120, 0:190] = 0
|
||||
context_map[120:size, 30:40] = 0
|
||||
context_map[180:190, 50:60] = 0
|
||||
|
||||
return context_map
|
||||
|
||||
|
||||
# Register map builders
|
||||
map_builders = {
|
||||
"flat": flat_context_map_builder,
|
||||
"hills": hills_context_map_builder,
|
||||
"labyrinth": labyrinth_context_map_builder,
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"seed": 42,
|
||||
"sigma_i": 3,
|
||||
"sigma_j": 4,
|
||||
"size": 200,
|
||||
"map_type": "hills",
|
||||
"start_i": 50,
|
||||
"start_j": 100,
|
||||
"n_iterations": 1000
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def plot_trajectory(trajectory, context_map):
|
||||
""" Plot a trajectory over a context map. """
|
||||
trajectory = np.asarray(trajectory)
|
||||
plt.matshow(context_map)
|
||||
plt.plot(trajectory[:, 1], trajectory[:, 0], color='r')
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_trajectory_hexbin(trajectory):
|
||||
""" Plot an hexagonal density map of a trajectory. """
|
||||
trajectory = np.asarray(trajectory)
|
||||
with plt.rc_context({'figure.figsize': (4, 4), 'axes.labelsize': 16,
|
||||
'xtick.labelsize': 14, 'ytick.labelsize': 14}):
|
||||
plt.hexbin(trajectory[:, 1], trajectory[:, 0], gridsize=30,
|
||||
extent=(0, 200, 0, 200), edgecolors='none', cmap='Reds')
|
||||
plt.gca().invert_yaxis()
|
||||
plt.xlabel('X')
|
||||
plt.ylabel('Y')
|
|
@ -0,0 +1,42 @@
|
|||
import json
|
||||
import time
|
||||
|
||||
import git
|
||||
import numpy as np
|
||||
|
||||
from walker import Walker
|
||||
from context_maps import map_builders
|
||||
|
||||
|
||||
with open("inputs.json", 'r') as f:
|
||||
inputs = json.load(f)
|
||||
|
||||
random_state = np.random.RandomState(inputs["seed"])
|
||||
n_iterations = inputs["n_iterations"]
|
||||
|
||||
|
||||
|
||||
context_map_builder = map_builders[inputs["map_type"]]
|
||||
context_map = context_map_builder(inputs["size"])
|
||||
walker = Walker(inputs["sigma_i"], inputs["sigma_j"], context_map)
|
||||
|
||||
|
||||
trajectory = []
|
||||
for _ in range(n_iterations):
|
||||
i, j = walker.sample_next_step(inputs["start_i"], inputs["start_j"],
|
||||
random_state)
|
||||
trajectory.append((i, j))
|
||||
|
||||
# STEP 4: Save the trajectory
|
||||
curr_time = time.strftime("%Y%m%d-%H%M%S")
|
||||
np.save(f"sim_{curr_time}", trajectory)
|
||||
|
||||
|
||||
# STEP 5: Save the metadata
|
||||
# lookup git repository
|
||||
repo = git.Repo(search_parent_directories=True)
|
||||
sha = repo.head.object.hexsha
|
||||
|
||||
with open('meta.txt', 'w') as f:
|
||||
f.write(f'I estimated parameters at {curr_time}.\n')
|
||||
f.write(f'The git repo was at commit {sha}')
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
import numpy as np
|
||||
|
||||
|
||||
class Walker:
|
||||
""" The Walker knows how to walk at random on a context map. """
|
||||
|
||||
def __init__(self, sigma_i, sigma_j, context_map):
|
||||
self.sigma_i = sigma_i
|
||||
self.sigma_j = sigma_j
|
||||
self.size = context_map.shape[0]
|
||||
# Make sure that the context map is normalized
|
||||
context_map /= context_map.sum()
|
||||
self.context_map = context_map
|
||||
|
||||
# Pre-compute a 2D grid of coordinates for efficiency
|
||||
self._grid_ii, self._grid_jj = np.mgrid[0:self.size, 0:self.size]
|
||||
|
||||
# --- Walker public interface
|
||||
|
||||
def sample_next_step(self, current_i, current_j, random_state=np.random):
|
||||
""" Sample a new position for the walker. """
|
||||
|
||||
# Combine the next-step proposal with the context map to get a
|
||||
# next-step probability map
|
||||
next_step_map = self._next_step_proposal(current_i, current_j)
|
||||
selection_map = self._compute_next_step_probability(next_step_map)
|
||||
|
||||
# Draw a new position from the next-step probability map
|
||||
r = random_state.rand()
|
||||
cumulative_map = np.cumsum(selection_map)
|
||||
cumulative_map = cumulative_map.reshape(selection_map.shape)
|
||||
i_next, j_next = np.argwhere(cumulative_map >= r)[0]
|
||||
|
||||
return i_next, j_next
|
||||
|
||||
# --- Walker non-public interface
|
||||
|
||||
def _next_step_proposal(self, current_i, current_j):
|
||||
""" Create the 2D proposal map for the next step of the walker. """
|
||||
|
||||
# 2D Gaussian distribution , centered at current position,
|
||||
# and with different standard deviations for i and j
|
||||
grid_ii, grid_jj = self._grid_ii, self._grid_jj
|
||||
sigma_i, sigma_j = self.sigma_i, self.sigma_j
|
||||
|
||||
rad = (
|
||||
(((grid_ii - current_i) ** 2) / (sigma_i ** 2))
|
||||
+ (((grid_jj - current_j) ** 2) / (sigma_j ** 2))
|
||||
)
|
||||
|
||||
p_next_step = np.exp(-(rad / 2.0)) / (2.0 * np.pi * sigma_i * sigma_j)
|
||||
return p_next_step / p_next_step.sum()
|
||||
|
||||
def _compute_next_step_probability(self, next_step_map):
|
||||
""" Compute the next step probability map from next step proposal and
|
||||
context map. """
|
||||
next_step_probability = next_step_map * self.context_map
|
||||
next_step_probability /= next_step_probability.sum()
|
||||
return next_step_probability
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue