def test_accumulate(): assert list(accumulate(add, [1, 2, 3, 4, 5])) == [1, 3, 6, 10, 15] assert list(accumulate(mul, [1, 2, 3, 4, 5])) == [1, 2, 6, 24, 120] assert list(accumulate(add, [1, 2, 3, 4, 5], -1)) == [-1, 0, 2, 5, 9, 14] def binop(a, b): raise AssertionError('binop should not be called') start = object() assert list(accumulate(binop, [], start)) == [start]
def sequential_p_values( data: np.ndarray, null_probabilities: np.ndarray, dirichlet_probability=None, dirichlet_concentration=10000, ) -> np.ndarray: """ Accumulates sequential p-values after every datapoint Parameters ---------- data : np.ndarray Data i.e. [[0, 1], [1, 0], ...] or [[10, 12], [14, 3], ...] null_probabilities : np.ndarray The expected traffic allocation probability, where the values must sum to 1. Note the order must match the order of data. dirichlet_probability : np.ndarray The mean of the dirichlet distribution, subject to elements summing to 1. dirichlet_concentration : float How tightly the prior concentrates around the mean. Returns ------- np.ndarray Sequential p-value after every datapoint. """ data = np.array(data) if not _validate_data(data): raise TypeError("Data is supposed to be an array of integer arrays") bayes_factors = sequential_bayes_factors(data, null_probabilities, dirichlet_probability, dirichlet_concentration) inverse_bayes_factors = 1 / bayes_factors return list(accumulate(min, inverse_bayes_factors, 1))
def sequential_posteriors( data: np.ndarray, null_probabilities: np.ndarray, dirichlet_probability=None, dirichlet_concentration=10000, prior_odds=1, ) -> List[dict]: """ Accumulates the posteriors and marginal likelihoods for each datapoint. Parameters ---------- data : List[tuple] Data. null_probabilities : np.ndarray The expected traffic allocation probability, where the values must sum to 1. Note the order must match the order of data. dirichlet_probability : np.ndarray The mean of the dirichlet distribution, subject to elements summing to 1. dirichlet_concentration : float How tightly the prior concentrates around the mean. Returns ------- List[dict] Posterior distribution and marginal likelihoods at every datapoint. Examples -------- For unit-level data, we can use sequential_posteriors like so: >>> data = np.array([[1, 0, 0], [0, 1, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]]) >>> null_probabilities = [0.4, 0.4, 0.2] >>> list_dict = sequential_posteriors(data, null_probabilities) For time-aggregated data, we can pass in tuples that represent the aggregated count during that time: >>> data = np.array([[20, 17, 9], [18, 21, 8], [4, 6, 4], [18, 19, 11]]) >>> null_probabilities = [0.4, 0.4, 0.2] >>> list_dict = sequential_posteriors(data, null_probabilities) """ data = np.array(data) if not _validate_data(data): raise TypeError("Data is supposed to be an array of integer arrays") null_probabilities = np.array(null_probabilities) if dirichlet_probability is None: dirichlet_probability = null_probabilities dirichlet_alpha = dirichlet_probability * dirichlet_concentration acc = { const.LOG_POSTERIOR_ODDS: np.log(prior_odds), const.POSTERIOR_ODDS: prior_odds, const.LOG_BAYES_FACTOR: 0, const.BAYES_FACTOR: 1, const.P_VALUE: 1, const.POSTERIOR_PROBABILITY: posterior_probability(prior_odds), const.LOG_MARGINAL_LIKELIHOOD_M1: 0, const.LOG_MARGINAL_LIKELIHOOD_M0: 0, const.POSTERIOR_M1: dirichlet_alpha, const.POSTERIOR_M0: null_probabilities, } return list(accumulate(accumulator, data, acc))[1:]
def test_accumulate_works_on_consumable_iterables(): assert list(accumulate(add, iter((1, 2, 3)))) == [1, 3, 6]
def test_accumulate(): assert list(accumulate(add, [1, 2, 3, 4, 5])) == [1, 3, 6, 10, 15] assert list(accumulate(mul, [1, 2, 3, 4, 5])) == [1, 2, 6, 24, 120]
#!/usr/bin/env python3 from toolz.itertoolz import accumulate, frequencies with open('input', 'r') as f: inp = f.readline().strip().split(',') def total_movement(counts): straight = counts['nw'] - counts['se'] left = counts['sw'] - counts['ne'] right = counts['n'] - counts['s'] straight += left right -= left return abs(straight + right) print(total_movement(frequencies(inp))) counts = {dir: 0 for dir in ['n', 'nw', 'ne', 's', 'sw', 'se']} def single_count(counts, direction): counts[direction] += 1 return counts.copy() print(max(map(total_movement, accumulate(single_count, inp, counts))))