Example #1
0
    def test_quadratic_processes(self):

        S, E, I, R = sympy.symbols("S E I R")
        epi = SymbolicEpiModel([S, E, I, R])
        quadratic_rates = [I * S]
        quadratic_events = [Matrix([[-1, +1, 0, 0]])]
        epi.add_transmission_processes([
            (S, I, 1, I, E),
        ])
        for r0, r1 in zip(quadratic_rates, epi.quadratic_rate_functions):
            assert (r0 == r1)
        for e0, e1 in zip(quadratic_events, epi.quadratic_event_updates):
            assert (all([_e0 == _e1 for _e0, _e1 in zip(e0, e1)]))
Example #2
0
def symbolic_simulation_temporally_forced():
    from epipack import SymbolicEpiModel
    import sympy as sy
    from epipack.plottools import plot
    import numpy as np

    S, I, R, eta, rho, omega, t, T = \
            sy.symbols("S I R eta rho omega t T")

    N = 1000
    SIRS = SymbolicEpiModel([S,I,R],N)\
        .set_processes([
            (S, I, 3+sy.cos(2*sy.pi*t/T), I, I),
            (I, rho, R),
            (R, omega, S),
        ])

    SIRS.set_parameter_values({
        rho: 1,
        omega: 1 / 14,
        T: 100,
    })
    SIRS.set_initial_conditions({S: N - 100, I: 100})
    _t = np.linspace(0, 150, 1000)
    result = SIRS.integrate(_t)
    t_sim, result_sim = SIRS.simulate(max(_t))

    ax = plot(_t, result)
    plot(t_sim, result_sim, ax=ax)
    ax.get_figure().savefig('symbolic_model_time_varying_rate.png', dpi=300)
Example #3
0
    def test_stochastic_well_mixed(self):

        S, E, I, R = sympy.symbols("S E I R")

        N = 75000
        tmax = 100
        model = SymbolicEpiModel([S, E, I, R], N)
        model.set_processes([
            (S, I, 2, E, I),
            (I, 1, R),
            (E, 1, I),
        ])
        model.set_initial_conditions({S: N - 100, I: 100})

        tt = np.linspace(0, tmax, 10)
        result_int = model.integrate(tt)

        t, result_sim = model.simulate(tmax,
                                       sampling_dt=1,
                                       return_compartments=[S, R])

        for c, res in result_sim.items():
            #print(c, np.abs(1-res[-1]/result_int[c][-1]))
            #print(c, np.abs(1-res[-1]/result_sim[c][-1]))
            assert (np.abs(1 - res[-1] / result_int[c][-1]) < 0.05)
Example #4
0
    def test_linear_rates(self):

        S, E, I, R = sympy.symbols("S E I R")
        epi = SymbolicEpiModel([S, E, I, R])
        epi.add_transition_processes([
            (E, 1, I),
            (I, 1, R),
        ])
        linear_rates = [E, I]
        linear_events = [Matrix([[0, -1, +1, 0]]), Matrix([[0, 0, -1, +1]])]
        for r0, r1 in zip(linear_rates, epi.linear_rate_functions):
            assert (r0 == r1)
        for e0, e1 in zip(linear_events, epi.linear_event_updates):
            assert (all([_e0 == _e1 for _e0, _e1 in zip(e0, e1)]))
Example #5
0
    def test_time_dependent_rates(self):

        B, t = sympy.symbols("B t")
        epi = SymbolicEpiModel([B])
        epi.add_fission_processes([
            (B, t, B, B),
        ])
        epi.set_initial_conditions({B: 1})
        result = epi.integrate([0, 3], adopt_final_state=True)
        assert (np.isclose(epi.y0[0], np.exp(3**2 / 2)))
        epi.set_initial_conditions({B: 1})
        result = epi.integrate(np.linspace(0, 3, 10000),
                               integrator='euler',
                               adopt_final_state=True)
        eul = epi.y0[0]
        real = np.exp(3**2 / 2)
        assert (np.abs(1 - eul / real) < 1e-2)
Example #6
0
    def test_interactive_integrator(self):
        S, I, R, R0, tau, omega = sympy.symbols("S I R R_0 tau omega")

        I0 = 0.01
        model = SymbolicEpiModel([S,I,R])\
             .set_processes([
                    (S, I, R0/tau, I, I),
                    (I, 1/tau, R),
                    (R, omega, S),
                ])\
             .set_initial_conditions({S:1-I0, I:I0})

        parameters = {
            R0: LogRange(min=0.1, max=10, step_count=1000),
            tau: Range(min=0.1, max=10, value=8.0),
            omega: 1 / 14
        }

        t = np.linspace(0.01, 200, 1000)
        integrator = InteractiveIntegrator(model,
                                           parameters,
                                           t,
                                           figsize=(3, 4),
                                           return_compartments=[S, I])

        keys = sorted([str(k) for k in integrator.sliders.keys()])
        assert (all([a == b for a, b in zip(sorted(['R_0', 'tau']), keys)]))

        integrator.update_parameters()

        keys = sorted([str(k) for k in integrator.lines.keys()])
        assert (all([a == b for a, b in zip(sorted(['I', 'S']), keys)]))

        class change():
            new = True

        integrator.update_xscale(change())
        assert (integrator.ax.get_xscale() == 'log')
        assert (integrator.ax.get_yscale() == 'linear')
        integrator.update_yscale(change())
        assert (integrator.ax.get_xscale() == 'log')
        assert (integrator.ax.get_yscale() == 'log')

        integrator = InteractiveIntegrator(model,
                                           parameters,
                                           t,
                                           figsize=(3, 4))
        keys = sorted([str(k) for k in integrator.lines.keys()])
        assert (all([
            a == b
            for a, b in zip(sorted([str(C) for C in model.compartments]), keys)
        ]))
