def _ctmp_inverse( n_samples: int, probs: np.ndarray, gamma: float, csc_data: np.ndarray, csc_indices: np.ndarray, csc_indptrs: np.ndarray, rng: np.random.Generator) -> Tuple[Tuple[int], Tuple[int]]: """Apply CTMP algorithm to input counts dictionary, return sampled counts and associated shots. Equivalent to Algorithm 1 in Bravyi et al. Args: n_samples: Number of times to sample in CTMP algorithm. probs: probability vector constructed from counts. gamma: noise strength parameter csc_data: Sparse CSC matrix data array (`csc_matrix.data`). csc_indices: Sparse CSC matrix indices array (`csc_matrix.indices`). csc_indptrs: Sparse CSC matrix indices array (`csc_matrix.indptrs`). rng: RNG generator object. Returns: Tuple[Tuple[int], Tuple[int]]: Resulting list of shots and associated signs from the CTMP algorithm. """ alphas = rng.poisson(lam=gamma, size=n_samples) signs = np.mod(alphas, 2) x_vals = rng.choice(len(probs), size=n_samples, p=probs) # Apply CTMP sampling r_vals = rng.random(size=alphas.sum()) y_vals = np.zeros(x_vals.size, dtype=np.int) _markov_chain_compiled(y_vals, x_vals, r_vals, alphas, csc_data, csc_indices, csc_indptrs) return y_vals, signs
def sample_partition( skel: Skeleton, intensity: float = 1, ome: np.random.Generator = np.random.default_rng() ) -> (Partition, np.ndarray): """ :param skel: :param intensity: :param ome: :return: >>> # generate fixture >>> dim = 3 >>> fin_t = 1e2 >>> gen = sample_trial_generator(dim) >>> stat = get_stat(gen) >>> skel = sample_forwards(fin_t, None, gen) >>> # test >>> skel2 = paste_partition(sample_partition(skel)[0]) >>> np.all(skel.t == skel2.t), np.all(skel.xt == skel2.xt), skel.fin_t == skel2.fin_t (True, True, True) """ n_breaks = ome.poisson(intensity * skel.fin_t) new_t = np.linspace(0, skel.fin_t, n_breaks + 2) return partition_skeleton(skel, new_t[1:-1]), new_t[1:-1]
def _resample_extended_n( samples: _tp.List[np.ndarray], size: int, rng: np.random.Generator) -> _tp.Generator[np.ndarray, None, None]: n = len(samples[0]) for i in range(size): k = rng.poisson(1, size=n) yield tuple(np.repeat(s, k) for s in samples)
def _resample_extended_1( sample: np.ndarray, size: int, rng: np.random.Generator) -> _tp.Generator[np.ndarray, None, None]: # randomly generates the sample size from a Poisson distribution n = len(sample) for i in range(size): k = rng.poisson(1, size=n) yield np.repeat(sample, k)
def _resample_parametric( sample: np.ndarray, size: int, dist: stats.rv_continuous, rng: np.random.Generator) -> _tp.Generator[np.ndarray, None, None]: n = len(sample) # fit parameters by maximum likelihood and sample from that if dist == stats.poisson: # - poisson has no fit method and there is no scale parameter # - random number generation for poisson distribution in scipy seems to be buggy mu = np.mean(sample) for _ in range(size): yield rng.poisson(mu, size=n) else: args = _fit_parametric_family(dist, sample) dist = dist(*args) for _ in range(size): yield dist.rvs(size=n, random_state=rng)
def sample_generator(rg: np.random.Generator): lat, lon = get_sample( rg.poisson(arrival_rate), rg, cd, sample_df, CHC_df, CHC_sub, CHC_sub_dict, save=False, ) time_windows = np.zeros((len(lat), 2)) for i in range(len(lat)): time_windows[i, 0] = 0 time_windows[i, 1] = 28800 customers = [Customer(lat[i], lon[i], 0.9, 0.9, rg=rg) for i in range(len(lat))] return customers, time_windows
def get_index_growth( rng: np.random.Generator, size: Tuple[int, int], ) -> np.ndarray: """Calculates cumulative growth to mimic index growth.""" # Subtracts 0.2 from values [0, 1] so that 1/5 have negative sign. # This is arbitrary, and results in the index increasing in 4 out # of 5 months. signs = np.sign(rng.random(size) - 0.2) # Takes a poisson dist with lambda = 1 and adds some random noise. # Multiply by signs to apply increasing / decreasing. pois = rng.poisson(1, size) noise = rng.random(size) growth = (pois + noise) * signs growth[0, :] = 0 # No growth at index start. return growth.cumsum(axis=0)
def sample_batch_ppp( intensity: float, bounds: Tuple[float, ...] = (1, 1), batch_size: int = 2, ome: np.random.Generator = np.random.default_rng() ) -> Iterator[np.ndarray]: """Sample from a Poisson point process in batches. >>> # generate fixture >>> gen = int(1e4) >>> bound = np.random.lognormal(size=2) >>> # draw iid samples >>> y = np.vstack([ppp for ppp in sample_batch_ppp(gen, tuple(bound))]) >>> # test sampling distribution >>> from scipy.stats import kstest, uniform >>> alpha = 1e-2 >>> sample = (y / bound).flatten() >>> dist = uniform() >>> alpha < kstest(sample, dist.cdf)[1] True """ assert 0 < intensity assert 0 < min(bounds) assert 0 < batch_size n_points = ome.poisson(intensity * np.prod(bounds)) batch_sizes = it.repeat(batch_size, int(n_points // batch_size)) if n_points % batch_size != 0: batch_sizes = it.chain(batch_sizes, [n_points % batch_size]) ub = 0 for i in batch_sizes: lb, ub = ub, ub + bounds[0] * ome.beta(i, n_points + 1 - i) if i == 1: u0 = np.array([ub]) else: u0 = np.hstack([np.sort(ome.uniform(lb, ub, i - 1)), ub]) u = ome.uniform(np.zeros(len(bounds[1:])), bounds[1:], (i, len(bounds[1:]))) yield np.vstack([u0, u.T]).T
def sample_generator(rg: np.random.Generator): lat, lon = get_sample( rg.poisson(arrival_rate) * num_addresses, rg, cd, sample_df, CHC_df, CHC_sub, CHC_sub_dict, save=False, ) customers = [ Customer( lat[i], lon[i], 0.9, 0.9, rg=rg, presence_interval=28800 // 16, presence=markov_presence(16, 0.2, rg), ) for i in range(len(lat)) ] num_actual_packages = len(customers) // num_addresses for i in range(len(customers)): customers[i].add_alternate(customers[i % num_actual_packages]) time_windows = np.zeros((len(customers), 2)) for i in range(len(customers)): time_windows[i, :] = customers[i].get_time_window( [[i, i + 28800 // num_time_windows] for i in range(0, 28800, 28800 // num_time_windows)]) """for i in range(len(lat)): interval = (day_end - day_start) / num_time_windows for j in range(num_time_windows): if rg.random() > (num_time_windows - (j + 1)) / num_time_windows: time_windows[i, 0] = interval * j time_windows[i, 1] = interval * (j + 1) break""" return customers, time_windows
def sample_ppp( intensity: float, bound: Tuple[float, ...] = (1, 1), ome: np.random.Generator = np.random.default_rng() ) -> np.ndarray: """Sample from a Poisson point process on the plane. :param intensity: :param bound: :param ome: :return: >>> # generate fixture >>> gen = int(1e4) >>> bound = np.random.lognormal(size=2) >>> # draw iid samples >>> y = sample_ppp(gen, tuple(bound)) >>> # test sampling distribution >>> from scipy.stats import kstest, uniform >>> alpha = 1e-2 >>> sample = (y / bound).flatten() >>> dist = uniform() >>> alpha < kstest(sample, dist.cdf)[1] True """ assert 0 < intensity assert 0 < min(bound) n_points = ome.poisson(intensity * np.prod(bound)) locations = ome.uniform(np.zeros(len(bound)), bound, (n_points, len(bound))) return locations[np.argsort(locations[:, 0])]
def _computeInfectiousContactsStochastic( contacts: List[float], infectious: List[float], susceptibles: Union[int, float], totalInAge: Union[int, float], random_state: np.random.Generator) -> float: """ Takes a list of contacts (usually coming from other age groups) which should be paired with a list of infectious people from the same group. This function will then estimate the number of infectious contacts those people will produce. :param contacts: A list with the number of contacts per incoming group :param infectious: The number of incoming infectious people, paired with the the list of contacts :param susceptibles: The number of susceptible people to which the contacts can target :param totalInAge: Total number of people in target population :param random_state: Random number generator used for the model :return: The number of potentially infectious contacts """ if len(contacts) != len(infectious): raise ValueError("contacts and infectious must have the same length") assert isinstance(totalInAge, int) or totalInAge.is_integer() assert isinstance(susceptibles, int) or susceptibles.is_integer() inf_max = int(round(max(infectious))) # each np.array represent one original (contact, infectious) pair numbersOfContacts: np.array = np.zeros((len(contacts), inf_max), dtype=int) for n, (contact, infected) in enumerate(zip(contacts, infectious)): x = random_state.poisson(contact, int(round(infected))) numbersOfContacts[n, :len(x)] = x # Number of contacts cannot be higher than the number of people in the node numbersOfContacts = np.minimum( np.array(numbersOfContacts).T, int(totalInAge)) result = random_state.hypergeometric( np.full(len(contacts), int(susceptibles)), np.full(len(contacts), int(totalInAge - susceptibles)), numbersOfContacts, ).T return cast(float, np.sum(result))