def test_sum_stats_save_load(history: History): arr = sp.random.rand(10) arr2 = sp.random.rand(10, 2) particle_list = [ Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss1": .1, "ss2": arr2, "ss3": example_df(), "rdf0": r["iris"] }], [], True), Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss12": .11, "ss22": arr, "ss33": example_df(), "rdf": r["mtcars"] }], [], True) ] history.append_population(0, 42, Population(particle_list), 2, ["m1", "m2"]) weights, sum_stats = history.get_sum_stats(0, 0) assert (weights == 0.5).all() assert sum_stats[0]["ss1"] == .1 assert (sum_stats[0]["ss2"] == arr2).all() assert (sum_stats[0]["ss3"] == example_df()).all().all() assert (sum_stats[0]["rdf0"] == pandas2ri.ri2py(r["iris"])).all().all() assert sum_stats[1]["ss12"] == .11 assert (sum_stats[1]["ss22"] == arr).all() assert (sum_stats[1]["ss33"] == example_df()).all().all() assert (sum_stats[1]["rdf"] == pandas2ri.ri2py(r["mtcars"])).all().all()
def test_sum_stats_save_load(history: History): import scipy as sp arr = sp.random.rand(10) arr2 = sp.random.rand(10, 2) particle_population = [ ValidParticle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss1": .1, "ss2": arr2 }]), ValidParticle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss12": .11, "ss22": arr }]) ] history.append_population(0, 42, particle_population, 2, ["m1", "m2"]) weights, sum_stats = history.get_sum_stats(0, 0) assert (weights == 0.5).all() assert sum_stats[0]["ss1"] == .1 assert (sum_stats[0]["ss2"] == arr2).all() assert sum_stats[1]["ss12"] == .11 assert (sum_stats[1]["ss22"] == arr).all()
def test_sum_stats_save_load(history: History): arr = sp.random.rand(10) arr2 = sp.random.rand(10, 2) particle_list = [ Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss1": .1, "ss2": arr2, "ss3": example_df(), "rdf0": r["faithful"]}], # TODO: check why iris fails accepted_distances=[.1]), Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss12": .11, "ss22": arr, "ss33": example_df(), "rdf": r["mtcars"]}], accepted_distances=[.1])] history.append_population(0, 42, Population(particle_list), 2, ["m1", "m2"]) weights, sum_stats = history.get_weighted_sum_stats_for_model(0, 0) assert (weights == 0.5).all() assert sum_stats[0]["ss1"] == .1 assert (sum_stats[0]["ss2"] == arr2).all() assert (sum_stats[0]["ss3"] == example_df()).all().all() assert (sum_stats[0]["rdf0"] == pandas2ri.ri2py(r["faithful"])).all().all() assert sum_stats[1]["ss12"] == .11 assert (sum_stats[1]["ss22"] == arr).all() assert (sum_stats[1]["ss33"] == example_df()).all().all() assert (sum_stats[1]["rdf"] == pandas2ri.ri2py(r["mtcars"])).all().all()
def rand_pop_list(m: int): """ Create a population for model m, of random size >= 3. Parameters ---------- m: int the model number Returns ------- """ pop = [ Particle(m=m, parameter=Parameter({ "a": np.random.randint(10), "b": np.random.randn() }), weight=np.random.rand() * 42, sum_stat={ "ss_float": 0.1, "ss_int": 42, "ss_str": "foo bar string", "ss_np": np.random.rand(13, 42), "ss_df": example_df() }, distance=np.random.rand()) for _ in range(np.random.randint(10) + 3) ] return pop
def rand_pop(m: int): """ Parameters ---------- m: int the model number Returns ------- """ pop = [ Particle( m, Parameter({ "a": np.random.randint(10), "b": np.random.randn() }), sp.rand() * 42, [sp.rand()], [{ "ss_float": 0.1, "ss_int": 42, "ss_str": "foo bar string", "ss_np": sp.rand(13, 42), "ss_df": example_df() }], [], True) for _ in range(np.random.randint(10) + 3) ] return pop
def test_single_particle_save_load_np_int64(history: History): # Test if np.int64 can also be used for indexing # This is an important test!!! m_list = [0, np.int64(0)] t_list = [0, np.int64(0)] particle_list = [ Particle(m=0, parameter=Parameter({ "a": 23, "b": 12 }), weight=.2, accepted_sum_stats=[{ "ss": .1 }], accepted_distances=[.1]) ] history.append_population(0, 42, Population(particle_list), 2, [""]) for m in m_list: for t in t_list: df, w = history.get_distribution(m, t) assert w[0] == 1 assert df.a.iloc[0] == 23 assert df.b.iloc[0] == 12
def test_sum_stats_save_load(history: History): arr = np.random.rand(10) arr2 = np.random.rand(10, 2) particle_list = [ Particle(m=0, parameter=Parameter({ "a": 23, "b": 12 }), weight=.2, sum_stat={ "ss1": .1, "ss2": arr2, "ss3": example_df(), "rdf0": r["iris"] }, distance=.1), Particle(m=0, parameter=Parameter({ "a": 23, "b": 12 }), weight=.2, sum_stat={ "ss12": .11, "ss22": arr, "ss33": example_df(), "rdf": r["mtcars"] }, distance=.1) ] history.append_population(0, 42, Population(particle_list), 2, ["m1", "m2"]) weights, sum_stats = history.get_weighted_sum_stats_for_model(0, 0) assert (weights == 0.5).all() assert sum_stats[0]["ss1"] == .1 assert (sum_stats[0]["ss2"] == arr2).all() assert (sum_stats[0]["ss3"] == example_df()).all().all() with localconverter(pandas2ri.converter): assert (sum_stats[0]["rdf0"] == r["iris"]).all().all() assert sum_stats[1]["ss12"] == .11 assert (sum_stats[1]["ss22"] == arr).all() assert (sum_stats[1]["ss33"] == example_df()).all().all() with localconverter(pandas2ri.converter): assert (sum_stats[1]["rdf"] == r["mtcars"]).all().all()
def generate_valid_proposal( t: int, m: np.ndarray, p: np.ndarray, model_prior: RV, parameter_priors: List[Distribution], model_perturbation_kernel: ModelPerturbationKernel, transitions: List[Transition]): """Sample a parameter for a model. Parameters ---------- t: Population index to generate for. m: Indices of alive models. p: Probabilities of alive models. model_prior: The model prior. parameter_priors: The parameter priors. model_perturbation_kernel: The model perturbation kernel. transitions: The transitions, one per model. Returns ------- (m_ss, theta_ss): Model, parameter. """ # first generation if t == 0: # sample from prior m_ss = int(model_prior.rvs()) theta_ss = parameter_priors[m_ss].rvs() return m_ss, theta_ss # later generation # counter n_sample, n_sample_soft_limit = 0, 1000 # sample until the prior density is positive while True: if len(m) > 1: index = fast_random_choice(p) m_s = m[index] m_ss = model_perturbation_kernel.rvs(m_s) # theta_s is None if the population m_ss has died out. # This can happen since the model_perturbation_kernel # can return a model nr which has died out. if m_ss not in m: continue else: # only one model m_ss = m[0] theta_ss = Parameter(**transitions[m_ss].rvs().to_dict()) # check if positive under prior if (model_prior.pmf(m_ss) * parameter_priors[m_ss].pdf(theta_ss) > 0): return m_ss, theta_ss # unhealthy sampling detection n_sample += 1 if n_sample == n_sample_soft_limit: logger.warning( "Unusually many (model, parameter) samples have prior " "density zero. The transition might be inappropriate.")
def test_t_count(history: History): particle_list = [ Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss": .1}], accepted_distances=[.1])] for t in range(1, 10): history.append_population(t, 42, Population(particle_list), 2, ["m1"]) assert t == history.max_t
def rand_pop(m): pop = [ ValidParticle( m, Parameter({ "a": np.random.randint(10), "b": np.random.randn() }), 200, [.1], [{ "ss": .1 }]) for _ in range(np.random.randint(10) + 3) ] return pop
def test_t_count(history: History): particle_population = [ ValidParticle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }]) ] for t in range(1, 10): history.append_population(t, 42, particle_population, 2, ["m1"]) assert t == history.max_t
def test_total_nr_samples(history: History): particle_list = [ Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss": .1}], accepted_distances=[.1])] population = Population(particle_list) history.append_population(0, 42, population, 4234, ["m1"]) history.append_population(0, 42, population, 3, ["m1"]) assert 4237 == history.total_nr_simulations
def test_t_count(history: History): particle_list = [ Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }], [], True) ] for t in range(1, 10): history.append_population(t, 42, Population(particle_list), 2, ["m1"]) assert t == history.max_t
def setUp(self): self.d = Distribution( **{ "a": RV("randint", low=0, high=3 + 1), "b": Distribution( **{ "b1": RV("randint", low=0, high=3 + 1), "b2": RV("randint", low=0, high=3 + 1), } ), } ) self.d_plus_one = Distribution( **{ "a": RV("randint", low=1, high=1 + 1), "b": Distribution( **{ "b1": RV("randint", low=1, high=1 + 1), "b2": RV("randint", low=1, high=1 + 1), } ), } ) self.x_one = Parameter({"a": 1, "b": Parameter({"b1": 1, "b2": 1})}) self.x_zero = Parameter({"a": 0, "b": Parameter({"b1": 0, "b2": 0})}) self.x_two = Parameter({"a": 2, "b": Parameter({"b1": 2, "b2": 2})})
def test_save_no_sum_stats(history: History): """ Test that what has been stored can be retrieved correctly also when no sum stats are saved. """ particle_list = [] for _ in range(0, 6): particle = Particle( m=0, parameter=Parameter({"th0": np.random.random()}), weight=1.0 / 6, sum_stat={"ss0": np.random.random(), "ss1": np.random.random()}, distance=np.random.random(), ) particle_list.append(particle) population = Population(particle_list) # do not save sum stats # use the attribute first to make sure we have no typo print(history.stores_sum_stats) history.stores_sum_stats = False # test some basic routines history.append_population( t=0, current_epsilon=42.97, population=population, nr_simulations=10, model_names=[""], ) # just call history.get_distribution(0, 0) # test whether weights and distances returned correctly weighted_distances_h = history.get_weighted_distances() weighted_distances = population.get_weighted_distances() assert np.allclose( weighted_distances_h[['distance', 'w']], weighted_distances[['distance', 'w']], ) weights, sum_stats = history.get_weighted_sum_stats(t=0) # all particles should be contained nonetheless assert len(weights) == len(particle_list) for sum_stat in sum_stats: # should be empty assert not sum_stat history.get_population_extended()
def test_total_nr_samples(history: History): particle_population = [ ValidParticle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }]) ] history.append_population(0, 42, particle_population, 4234, ["m1"]) history.append_population(0, 42, particle_population, 3, ["m1"]) assert 4237 == history.total_nr_simulations
def test_t_count(history: History): particle_list = [ Particle( m=0, parameter=Parameter({"a": 23, "b": 12}), weight=1.0, sum_stat={"ss": 0.1}, distance=0.1, ) ] for t in range(1, 10): history.append_population(t, 42, Population(particle_list), 2, ["m1"]) assert t == history.max_t
def test_total_nr_samples(history: History): particle_list = [ Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }], [], True) ] population = Population(particle_list) history.append_population(0, 42, population, 4234, ["m1"]) history.append_population(0, 42, population, 3, ["m1"]) assert 4237 == history.total_nr_simulations
def test_single_particle_save_load(history: History): particle_list = [ Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss": .1}], accepted_distances=[.1]) ] history.append_population(0, 42, Population(particle_list), 2, [""]) df, w = history.get_distribution(0, 0) assert w[0] == 1 assert df.a.iloc[0] == 23 assert df.b.iloc[0] == 12
def test_single_particle_save_load(history: History): particle_list = [ Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }], [], True) ] history.append_population(0, 42, Population(particle_list), 2, [""]) df, w = history.get_distribution(0, 0) assert w[0] == 1 assert df.a.iloc[0] == 23 assert df.b.iloc[0] == 12
def test_total_nr_samples(history: History): particle_list = [ Particle( m=0, parameter=Parameter({"a": 23, "b": 12}), weight=1.0, sum_stat={"ss": 0.1}, distance=0.1, ) ] population = Population(particle_list) history.append_population(0, 42, population, 4234, ["m1"]) history.append_population(0, 42, population, 3, ["m1"]) assert 4237 == history.total_nr_simulations
def test_model_name_load_single_with_pop(history_uninitialized: History): h = history_uninitialized model_names = ["m1"] h.store_initial_data(0, {}, {}, {}, model_names, "", "", "") particle_list = [ Particle(m=0, parameter=Parameter({"a": 23, "b": 12}), weight=.2, accepted_sum_stats=[{"ss": .1}], accepted_distances=[.1])] h.append_population(0, 42, Population(particle_list), 2, model_names) h2 = History(h.db_identifier) model_names_loaded = h2.model_names() assert model_names == model_names_loaded
def sample_from_prior(self) -> Sample: sample = Sample(record_rejected=True) for sumstat, accepted in zip(self.sumstats, self.accepted_list): sample.append( Particle( m=0, parameter=Parameter({ 'p1': np.random.randint(10), 'p2': np.random.randn() }), weight=np.random.uniform(), sum_stat=sumstat, distance=np.random.uniform(), accepted=accepted, ), ) return sample
def test_single_particle_save_load(history: History): particle_list = [ Particle( m=0, parameter=Parameter({"a": 23, "b": 12}), weight=1.0, sum_stat={"ss": 0.1}, distance=0.1, ), ] history.append_population(0, 42, Population(particle_list), 2, [""]) df, w = history.get_distribution(0, 0) assert w[0] == 1 assert df.a.iloc[0] == 23 assert df.b.iloc[0] == 12
def test_model_name_load_single_with_pop(history_uninitialized: History): h = history_uninitialized model_names = ["m1"] h.store_initial_data(0, {}, {}, {}, model_names, "", "", "") particle_list = [ Particle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }], [], True) ] h.append_population(0, 42, Population(particle_list), 2, model_names) h2 = History(h.db_identifier) model_names_loaded = h2.model_names() assert model_names == model_names_loaded
def test_model_name_load_single_with_pop(history_uninitialized: History): h = history_uninitialized model_names = ["m1"] h.store_initial_data(0, {}, {}, {}, model_names, "", "", "") particle_list = [ Particle( m=0, parameter=Parameter({"a": 23, "b": 12}), weight=1.0, sum_stat={"ss": 0.1}, distance=0.1, ) ] h.append_population(0, 42, Population(particle_list), 2, model_names) h2 = History(h.db) model_names_loaded = h2.model_names() assert model_names == model_names_loaded
def rand_pop_list(m: int = 0, normalized: bool = True, n_sample: int = None): """ Create a population for model m, of random size >= 3. Parameters ---------- m: The model index normalized: Whether to normalize the population weight to 1. n_sample: Number of samples. Returns ------- List[Particle]: A list of particles """ if n_sample is None: n_sample = np.random.randint(10) + 3 pop = [ Particle( m=m, parameter=Parameter( {"a": np.random.randint(10), "b": np.random.randn()} ), weight=np.random.rand() * 42, sum_stat={ "ss_float": 0.1, "ss_int": 42, "ss_str": "foo bar string", "ss_np": np.random.rand(13, 42), "ss_df": example_df(), }, accepted=True, distance=np.random.rand(), ) for _ in range(n_sample) ] if normalized: total_weight = sum(p.weight for p in pop) for p in pop: p.weight /= total_weight return pop
def test_single_particle_save_load_np_int64(history: History): # Test if np.int64 can also be used for indexing # This is an important test!!! m_list = [0, np.int64(0)] t_list = [0, np.int64(0)] particle_population = [ ValidParticle(0, Parameter({ "a": 23, "b": 12 }), .2, [.1], [{ "ss": .1 }]) ] history.append_population(0, 42, particle_population, 2, [""]) for m in m_list: for t in t_list: df, w = history.get_distribution(m, t) assert w[0] == 1 assert df.a.iloc[0] == 23 assert df.b.iloc[0] == 12