4. Discussion: Two next-step proposals #4

Open
opened 2026-08-31 16:04:16 +02:00 by lisa · 7 comments
Owner

Prof. McSmartypants wants to try running the walker with a different next step proposal that looks like this:

def square_next_step_proposal(current_i, current_j, size, width):
    """ Square next step proposal. """
    grid_ii, grid_jj = np.mgrid[0:size, 0:size]
    inside_mask = (np.abs(grid_ii - current_i) <= width // 2) & (np.abs(grid_jj - current_j) <= width // 2)
    p_next_step = inside_mask / inside_mask.sum()
    return p_next_step

Maybe we will need to add different step proposals later, so let's set this up properly, maybe by passing the proposal function to the walker. How should we design that code?

Exercise instructions:
Go to the notebook walker/Step_4_break_out_the_next_step_probability and follow the instructions. Comment here what you think the solution could look like. Also feel free to comment on other group's suggestions.

Make sure to include your suggested code snippet(s)

Prof. McSmartypants wants to try running the walker with a different next step proposal that looks like this: ```python def square_next_step_proposal(current_i, current_j, size, width): """ Square next step proposal. """ grid_ii, grid_jj = np.mgrid[0:size, 0:size] inside_mask = (np.abs(grid_ii - current_i) <= width // 2) & (np.abs(grid_jj - current_j) <= width // 2) p_next_step = inside_mask / inside_mask.sum() return p_next_step ``` Maybe we will need to add different step proposals later, so let's set this up properly, maybe by passing the proposal function to the walker. How should we design that code? Exercise instructions: Go to the notebook walker/Step_4_break_out_the_next_step_probability and follow the instructions. Comment here what you think the solution could look like. Also feel free to comment on other group's suggestions. Make sure to include your suggested code snippet(s)
Member
from step_generators import gaussian_step, square_step
context_map = hills_context_map(size=200)
params_dict = {'sigma_i' : 3, 'sigma_j' : 4}
walker = Walker( context_map=context_map, next_step_proposal = gaussian_step, params = params_dict)

# Sample a next step 1000 times
i, j = 100, 50
trajectory = []
for _ in range(1000):
    i, j = walker.sample_next_step(i, j)
    trajectory.append((i, j))
    
plot_trajectory(trajectory, walker.context_map)
```python from step_generators import gaussian_step, square_step context_map = hills_context_map(size=200) params_dict = {'sigma_i' : 3, 'sigma_j' : 4} walker = Walker( context_map=context_map, next_step_proposal = gaussian_step, params = params_dict) # Sample a next step 1000 times i, j = 100, 50 trajectory = [] for _ in range(1000): i, j = walker.sample_next_step(i, j) trajectory.append((i, j)) plot_trajectory(trajectory, walker.context_map) ```
Member

we would change the function _next_step_proposal so that it takes a custom function that defines the probability distribution around current_i, current_j. This custom function is passed to the constructor from outside the class.

we would change the function `_next_step_proposal` so that it takes a custom function that defines the probability distribution around `current_i, current_j`. This custom function is passed to the constructor from outside the class.
Member

import matplotlib.pyplot as plt
import numpy as np

from context_maps import flat_context_map, hills_context_map, labyrinth_context_map
from plotting import plot_trajectory, plot_trajectory_hexbin
from walker import Walker
from next_step_proposals import guassian_next_step_proposal, square_next_step_proposal #import functions ```

and then call 

``` context_map = hills_context_map(size=200)
walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map)

# Sample a next step 1000 times
i, j = 100, 50
trajectory = []
for _ in range(1000):
    i, j = walker.sample_next_step(i, j, square_next_tep_proposal, {'width':200}) #call function 
    trajectory.append((i, j))
    
plot_trajectory(trajectory, walker.context_map) ```
``` %matplotlib inline import matplotlib.pyplot as plt import numpy as np from context_maps import flat_context_map, hills_context_map, labyrinth_context_map from plotting import plot_trajectory, plot_trajectory_hexbin from walker import Walker from next_step_proposals import guassian_next_step_proposal, square_next_step_proposal #import functions ``` and then call ``` context_map = hills_context_map(size=200) walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map) # Sample a next step 1000 times i, j = 100, 50 trajectory = [] for _ in range(1000): i, j = walker.sample_next_step(i, j, square_next_tep_proposal, {'width':200}) #call function trajectory.append((i, j)) plot_trajectory(trajectory, walker.context_map) ```
Member

New module:

def gaussian_step(current_i, current_j, sigma_i, sigma_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 = np.mgrid[0:size, 0:size]
    sigma_i, sigma_j = sigma_i, 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)
    p_next_step = p_next_step / p_next_step.sum()
    return p_next_step

def square_next_step_proposal(current_i, current_j, size, width):
    """ Square next step proposal. """
    grid_ii, grid_jj = np.mgrid[0:size, 0:size]
    inside_mask = (np.abs(grid_ii - current_i) <= width // 2) & (np.abs(grid_jj - current_j) <= width // 2)
    p_next_step = inside_mask / inside_mask.sum()
    return p_next_step

Class change:

def _next_step_proposal(self, current_i, current_j, function_to_use, kw_args):
        """ Create the 2D proposal map for the next step of the walker. """

        p_next_step = function_to_use(current_i, current_j, **kw_args)

    
        return p_next_step / p_next_step.sum()
New module: ``` def gaussian_step(current_i, current_j, sigma_i, sigma_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 = np.mgrid[0:size, 0:size] sigma_i, sigma_j = sigma_i, 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) p_next_step = p_next_step / p_next_step.sum() return p_next_step def square_next_step_proposal(current_i, current_j, size, width): """ Square next step proposal. """ grid_ii, grid_jj = np.mgrid[0:size, 0:size] inside_mask = (np.abs(grid_ii - current_i) <= width // 2) & (np.abs(grid_jj - current_j) <= width // 2) p_next_step = inside_mask / inside_mask.sum() return p_next_step ``` Class change: ``` def _next_step_proposal(self, current_i, current_j, function_to_use, kw_args): """ Create the 2D proposal map for the next step of the walker. """ p_next_step = function_to_use(current_i, current_j, **kw_args) return p_next_step / p_next_step.sum() ```
Member

imports: import both next_step_proposal_arguments and next_step_proposal

In the walker file, we define both functions. next_step_proposal uses the arguments that are supplied through the stars (**kwargs).

Before the walker instantiation we define a proposal_dict in which we add all the arguments and their values. In the instantiation of the walker, the proposal_dict file is supplied to next_step_proposal_arguments, which under the hood passes it to next_step_proposal.

imports: import both next_step_proposal_arguments and next_step_proposal In the walker file, we define both functions. next_step_proposal uses the arguments that are supplied through the stars (**kwargs). Before the walker instantiation we define a proposal_dict in which we add all the arguments and their values. In the instantiation of the walker, the proposal_dict file is supplied to next_step_proposal_arguments, which under the hood passes it to next_step_proposal.
Member
  1. Modify imports> from next_step_proposal import gaussian_next_step_proposal, square_next_step_proposal

a. Define walker(self, sigma_i, sigma_j,next_step_proposal,nect_step_proposal)arguement)
b. walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map, square_next_step_proposal, {'size':200, 'width':14})

