← Deterministic Models

05

Time grids, lists and NumPy arrays

A numerical epidemic model needs a sequence of time points and a place to store the compartment values at those times. This lesson prepares those structures without yet solving the SIR equations.

Biological scenario

We want to prepare an SIR simulation covering 5 days, with values recorded every 0.5 day. The initial state is \(S(0)=4985\), \(I(0)=12\) and \(R(0)=3\).

How can Python represent the observation times and reserve matching storage for the three compartment histories?

From continuous time to a time grid

The mathematical model describes continuous time, but a numerical program stores results at selected time points:

0
0.5
1.0
1.5
2.0
…
5.0

If \(t_0=0\) and \(\Delta t=0.5\), then

\[t_n=t_0+n\Delta t.\]

There are 10 intervals but 11 stored time points because both the starting and ending times are included.

Python lists

A list stores an ordered collection of values. Square brackets create a list:

observation_days = [0, 1, 2, 3]
infected_counts = [12, 14, 17, 21]
Index 012
Index 114
Index 217
Index 321
Nextappend
  • Python indexing begins at 0, so infected_counts[0] is 12.
  • len(infected_counts) returns the number of stored values.
  • infected_counts.append(26) adds 26 to the end.
  • The time list and infected-count list must have equal lengths if their entries correspond.

Why use NumPy arrays?

Python list

infected = [12, 14, 17, 21]

Flexible general-purpose container. Useful for collecting values gradually.

NumPy array

infected = np.array([12, 14, 17, 21])

Numerical container designed for efficient scientific calculations on many values.

For example, an array can divide every entry in one operation:

infected_proportion = infected / N

A Python list does not perform this numerical operation in the same way.

Important NumPy tools

CodePurposeImportant condition
import numpy as npLoads NumPy and gives it the short name np.NumPy must be available in the Python environment.
np.array(values)Converts supplied values into a NumPy array.Numerical model arrays should normally contain compatible number types.
np.linspace(start, end, points)Creates equally spaced values including both endpoints.points is the number of stored values, not the number of intervals.
np.full(length, np.nan)Creates storage filled with missing-value markers.np.nan means “not yet assigned a numerical value.”
array.shapeReports the dimensions of an array.A one-dimensional array with 11 values has shape (11,).
array.dtypeReports the stored numerical data type.Arrays containing np.nan use a floating-point type.

Construct a reliable time grid

Step 1: Calculate intervals and points

number_of_steps = int(round((end_time - start_time) / dt))
number_of_points = number_of_steps + 1

Ten half-day intervals cover 5 days. Adding one includes the initial time point.

Step 2: Create the time array

time = np.linspace(start_time, end_time, number_of_points)

linspace is short for linearly spaced values.

Step 3: Create matching compartment arrays

S = np.full(number_of_points, np.nan)
I = np.full(number_of_points, np.nan)
R = np.full(number_of_points, np.nan)

Each compartment array has exactly one storage position for every time point.

Step 4: Store the initial conditions at index 0

S[0] = 4985
I[0] = 12
R[0] = 3

Index 0 corresponds to \(t=0\). Later, a numerical method will calculate and store the remaining values.

Run the complete preparation program

Interactive PythonTime grid and SIR storage

Output

Run the code to see the result.

Expected outcome

IndexTimeSIR
00.04985.012.03.0
10.5nannannan
21.0nannannan
31.5nannannan
42.0nannannan

The arrays are prepared but the epidemic has not yet been solved. Only index 0 contains the initial conditions. The nan entries deliberately mark future values that a numerical method still needs to calculate.

Lists and arrays in a modelling workflow

  • Use a list when values are being collected flexibly or may contain different kinds of information.
  • Use a NumPy array for organised numerical calculations with a fixed shape.
  • Corresponding time and compartment arrays must have equal lengths.
  • Index \(n\) connects time[n], S[n], I[n] and R[n].
  • The time-step size and the spacing of the time array must agree.

Try it yourself

Change end_time = 5 to end_time = 10 while keeping dt = 0.5.

  1. Predict the new number of intervals.
  2. Predict the new number of stored points.
  3. Run the program.
  4. Check the array shape and explain why it contains one more value than the number of intervals.