Example #1
0
    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
Example #2
0
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]
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)
Example #6
0
    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
Example #7
0
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)
Example #8
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
Example #10
0
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])]
Example #11
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))