1. Modify imports> `from next_step_proposal import gaussian_next_step_proposal, square_next_step_proposal` 2. a. Define walker(self, sigma_i, sigma_j,next_step_proposal,nect_step_proposal)arguement) b. `walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map, square_next_step_proposal, {'size':200, 'width':14})`
Member

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np
import next_step_proposal # this is the function to compute different type of proposals

from context_maps import flat_context_map, hills_context_map, labyrinth_context_map
from plotting import plot_trajectory, plot_trajectory_hexbin
from walker import Walker
context_map = hills_context_map(size=200)

# Constructor now takes the function and the dictionary as args. So different istances can use different proposals
walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map, next_step_proposal, next_step_proposal_args)

# Sample a next step 1000 times
i, j = 100, 50
trajectory = []
for _ in range(1000):
    i, j = walker.sample_next_step(i, j)
    trajectory.append((i, j))
    
plot_trajectory(trajectory, walker.context_map)
``` %matplotlib inline import matplotlib.pyplot as plt import numpy as np import next_step_proposal # this is the function to compute different type of proposals from context_maps import flat_context_map, hills_context_map, labyrinth_context_map from plotting import plot_trajectory, plot_trajectory_hexbin from walker import Walker context_map = hills_context_map(size=200) # Constructor now takes the function and the dictionary as args. So different istances can use different proposals walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map, next_step_proposal, next_step_proposal_args) # Sample a next step 1000 times i, j = 100, 50 trajectory = [] for _ in range(1000): i, j = walker.sample_next_step(i, j) trajectory.append((i, j)) plot_trajectory(trajectory, walker.context_map) ```
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
8 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ASPP/2026-prague-scientific-patterns#4
No description provided.