def mux(seed_pool, n_samples, k, lam=256.0, pool_weights=None,
        with_replacement=True, prune_empty_seeds=True, revive=False):
    n_seeds = len(seed_pool)

    if not n_seeds:
        raise RuntimeError('Cannot mux an empty seed-pool')

    # Set up the sampling distribution over streams
    seed_distribution = 1./n_seeds * np.ones(n_seeds)

    if pool_weights is None:
        pool_weights = seed_distribution.copy()

    pool_weights = np.atleast_1d(pool_weights)

    assert len(pool_weights) == len(seed_pool)
    assert (pool_weights > 0.0).any()
    pool_weights /= np.sum(pool_weights)

    # Instantiate the pool
    streams = [None] * k

    stream_weights = np.zeros(k)
    stream_counts = np.zeros(k, dtype=int)
    stream_idxs = np.zeros(k, dtype=int)
    for idx in range(k):

        if not (seed_distribution > 0).any():
            break

        stream_idxs[idx] = np.random.choice(n_seeds, p=seed_distribution)
        streams[idx], stream_weights[idx] = generate_new_seed(
            stream_idxs[idx], seed_pool, pool_weights, seed_distribution, lam,
            with_replacement)

    weight_norm = np.sum(stream_weights)

    # Main sampling loop
    n = 0

    if n_samples is None:
        n_samples = np.inf

    while n < n_samples and weight_norm > 0.0:
        # Pick a stream from the active set
        idx = np.random.choice(k, p=stream_weights / weight_norm)

        # Can we sample from it?
        try:
            # Then yield the sample
            yield six.advance_iterator(streams[idx])

            # Increment the sample counter
            n += 1
            stream_counts[idx] += 1

        except StopIteration:
            # Oops, this one's exhausted.

            if prune_empty_seeds and stream_counts[idx] == 0:
                # If we're disabling empty seeds, see if this stream produced data
                seed_distribution[stream_idxs[idx]] = 0.0

            if revive and not with_replacement:
                # If we need to revive a seed, give it the max current probability
                if seed_distribution.any():
                    seed_distribution[stream_idxs[idx]] = np.max(seed_distribution)
                else:
                    seed_distribution[stream_idxs[idx]] = 1.0

            if (seed_distribution > 0).any():
                # Replace it and move on if there are still seedsin the pool.
                seed_distribution[:] /= np.sum(seed_distribution)

                stream_idxs[idx] = np.random.choice(n_seeds,
                                                    p=seed_distribution)

                streams[idx], stream_weights[idx] = generate_new_seed(
                    stream_idxs[idx], seed_pool, pool_weights,
                    seed_distribution, lam, with_replacement)

                stream_counts[idx] = 0

            else:
                # Otherwise, this one's exhausted.  Set its probability to 0
                stream_weights[idx] = 0.0

            weight_norm = np.sum(stream_weights)
Stochastic multiplexor for generator seeds.
dataset/ETHPy150Open bmcfee/pescador/pescador/util.py/mux