# COVID-19 — Policy Simulator

COVID-19 — Policy Simulator

COVID-19 — Policy Simulator

Development of a COVID-19 Simulator

Jan Brugård, Ankit Naik, Malte Lenz, and Sergio Vargas

Wolfram MathCore

April 9, 2020

The Simulator

With the help of Wolfram System Modeler, the Wolfram Language and my wonderful colleagues (thanks for having patience with me) I have developed a COVID-19 — Policy Simulator. The ambition is not to give any precise numbers but to make it easier to understand how simple yet at the same time complicated it is to control a pandemic. This notebook is focused on the development of the simulator. There is a separate notebook focusing on the actual use of it.

While developing the simulator, I realized that my intuition was far from correct in many cases. I doubted the results more than one time and was sure there were mistakes in the model, but most of the time, it turned out that it was not the model faulting—it was my intuition. Will your intuition be better than mine? Download the newly released HighSchoolBiology Virtual Lab 1.1, open it, click “Herd Immunity” and then the “Try the Lab” button. This will start an installation process. Once finished, a lab notebook is open. You can now go back to this notebook to test your intuition!

I hope that using this simulator gives you a good idea of how complex it is to find the optimal path through a pandemic and also, to some extent, why a recipe that works in one country does not apply to another.

Important: This simulator is not exact. Many rather rough assumptions are made for several different reasons. Most of these , but not all, are mentioned and discussed below. In most cases, the simulator allows you to modify some of the assumptions by yourself.

Simulating the COVID-19 Pandemic

If you are not familiar with exponential growth, the natural reproduction number R0 and herd immunity, I recommend reading this post first.

As said, I will use the HighSchoolBiology Virtual Lab for all simulations in this post. Among other things, included in this virtual lab is a SIR model. This is the most fundamental compartmental model used in epidemiology. I will not explain the model in detail here; however, if you are interested, I recommend Robert Nachbar’s post Epidemiological Models for Influenza and COVID-19.

The most basic version of the model can be described like this:

Each person can either be susceptible (s), infected (i) or recovered (r). In this simple version the latter stage includes those unfortunate people that die too.

S = susceptible population (the part of the population that is not immune yet)

I = infected population

R = recovered population (including those that died)

I = infected population

R = recovered population (including those that died)

At any given point in time the total population, T, will be a sum of the three others:

T = S + I + R

or normalized:

1 = s + i + r

Note that in general, I will be using absolute values rather than proportions.

I will use Sweden as the example for this simulator as I am from Sweden. Therefore, I have more knowledge about what has been done here and how the country works, so I can put things into context. Furthermore, Sweden has a lot of data available, which makes it easier to get the underlying facts. Sweden's population is almost 10 million people:

In[]:=

CountryData["Sweden","Population"]

Out[]=

9910701

people

Let us start by simulating a situation with no vaccine available and where no specific policies are applied:

In[]:=

modelName="HighSchoolBiology.HerdImmunity.Exercises.NoVaccineModel";

Assuming R0 = 2.65, i.e. the mean value according to the believed range on April 1, 2020 (reference, note that the range was drastically changed on April 7), I use a mean infectious period of four days for now and start the simulation with one person infected:

In[]:=

sim=SystemModelSimulate[modelName,200,<|"ParameterValues"{"R0"2.65,"tau"4,"initialSusceptible"10000000-1,"initialInfected"1}|>];Column@{SystemModelPlot[sim,ImageSizeLarge,FillingAxis,AxesLabel{"days","people"}],SystemModelPlot[sim,"infected.n",ImageSizeLarge,FillingAxis,PlotRangeAll,AxesLabel{"days","people"},PlotStyleOrange]}

Out[]=

| |||||||||

In[]:=

Quiet@FindMaximum[sim["infected.n"][t],t]

Out[]=

{2.54876×,{t40.4}}

6

10

Note the huge number, around 2.5 million, of infected at day 40. Note that to keep the model as simple as possible, I am only considering those being in the infectious stage as infected, so in the simulation, people will move to the recovered state as soon as they are not infectious any longer. What would the same process look like if we change R0 to the lower range for COVID-19, i.e. 1.4?

