Source code for silico.urinal

"""Urinal protocol iteration"""

from itertools import product
from collections import deque

import numpy as np

from .common import prod


[docs] def distance_matrix(indices, shape, p=2): """ Returns an array whose elements are the p-norm distances to the point with the given indices. Args: indices (tuple of int): The indices of the point. shape (tuple of int): The shape of the array. p (int): The p-norm to use (deafults to 2=ecuclidean) Returns: An array of the given shape whose elements are the p-norm distances to the point of the given indices. """ # Create arrays of indices for each dimension. indices_arrays = np.indices(shape) # Compute the p-norm distances to the point (i_1, i_2, ..., i_n). diff = indices_arrays - np.array(indices).reshape(-1, *(1,) * len(shape)) distances = np.linalg.norm(diff, ord=p, axis=0) return distances
[docs] def urinal_iteration(dims, p=1): """Yield the coordinates of urinal-like iteration""" n = prod(dims) distances = np.ones(dims) * np.inf to_yield = deque(list(product(*[[0, x - 1] for x in dims]))) # Corners i = 0 while i < n: if to_yield: i += 1 element = to_yield.popleft() yield element distances = np.minimum(distances, distance_matrix(element, dims, p)) else: to_yield.append(np.unravel_index(np.argmax(distances, axis=None), distances.shape))