SEIR
seir_model = {
"simulation": { // (1)
"n_simulations": 1000000, // (2)
"n_executions": 1, // (3)
"n_steps": 230 // (4)
},
"compartments": { // (5)
"S": {
"initial_value": 1, // (6)
"minus_compartments": "I" // (7)
},
"E": { "initial_value": 0 },
"I": {
"initial_value": "Io", // (8)
},
"R": { "initial_value": 0 },
},
"params": { // (9)
"betta": {
"min": 0.1, // (10)
"max": 0.3
},
"Io": {
"min": 1e-6,
"max": 1e-4
}
},
"fixed_params": { // (11)
"K_mean": 1,
"mu": 0.07,
"eta":0.08
},
"reference": { // (12)
"compartments" : ["R"]
},
"results": {
"save_percentage": 0.01 // (13)
}
}
- Here we define simulation parameters
- How many simulations to do in parallel each execution
- Number of times the simulation runs
-
Number of times the evolution function is executed each simulation
-
Here we define the compartments of the model. Each field must be unique
- Initial value set to a fixed number
- You subtract the value of other compartments after all of them are initialized
-
You can set the initial value of compartments as parameters
-
Here we define parameters that will be randomly generated for each simulation. Each field must be unique
-
A min value and max value must be set for each parameter
-
Definition of constant for all the simulations
-
Definition of which compartments the results should be compared with
-
Percentage of simulations that will be saved. The best of course
Now we need to define the evolution function of the system and assign it to the model:
import compartmental as gcm
gcm.use_numpy()
# gcm.use_cupy() # For GPU usage
SeirModel = gcm.GenericModel(seir_model)
def evolve(m, *args, **kargs):
p_infected = m.betta * m.K_mean * m.I
m.R += m.mu * m.I
m.I += m.E * m.eta - m.I * m.mu
m.E += m.S * p_infected - m.E * m.eta
m.S -= m.S * p_infected
SeirModel.evolve = evolve
Once the model is defined and the evolution function is set we can create a trajectory of the model. We can set specific values for the random parameters as follows:
sample, sample_params = gcm.util.get_model_sample_trajectory(
SeirModel,
**{"betta": 0.2, "Io":6e-5}
)
sample
yields:
import matplotlib.pyplot as plt
plt.plot(sample[SeirModel.compartment_name_to_index["S"]], 'green')
plt.plot(sample[SeirModel.compartment_name_to_index["E"]], 'red')
plt.plot(sample[SeirModel.compartment_name_to_index["I"]], 'orange')
plt.plot(sample[SeirModel.compartment_name_to_index["R"]], 'brown')
plt.show()
Now we can use the sample
and try to infer the values of \(\beta\) and \(Io\).
seir.data
file. We load them, compute the weights and the percentiles 30
and 70
with:
results = gcm.util.load_parameters("seir.data")
weights = numpy.exp(-results[0]/numpy.min(results[0]))
percentiles = gcm.util.get_percentiles_from_results(SeirModel, results, 30, 70)
Finally plot the reference values with the percentiles and histograms for the parameters \(\beta\) and \(Io\) (the red line indicates the value used for the reference):
plt.figure()
plt.fill_between(numpy.arange(percentiles.shape[2]), percentiles[0,0], percentiles[0,2], alpha=0.3)
plt.plot(sample[SeirModel.compartment_name_to_index["R"]], 'black')
plt.plot(numpy.arange(percentiles.shape[2]), percentiles[0,1], '--', color='purple')
fig, *axes = plt.subplots(1, len(results)-1)
for i, ax in enumerate(axes[0], 1):
ax.hist(results[i], weights=weights)
ax.vlines(sample_params[i-1], *ax.get_ylim(), 'red')
plt.show()