Example #7
0
    def test_basic_analytics(self):
        S, I, R, eta, rho, omega, t = symbols("S I R eta rho omega, t")

        SIRS = SymbolicEpiModel([S, I, R])

        SIRS.set_processes([
            #### transmission process ####
            # S + I (eta)-> I + I
            (S, I, eta, I, I),

            #### transition processes ####
            # I (rho)-> R
            # R (omega)-> S
            (I, rho, R),
            (R, omega, S),
        ])

        odes = SIRS.ODEs()

        expected = [
            Eq(Derivative(S, t), -I * S * eta + R * omega),
            Eq(Derivative(I, t), I * (S * eta - rho)),
            Eq(Derivative(R, t), I * rho - R * omega)
        ]

        assert (all([got == exp for got, exp in zip(odes, expected)]))

        fixed_points = SIRS.find_fixed_points()
        expected = FiniteSet((S, 0, 0), (rho / eta, R * omega / rho, R))

        assert (all([got == exp for got, exp in zip(fixed_points, expected)]))

        J = SIRS.jacobian()
        expected = Matrix([[-I * eta, -S * eta, omega],
                           [I * eta, S * eta - rho, 0], [0, rho, -omega]])
        N = SIRS.N_comp
        assert (all(
            [J[i, j] == expected[i, j] for i in range(N) for j in range(N)]))

        eig = SIRS.get_eigenvalues_at_disease_free_state()
        expected = {-omega: 1, eta - rho: 1, 0: 1}

        assert (all([v == expected[k] for k, v in eig.items()]))
Example #8
0
    def test_exceptions(self):

        B, mu, t = sympy.symbols("B mu t")
        epi = SymbolicEpiModel([B])
        epi.add_fission_processes([
            (B, mu, B, B),
        ])
        epi.set_initial_conditions({B: 1})

        self.assertRaises(ValueError, epi.integrate, [0, 1])

        self.assertRaises(ValueError, SymbolicEpiModel, [t])

        self.assertRaises(ValueError,
                          epi.get_eigenvalues_at_disease_free_state)
Example #9
0
    def test_adding_quadratic_processes(self):

        S, E, I, A, R, rho = sympy.symbols("S E I A R rho")
        epi = SymbolicEpiModel([S, E, I, A, R])

        epi.set_processes([
            (S, I, rho, I, E),
        ])
        epi.add_transmission_processes([
            (S, A, rho, A, E),
        ])
        quadratic_rates = [I * S * rho, S * A * rho]
        quadratic_events = [
            Matrix([[-1, +1, 0, 0, 0]]),
            Matrix([[-1, +1, 0, 0, 0]])
        ]
        for r0, r1 in zip(quadratic_rates, epi.quadratic_rate_functions):
            assert (r0 == r1)
        for e0, e1 in zip(quadratic_events, epi.quadratic_event_updates):
            assert (all([_e0 == _e1 for _e0, _e1 in zip(e0, e1)]))
Example #10
0
    def test_changing_population_size(self):

        A, B, C, t = sympy.symbols("A B C t")
        epi = SymbolicEpiModel([A, B, C],
                               10,
                               correct_for_dynamical_population_size=True)
        epi.set_initial_conditions({A: 5, B: 5})
        epi.set_processes([
            (A, B, 1, C),
        ], allow_nonzero_column_sums=True)

        dydt = epi.dydt()
        assert (dydt[0] == -1 * A * B / (A + B + C))

        _, res = epi.simulate(1e9)
        assert (res[C][-1] == 5)

        epi.set_processes([
            (None, 1 + sympy.log(1 + t), A),
            (A, 1 + sympy.log(1 + t), B),
            (B, 1 + sympy.log(1 + t), None),
        ],
                          allow_nonzero_column_sums=True)

        rates, comp_changes = epi.get_numerical_event_and_rate_functions()
        _, res = epi.simulate(200, sampling_dt=0.05)

        vals = np.concatenate([res[A][_ > 10], res[B][_ > 10]])
        rv = poisson(vals.mean())
        measured, bins = np.histogram(vals,
                                      bins=np.arange(10) - 0.5,
                                      density=True)
        theory = [
            rv.pmf(i) for i in range(0,
                                     len(bins) - 1) if measured[i] > 0
        ]
        experi = [
            measured[i] for i in range(0,
                                       len(bins) - 1) if measured[i] > 0
        ]
        # make sure the kullback-leibler divergence is below some threshold
        assert (entropy(theory, experi) < 2e-3)
        assert (np.median(res[A]) == 1)
Example #11
0
 def test_compartments(self):
     comps = sympy.symbols("S E I R")
     epi = SymbolicEpiModel(comps)
     assert (all(
         [i == epi.get_compartment_id(C) for i, C in enumerate(comps)]))
Example #12
0
    print()
    print(epi.ODEs())
    print(epi.find_fixed_points())

    omega = sympy.symbols("omega")
    epi = SymbolicSIRSModel(eta, rho, omega)
    print()
    print(epi.ODEs())
    print(epi.find_fixed_points())

    import sympy
    from epipack import SymbolicEpiModel

    S, I, eta, rho = sympy.symbols("S I eta rho")

    SIS = SymbolicEpiModel([S, I])
    SIS.add_transmission_processes([
        (I, S, eta, I, I),
    ])
    SIS.add_transition_processes([
        (I, rho, S),
    ])

    print(SIS.find_fixed_points())

    print(SIS.get_eigenvalues_at_fixed_point({S: 1}))

    print("==========")
    SIS = SymbolicEpiModel([S, I])
    SIS.set_processes([
        (I, S, eta / (1 - I), I, I),