In[]:=

sim=SystemModelSimulate[modelName,200,<|"ParameterValues"{"R0"1.4,"tau"4,"initialSusceptible"10000000-1,"initialInfected"1}|>];Column@{SystemModelPlot[sim,ImageSizeLarge,FillingAxis,AxesLabel{"days","people"}],SystemModelPlot[sim,"infected.n",ImageSizeLarge,PlotRangeAll,FillingAxis,AxesLabel{"days","people"},PlotStyleOrange]}

Out[]=

| |||||||||

It takes about 3.5 times longer for the outbreak to develop, and the peak is much lower but still big:

In[]:=

Quiet@FindMaximum[sim["infected.n"][t],t]

Out[]=

{453769.,{t145.7}}

What happens if, on top of this, we halve the mean infectious period, τ?

The maximum is the same, almost half a million; however, it is reached much faster, so we can see that both the natural reproduction number, R0, and the mean infectious period, τ, are important.

COVID-19 in Sweden

Sweden is sparsely populated, has the lowest number of people per household (i.e. many single-person households) and, as our chief epidemiologist Anders Tegnell put it, we are quite boring, i.e. socially distant by nature. All these and more factors probably mean that we have a relatively low R0; I would guess around 2. That said, I will still use the mean value of 2.65 as default in the simulator. You can modify this, as well as the other factors that I will be mentioning, as you like in the simulator.

Furthermore, It is hard to know how many cases of COVID-19 a country has had to date. Sweden had 5568 known cases on April 2; however, as is the case in most countries, we are only testing those that are sick enough to go to the hospital. However, a couple of days ago Anders Tegnell said that he expected Sweden to have more infected than the estimated 1% infected in Iceland (Swedish article), so I will guess 2% and that three quarters of those have passed the infectious stage.

A few days ago, the Public Health Agency of Sweden published this report (in Swedish only), which I will be using for most of my assumptions below. For instance, the report states that the mean infectious time is five days, so I will use that. Let us use these updated values to make a new simulation:

This looks much better. The number of infected is so small that we can hardly see it in the left-hand plot. Let’s see when we can expect the maximum number of cases:

The model predicts the peak in active cases at 51 days, so let’s compare that with the numbers in the report. Even though the report is in Swedish, the graphs can be easily understood even if you do not speak the language. The report has a lot of graphs from page 5 an onward. The graphs in the left-hand column show the forecasted increase in demand for hospital beds due to COVID-19 and the right-hand side has the critical cases. Each row represents a different region. If I, roughly, add the peak values for each region, I get a maximum of 2200 beds. However, the report has the peak for intensive care beds in about 65–80 days from now. Note though that the report is not defining the date for day 0 and is also making several assumptions that I have limited knowledge about, so it should be seen more as an example than a prediction. Nevertheless, I am taking the freedom to use it as is.

The report also shows the predicted need of intensive care beds. Using this, I can calculate a factor for the number of beds needed:

This suggests that around 3% of the infected will be in intensive care at the peak. Furthermore, the report states that each person in need of intensive care will need it for an average of between 10–14 days, so let’s use this to forecast the number in need of intensive care:

It shows that up to 1500 patients should need intensive care by now, but according to official data, it is 429. So why is this? The problem is that there is a delay in the system; it takes longer to leave than to enter the intensive care stage. To account for this I will update the model so it looks like this:

Each group of people is connected by different arrows, indicating a flow of people from one group to another. The plus sign on the infection arrow indicates a positive regulation of the infection rate, i.e. the more infected people the faster the infection rate (which is exactly why the infection becomes exponential).

This can be done by drag and drop using System Modeler or by using ConnectSystemModelComponents from the Wolfram Language:

I roughly set transition rates that give a behavior that replicates the example from the Public Health Authority:

The maximum is now at 63 days:

