Source code for kleinberg_grid_simulator.python_implementation.shortcuts

import numpy as np
from numba import njit  # type: ignore

from kleinberg_grid_simulator.python_implementation.seed import set_seeds


[docs] @njit def radius2shortcut(radius): """ Parameters ---------- radius: :class:`int` Radius to draw shortcut from. Returns ------- x: :class:`int` x relative coordinate y: :class:`int` y relative coordinate Examples -------- >>> set_seeds() >>> radius2shortcut(10) (-9, 1) >>> radius2shortcut(2**40) (772882432861, -326629194915) """ angle = np.random.randint(-2 * radius + 1, 2 * radius + 1) return (radius - np.abs(angle)), (np.sign(angle) * (radius - np.abs(radius - np.abs(angle))))
[docs] def draw_r_lt_1(n, r): """ Parameters ---------- n: :class:`int` grid size r: :class:`float` Shortcut exponent (<1) Returns ------- callable A shortcut generator Examples -------- >>> set_seeds() >>> gen = draw_r_lt_1(100, .5) >>> gen() (0, -103) >>> gen = draw_r_lt_1(1000000000, .8) >>> gen() (1482484865, 59640099) """ expo = 2 - r pow_max_radius = (2 * (n - 1) + 1) ** expo - 1 def generator(): radius = np.floor((np.random.rand() * pow_max_radius + 1) ** (1 / expo)) while np.random.rand() * radius * ((1 + 1 / radius) ** expo - 1) > expo: radius = np.floor((np.random.rand() * pow_max_radius + 1) ** (1 / expo)) return radius2shortcut(np.int64(radius)) return generator
[docs] def draw_r_eq_1(n): """ Parameters ---------- n: :class:`int` grid size Returns ------- callable A shortcut generator Examples -------- >>> set_seeds() >>> gen = draw_r_eq_1(100) >>> gen() (0, -103) >>> gen = draw_r_eq_1(1000000000) >>> gen() (677037233, 596605187) """ max_radius = 2 * (n - 1) + 1 def generator(max_radius=max_radius): return radius2shortcut(1 + np.random.randint(max_radius)) return generator
[docs] def draw_1_lt_r_lt_2(n, r): """ Parameters ---------- n: :class:`int` grid size r: :class:`float` Shortcut exponent (1<r<2) Returns ------- callable A shortcut generator Examples -------- >>> set_seeds() >>> gen = draw_1_lt_r_lt_2(100, 1.5) >>> gen() (-78, -103) >>> gen = draw_1_lt_r_lt_2(1000000000, 1.8) >>> gen() (123799, 141186) """ expo = 2 - r pow_max_radius = (2 * (n - 1)) ** expo - 1 p1 = 1 / (1 + pow_max_radius / expo) def generator(expo=expo, pow_max_radius=pow_max_radius, p1=p1): while True: if np.random.rand() < p1: return radius2shortcut(1) else: radius = np.ceil((np.random.rand() * pow_max_radius + 1) ** (1 / expo)) if np.random.rand() * radius * (1 - (1 - 1 / radius) ** expo) < expo: return radius2shortcut(np.int64(radius)) return generator
[docs] def draw_r_eq_2(n): """ Parameters ---------- n: :class:`int` grid size Returns ------- callable A shortcut generator Examples -------- >>> set_seeds() >>> gen = draw_r_eq_2(100) >>> gen() (-50, -103) >>> gen = draw_r_eq_2(1000000000) >>> gen() (23, -6) """ max_radius = 2 * (n - 1) p1 = 1 / (1 + np.log(max_radius)) def generator(max_radius=max_radius, p1=p1): while True: if np.random.rand() < p1: return radius2shortcut(1) else: radius = np.ceil(max_radius ** np.random.rand()) if np.random.rand() * radius * np.log(1 + 1 / (radius - 1)) < 1: return radius2shortcut(np.int64(radius)) return generator
[docs] def draw_2_lt_r(n, r): """ Parameters ---------- n: :class:`int` grid size r: :class:`float` Shortcut exponent (>2) Returns ------- callable A shortcut generator Examples -------- >>> set_seeds() >>> gen = draw_2_lt_r(100, 2.5) >>> gen() (29, -45) >>> gen = draw_2_lt_r(10000000, 2.8) >>> gen() (2, 0) >>> gen = draw_2_lt_r(100000, 2.2) >>> gen() (0, -1) >>> gen() (-39, -15) """ expo = r - 2 pow_max_radius = 1 / (2 * (n - 1)) ** expo - 1 p1 = 1 / (1 - pow_max_radius / expo) def generator(expo=expo, pow_max_radius=pow_max_radius, p1=p1): while True: if np.random.rand() < p1: return radius2shortcut(1) else: radius = np.ceil(1 / (np.random.rand() * pow_max_radius + 1) ** (1 / expo)) if np.random.rand() * radius * ((1 + 1 / (radius - 1)) ** expo - 1) < expo: return radius2shortcut(np.int64(radius)) return generator