Exemplo n.º 1
0
def test_apply_many_flows():
    """
    Expect multiple flows to operate independently and produce the correct final flow rate.
    """
    model = CompartmentalModel(times=[0, 5],
                               compartments=["S", "I", "R"],
                               infectious_compartments=["I"])
    model.set_initial_population(distribution={"S": 900, "I": 100})
    model.add_death_flow("infection_death", 0.1, "I")
    model.add_universal_death_flows("universal_death", 0.1)
    model.add_infection_frequency_flow("infection", 0.2, "S", "I")
    model.add_sojourn_flow("recovery", 10, "I", "R")
    model.add_transition_flow("vaccination", 0.1, "S", "R")
    model.add_crude_birth_flow("births", 0.1, "S")
    model._prepare_to_run()
    actual_flow_rates = model._get_compartment_rates(model.initial_population,
                                                     0)

    # Expect the effects of all these flows to be linearly superimposed.
    infect_death_flows = np.array([0, -10, 0])
    universal_death_flows = np.array([-90, -10, 0])
    infected = 900 * 0.2 * (100 / 1000)
    infection_flows = np.array([-infected, infected, 0])
    recovery_flows = np.array([0, -10, 10])
    vaccination_flows = np.array([-90, 0, 90])
    birth_flows = np.array([100, 0, 0])
    expected_flow_rates = (infect_death_flows + universal_death_flows +
                           infection_flows + recovery_flows +
                           vaccination_flows + birth_flows)
    assert_array_equal(actual_flow_rates, expected_flow_rates)
Exemplo n.º 2
0
def test_apply_flows__with_function_flow__expect_flows_applied(
        inf_pop, sus_pop, exp_flow):
    """
    Expect a flow to occur proportional to the result of `get_flow_rate`.
    """
    def get_flow_rate(flow, comps, comp_vals, flows, flow_rates, time):
        _, i_pop, _ = comp_vals
        i_flow, _ = flow_rates
        return i_pop + i_flow

    model = CompartmentalModel(times=[0, 5],
                               compartments=["S", "I", "R"],
                               infectious_compartments=["I"])
    model.set_initial_population(distribution={"S": sus_pop, "I": inf_pop})
    model.add_transition_flow("infection", 0.1, "S", "I")
    model.add_function_flow("treatment", get_flow_rate, "I", "S")
    model._prepare_to_run()
    actual_flow_rates = model._get_compartment_rates(model.initial_population,
                                                     0)
    expected_infected = sus_pop * 0.1
    expected_flow_rates = np.array([
        exp_flow - expected_infected,
        expected_infected - exp_flow,
        0,
    ])

    assert_array_equal(actual_flow_rates, expected_flow_rates)
Exemplo n.º 3
0
def test_apply_flows__with_transition_flow__expect_flows_applied(
        inf_pop, sus_pop, exp_flow):
    """
    Expect a flow to occur proportional to the compartment size and parameter.
    """
    model = CompartmentalModel(times=[0, 5],
                               compartments=["S", "I"],
                               infectious_compartments=["I"])
    model.set_initial_population(distribution={"S": sus_pop, "I": inf_pop})
    model.add_transition_flow("deliberately_infected", 0.1, "S", "I")
    model._prepare_to_run()
    actual_flow_rates = model._get_compartment_rates(model.initial_population,
                                                     0)
    # Expect sus_pop * 0.1 = exp_flow
    expected_flow_rates = np.array([-exp_flow, exp_flow])
    assert_array_equal(actual_flow_rates, expected_flow_rates)
Exemplo n.º 4
0
def test_flow_derived_outputs():
    model = CompartmentalModel(
        times=[0, 5], compartments=["S", "I", "R"], infectious_compartments=["I"]
    )
    model.set_initial_population(distribution={"S": 900, "I": 100})

    # Constant entry.
    model.add_importation_flow("imports", num_imported=2, dest="S")
    model.request_output_for_flow(name="importation", flow_name="imports")
    model.request_output_for_flow(name="importation_raw", flow_name="imports", raw_results=True)

    # Linear entry.
    model.add_importation_flow("imports_land", num_imported=lambda t: 3 * t, dest="S")
    model.request_output_for_flow(name="importation_land", flow_name="imports_land")

    # Quadratic entry.
    model.add_importation_flow("imports_air", num_imported=lambda t: t ** 2, dest="S")
    model.request_output_for_flow(name="importation_air", flow_name="imports_air")

    # Fractional transition flow
    model.add_transition_flow("recovery", 0.1, "I", "R")
    model.request_output_for_flow(name="recovery_raw", flow_name="recovery", raw_results=True)
    model.request_output_for_flow(name="recovery_delta", flow_name="recovery", raw_results=False)

    model.run()
    dos = model.derived_outputs

    # Raw outputs are the instantaneous flow rate at a given time.
    assert_allclose(dos["recovery_raw"], model.outputs[:, 1] * 0.1, rtol=0.01)

    # Post-processed outputs reflect changes in compartment size.
    recovered_count = np.zeros_like(model.outputs[:, 2])
    recovered_count[1:] = np.diff(model.outputs[:, 2])
    assert_allclose(dos["recovery_delta"][1:], recovered_count[1:], rtol=0.01)

    # Good match for constant
    assert_array_equal(dos["importation"][1:], np.array([2, 2, 2, 2, 2]))
    assert_array_equal(dos["importation_raw"], np.array([2, 2, 2, 2, 2, 2]))

    # Good match for linear
    assert_allclose(dos["importation_land"][1:], np.array([1.5, 4.5, 7.5, 10.5, 13.5]))
    # So-so match for quadratic
    assert_allclose(dos["importation_air"][1:], np.array([0.5, 2.5, 6.5, 12.5, 20.5]), rtol=0.1)