ODEModel

models.ODEModel(
    states,
    interventions,
    dynamics_and_rewards,
    horizon,
    discount_rate=0.03,
    method='RK45',
    rtol=1e-08,
    atol=1e-08,
    max_step=None,
    effect='qaly',
)

Ordinary differential equation (compartmental) model engine.

discount_rate is an annual rate discounted continuously, exp(-rate * t), the convention for continuous-time accrual. The horizon is in the same time units as the derivatives (years, by convention).

Parameters

Name Type Description Default
states Sequence[str] Compartment labels; their order fixes every array’s axis order. required
interventions InterventionSpec A sequence of intervention names or heormodel.models.Intervention objects, in the order they appear in Outcomes. An Intervention may carry parameter decision levers merged into params for that intervention. required
dynamics_and_rewards Callable[[pd.Series, str], ODESpec] fn(params, intervention) -> ODESpec returning the system and reward arrays for one intervention under one parameter set. params is a draw-matrix row (a pandas.Series); intervention is the intervention name. required
horizon float Length of the analytic time horizon, in years. required
discount_rate float Annual discount rate for costs and effects (0.03 by default), applied continuously. 0.03
method str Integration method passed to scipy.integrate.solve_ivp ("RK45" by default; "LSODA" switches automatically to a stiff solver when the dynamics stiffen). 'RK45'
rtol float Relative error tolerance for the integrator. 1e-08
atol float Absolute error tolerance for the integrator. 1e-08
max_step float | None Largest step the integrator may take, in years; None (the default) lets the solver choose. Set it to force the solver through a short-lived feature, such as a narrow epidemic peak, it might otherwise step over. None
effect str Name of the primary effect column (quality-adjusted life-years by default). 'qaly'

Example

import numpy as np, pandas as pd from heormodel.models.ode import ODEModel, ODESpec def dynamics_and_rewards(params, intervention): … k = params[“decay”] … return ODESpec( … derivatives=lambda t, y: np.array([-k * y[0], k * y[0]]), … initial=np.array([1.0, 0.0]), … state_cost=np.array([params[“cost”], 0.0]), … state_effect=np.array([1.0, 0.0])) engine = ODEModel( … states=(“alive”, “dead”), interventions=(“care”,), … dynamics_and_rewards=dynamics_and_rewards, horizon=10.0) draws = pd.DataFrame({“decay”: [0.1], “cost”: [1000.0]}, … index=pd.RangeIndex(1, name=“iteration”)) engine.evaluate(draws).interventions [‘care’]

Methods

Name Description
trajectory Compartment occupancy over the horizon for one parameter set.

trajectory

models.ODEModel.trajectory(params, intervention, *, n_points=200)

Compartment occupancy over the horizon for one parameter set.

A convenience for inspection and plotting (an epidemic curve, a vaccination-coverage path); it is not part of the engine contract and does not accrue costs or effects. evaluate is what produces Outcomes.

Parameters

Name Type Description Default
params pd.Series One draw-matrix row (a pandas.Series) of parameter values. required
intervention str The intervention name passed to dynamics_and_rewards. required
n_points int Number of evenly spaced time points returned over [0, horizon]. 200

Returns

Name Type Description
pd.DataFrame A DataFrame with a time column and one column per compartment.

Example

import numpy as np, pandas as pd from heormodel.models.ode import ODEModel, ODESpec def dynamics_and_rewards(params, intervention): … return ODESpec( … derivatives=lambda t, y: np.array([-0.1 * y[0], 0.1 * y[0]]), … initial=np.array([1.0, 0.0]), … state_cost=np.zeros(2), state_effect=np.array([1.0, 0.0])) engine = ODEModel(states=(“a”, “b”), interventions=(“s”,), … dynamics_and_rewards=dynamics_and_rewards, horizon=10.0) traj = engine.trajectory(pd.Series(dtype=float), “s”, n_points=3) list(traj.columns) [‘time’, ‘a’, ‘b’]

Back to top