def sample_from_probability_distribution( probability_distribution: dict, n_samples: int) -> collections.Counter: """ Samples events from a discrete probability distribution Args: probabilty_distribution: The discrete probability distribution to be used for sampling. This should be a dictionary n_samples (int): The number of samples desired Returns: A dictionary of the outcomes sampled. The key values are the things be sampled and values are how many times those things appeared in the sampling """ if isinstance(probability_distribution, dict): prob_pmf = lea.pmf(probability_distribution) sampled_dict: collections.Counter = collections.Counter( prob_pmf.random(n_samples)) return sampled_dict else: raise RuntimeError( "Probability distribution should be a dictionary with key value \ being the thing being sampled and the value being probability of getting \ sampled ")
def merge_distributions(parent_distribution, child_dictionary): result_dict = dict() for (key, key_prob) in parent_distribution.pmf_tuple: for (value, value_prob) in child_dictionary[key].pmf_tuple: result_dict[value] = result_dict.setdefault( value, 0.0) + key_prob * value_prob return lea.pmf(result_dict)
def variable_tests(shots, success_probability): if not isinstance(shots, lea.Lea): shots = lea.vals(shots) distribution = dict() for (n, p) in shots.pmf_tuple: single_distribution = lea.binom(n, success_probability) for (n_p, p_p) in single_distribution.pmf_tuple: distribution[n_p] = distribution.setdefault(n_p, 0.0) + (p * p_p) return lea.pmf(distribution)
def variable_damage_table(max_wounds, damage_die, wounds_per_model, flatten=True): result_dict = dict() if not isinstance(damage_die, lea.Lea): damage_die = lea.vals(damage_die) for i in range(0, max_wounds + 1): for j in range(wounds_per_model): if i > 0: damage_spread = lea.min_of(wounds_per_model - j, damage_die) temp_dict = dict() for (n, p) in damage_spread.pmf_tuple: temp_dict = merge_pmf_dicts( add_pmf_to_result( (n, p), result_dict[(i - 1, (j - n) % wounds_per_model)].pmf_tuple), temp_dict) result_dict[(i, j)] = lea.pmf(temp_dict) else: result_dict[(i, j)] = lea.vals(i) if flatten: return flatten_damage_dictionary(result_dict) return result_dict
def die(number_of_faces: int) -> Distribution: face_probability = 1 / number_of_faces die_ = lea.pmf({i + 1: face_probability for i in range(number_of_faces)}) return die_