Epidemiological models for Influenza and COVID-19

MODERATOR NOTE: coronavirus resources & updates: https://wolfr.am/coronavirus


Recent updates:

DOWNLOAD-DESKTOP-NOTEBOOK.nb (3.65 MB)

29 Likes

Thanks, your work has helped me to understand this better. Instead of relatively closed compartments, have you done any modeling of spread of disease through contact networks? Quarantine measures work backwards through networks from index cases to exposed cases, with the ultimate goal of limiting the disease space to the size of infected plus exposed network and hopefully eliminating contact with this space to the healthy network space. Information about the disease can spread much more quickly than the disease. In the internet age there might be a role for social media networks to offer messaging to close contacts to limit the spread of even the common cold.

news-congrads-kkluyshnik-02-04-19.jpg – you have earned Featured Contributor Badge 2015-11-02_10-07-11.png

Your exceptional post has been selected for our editorial column Staff Picks http://wolfr.am/StaffPicks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you, keep it coming, and consider contributing to the The Notebook Archive!

A more manageable set of background notebooks is now available, starting with:

EpidemiologicalModelsForInfluenzaAndCOVID-19–part_1.nb

There is a TOC in each one to assist navigation among them.

1 Like

No, no modeling on networks yet.

You are quite right about the standard practice of tracing contact networks backwards in order to quarantine potentially exposed people. Unfortunately, those kind of data are not available for this pandemic. Martcheva gives a good description and model on pp. 230-234 of her book An Introduction to Mathematica Epidemiology.

Social media can play a role, and many people are posting constantly this week about steps to take to “flatten the curve”.

I greatly enjoyed your video presentation. It seemed that the size of the susceptible population made a big difference, which you explained as mixing being inefficient, and limiting by quarantine. I have been playing with a much simpler logistic model mainly to capture the day to day dynamics with the assumption that the epidemic can only be stopped with effective quarantine: Logistic Quarantine Model

The assumption is that the quarantine process is competing with the infection rate, but that the quarantine set can grow faster than the set of infected and exposed, such that the infected and exposed population is eventually contained in the quarantine set and that set becomes the limit to the susceptible set. I think if you incorporated this into your model, it could give a better estimate of the size of the susceptible set.

The model has worked with China. The graph below uses a very simple measure on the reported numbers. The daily differences of the log of the daily accumulated case numbers, i.e. the continuous growth rate, which should be horizontal if the number of cases grows exponentially.

The blue dots are the daily differences of log case number predicted by the logistic model on the last date of the data. Italy is shown below.

Once the actual data closes in on the predicted, the quarantine has successfully limited the susceptible population. I suspect with refinement, your model might eventually be sensitive enough to discover other dynamics. For instance did the Chinese method of quarantine to put infected people together in close quarters increase the death rate because, while the people were infected, they may not have developed much of an immune response, and the quarantine method permitted reinfection causing higher viral titers. Household quarantine also may guarantee higher infection rates of household members than if the infected person were removed from the household. In the community where I live in rural central Arizona, the population has decided to remove itself from the general population. The nearest reported infection is a hundred miles away. The Walmart and two supermarkets have been emptied and people are staying at home. Fortunately we are surrounded by three million acres of National Forest, so there is plenty of room to go hiking.

Congratulations! This is a very interesting and useful introduction into a highly topical issue. Following the yesterday’s fascinating presentation of the models, I have tried unsuccessfully to run the notebook (Mathematica 12.1, Win 10 64). I am getting many error messages.
Please advise!

EpidemiologicalModelsForInfluenzaAndCOVID-19–part_1 - errors.nb (1.58 MB)

Thanks for your interest. Did you also download the package that’s mentioned at the beginning of the initialization section: https://www.wolframcloud.com/obj/rnachbar/Published/CompartmentalModeling.wl?

The code for KineticCompartmentalModel is in the package and that’s how the transitions are interpreted and the ODEs generated.

I’ll copy the notice about the package to the top of the notebook so it’s more obvious.

No, I had not downloaded the package.
I did now.
Thank you!

Very good modeling. I was wondering if you could take into account herd immunity— as the number of recovered individuals goes up, the transmission rate goes down. Once 70% of the population is exposed the rate of infection begins to drastically decrease. Hence it may take a long time for the last 30% to be become infected

Another factor to consider with the data is the sensitivity of the test— at best it is 60% and in real world testing 40%.

Hi Robert,

This was an excellent introduction and great modeling.
My question is this: It seems like the modeling is trying to determine a few parameters across the whole population, when in fact we know that the parameters vary by age group. Why not consider breaking down the model in to population groups of different ages, for instance 0-9 years, 10-19, 20-29, etc. In this way, factors such as total population, mortality, effective community size, etc, can be independently optimized. Then, the total number of infections, deaths, etc. can be summed over age groups.

Cheers,

-Kent

1 Like

Indeed, that is on my To Do list. I can easily get the age distribution for a country from Wolfram|Alpha, so that will help with the initial conditions. However, to estimate the values for an age-stratified parameter we really need the number of confirmed cases, recovered cases, and deaths broken down by age too. There are some data on deaths for various ages.