Remember, the report is not defining the date for day 0 , so even if the simulated top here is between 2–18 days ahead of the predictions from the Public Health Authority, it might be that they are actually expecting a top earlier than this simulation. As you have seen, I have made a lot of assumptions to get to this stage, so the similarities should not be taken as any form of proof that the simulator is showing the correct values. Quite the opposite; it most likely isn’t. However, the qualitative behavior is probably quite close to reality.

Including Policy and the Possibility of Vaccination

This far, I have used a model with no vaccine available and no possibility to set policies. The HighShoolBiology Virtual Library contains a model called PolicyImpactModel, which includes both vaccination and the possibility to simulate policy impact, so let us take a look at that:

Note that it is common to create a new group of people, “vaccinated,” to distinguish them from the recovered group, but in this, case I will omit it for simplicity.

However, I will modify it a bit and add the possibility for susceptible people to travel abroad and get infected there:

Of course, not everyone that travels abroad will return infected, but to keep the model simple, I will just consider the proportion that actually gets infected during their vacation or business trip:

A fantastic vaccine program with 50 000 vaccinations per day is initiated from day 0. Now, everything looks much better:

Different countries have taken different measures. I will look a some of the most common:

◼

Improved hygiene (washing hands, cough in elbow, don’t touch your face, etc.)

◼

Social distancing (keep away from each other, no handshaking, work from home, etc.)

◼

Isolate the sick (even stricter social distancing when you’re sick)

◼

Lockdown (close restaurants, schools, shops)

◼

Close borders

◼

Seasonal effect

There are tons of other measures, but these are the ones I chose to add to my simulator. The first three ones are basically what we have done in Sweden, while most other countries have taken quite a few other measures.

To get a rough idea of reasonable values for the first five, I will use my country Sweden. As we still have very few limits (only having gatherings up to 500 people and high school and college are taught remotely, but other than that, there are currently no restrictions).

Let’s start by looking at the growth of COVID-19 in Sweden thus far:

Taking the ratio on successive days gives an estimate for the current growth rate (typically referred to as R):

Note that as the testing strategy has changed over time, this will have an effect on the number; however, I believe it is roughly correct.

Assuming that all three have an equal effect, they would have a reducing factor of 1.34 each:

However, it is my understanding that the most important measure is hygiene. I will give this a default values of 1.5, leaving the two others at 1.27 each:

Lockdown, is basically a combination of the two latter strategies plus,hopefully, some additional effect; I will set the total effect to 1.7 (1.27*1.27 = 1.6).

As for seasonal effect, there is no reliable data at all at the moment. However, previous corona viruses have had a clear seasonal decay in Sweden, so I will use a high default value of 2.2.

For the vaccination, the default value is that 5% of the susceptible population is vaccinated per day when a vaccination program is active. Finally, whenever borders are open, some people arrive to the country infected.

It is obvious that the seasonal effect will not be constant over each season. The same goes for all other policies, their effect will not be constant as people will likely not follow them equally well over time. However, the simulator is advanced enough by now, so I will not consider these possible variations.

Remember that the simulator allows you to vary these assumptions, so you can try to adjust it to what you believe is happening in your country or region.

To summarize, I have made the following assumptions, have added three alternative versions (roughly estimated again) and assumed other start values for R0:

◼

Infection properties

◼

Policy effects

*Note that social distancing and isolating the sick have no effect during lockdown in the simulator.

There are several other factors that you might want to include, e.g. improved testing and tracking apps. You may, of course, use any other policy, e.g. the seasonal effect, for this purpose and add it to the code (if you manage to decrypt my coding).

Finally—The Simulator!

With all assumptions made, it is now finally time to create the simulator:

Note: The System Modeler functions needed for this Manipulate cannot be run in the Wolfram Cloud, so you will need to download both the HighSchoolBiology Virtual Lab and this notebook in order to use it. Open the virtual lab on your desktop, navigate to “Herd Immunity” and click the “Try the Lab” button. This will install the needed components for this Policy Simulator notebook and open a new notebook that can be used to try the lab (but isn’t needed for the Policy Simulator). Then open the Policy Simulator notebook on your desktop and re-evaluate it in order to use the Manipulate.