See the University of Basel model for an example using age groups. They use estimates based on an analysis of the recent data from China, and are not fitting them. Their interface allows the user to adjust them, also.

1 Like

Running the EpidemiologicalModelsForInfluenzaAndCOVID-19–part_1.nb gives many errors.
I have downloaded the CompartmentalModeling.wl file and put it in the notebook folder and load it inside the notebook also.

Example of the first error:

Running the code:

{susceptibleSEIR, infectedSEIR, exposedSEIR, 
   recoveredSEIR} = {\[ScriptCapitalS], \[ScriptCapitalI], \
\[ScriptCapitalE], \[ScriptCapitalR]} /. 
   ParametricNDSolve[
    Join[odesSEIR /. 
      forceOfInfectionSEIR, {\[ScriptCapitalS][
        0] == \[ScriptCapitalN] - I0, \[ScriptCapitalE][0] == 
       0, \[ScriptCapitalI][0] == I0, \[ScriptCapitalR][0] == 0}], 
    Head /@ varsSEIR, {t, 0, 100}, {\[ScriptCapitalN], 
     I0, \[Beta], \[Zeta], \[Gamma]}];

I get the errors:

ParametricNDSolve::dspar: 1.5` cannot be used as a parameter.
ReplaceAll::reps: {ParametricNDSolve[{(\[ScriptCapitalE]^\[Prime])[t]==0. -\[Zeta] \[ScriptCapitalE][t]+1.5 \[ScriptCapitalI][t] \[ScriptCapitalS][t],(\[ScriptCapitalI]^\[Prime])[t]==0. +\[Zeta] \[ScriptCapitalE][t]-0.0478 \[ScriptCapitalI][t],(\[ScriptCapitalR]^\[Prime])[t]==0. +0.0478 \[ScriptCapitalI][t],(\[ScriptCapitalS]^\[Prime])[t]==0. -1.5 \[ScriptCapitalI][t] \[ScriptCapitalS][t],\[ScriptCapitalS][0]==-I0+\[ScriptCapitalN],\[ScriptCapitalE][0]==0,\[ScriptCapitalI][0]==I0,\[ScriptCapitalR][0]==0},{\[ScriptCapitalE],\[ScriptCapitalI],\[ScriptCapitalR],\[ScriptCapitalS]},{t,0,100},{\[ScriptCapitalN],I0,1.5,\[Zeta],0.0478}]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing.
Set::shape: Lists {susceptibleSEIR,infectedSEIR,exposedSEIR,recoveredSEIR} and {\[ScriptCapitalS],\[ScriptCapitalI],\[ScriptCapitalE],\[ScriptCapitalR]}/. ParametricNDSolve[{(\[ScriptCapitalE]^\[Prime])[t]==0. -\[Zeta] \[ScriptCapitalE][t]+1.5 \[ScriptCapitalI][t] \[ScriptCapitalS][t],(\[ScriptCapitalI]^\[Prime])[t]==0. +\[Zeta] \[ScriptCapitalE][t]-0.0478 \[ScriptCapitalI][t],(\[ScriptCapitalR]^\[Prime])[t]==0. +0.0478 \[ScriptCapitalI][t],(\[ScriptCapitalS]^\[Prime])[t]==0. -1.5 \[ScriptCapitalI][t] \[ScriptCapitalS][t],\[ScriptCapitalS][0]==-I0+\[ScriptCapitalN],\[ScriptCapitalE][0]==0,\[ScriptCapitalI][0]==I0,\[ScriptCapitalR][0]==0},{\[ScriptCapitalE],\[ScriptCapitalI],\[ScriptCapitalR],\[ScriptCapitalS]},{t,0,100},{\[ScriptCapitalN],I0,1.5,\[Zeta],0.0478}] are not the same shape.

The package should be loaded automatically when the initialization cells are evaluated.

The Cloud notebook was accidentally edited yesterday, and I thought I had restored the changes to the original state, but I might have missed something.

I will test the whole notebook now. Thanks for reporting the problem.

Apparently you assigned the value 1.5 to the symbol [Beta] and 0.0478 to [Gamma]. I can reproduce your error messages when I do that. Also, if you look at the second message, you can see that the last argument to ParametricNDSolve is {\[ScriptCapitalN], I0, 1.5, \[Zeta], 0.0478}, which shows numeric values instead of symbols for [Beta] and [Gamma].

It would probably be best to quit and restart the Kernel to fix the problem.

Please let me know if you did not assign values to [Beta] and [Gamma], because that would suggest that the Manipulates are “leaking” dynamic assignments, which I made every effort to code against.

1 Like

Don’t worry everything are ok, my bad. :slight_smile: After including Clear[“Global`*”] at the start, everything runs fine.
Probably some leftovers from previous notebook.

Thanks for all of these very very good project!

thank you! - where can we find the notebook part_2 and other parts if any? thank you so much
Gerhard

The table of contents at the top of the first notebook (found here) has links to all the others.

thank you- Gerhard

Hi, I hope you are okay.
I want to applied your code to my data, How can I upload my data for it could have the same format as your data?