Skip to Content

SIR

Overview

The SIR function numerically solves the SIR (Susceptible-Infected-Recovered) system of ordinary differential equations, a classic model for infectious disease spread in a population. The SIR model describes the time evolution of three compartments:

  • Susceptible (SS): individuals who can contract the disease
  • Infected (II): individuals who are currently infected and can transmit the disease
  • Recovered (RR): individuals who have recovered and are immune

The system is governed by:

dSdt=βSINdIdt=βSINγIdRdt=γI\begin{align*} \frac{dS}{dt} &= -\beta \frac{S I}{N} \\ \frac{dI}{dt} &= \beta \frac{S I}{N} - \gamma I \\ \frac{dR}{dt} &= \gamma I \end{align*}

where N=S+I+RN = S + I + R is the total population, β\beta is the infection rate, and γ\gamma is the recovery rate. The function uses scipy.integrate.solve_ivp  to perform the integration, exposing only the most commonly used parameters for Excel users. The output includes a header row and a time column for clarity. This example function is provided as-is without any representation of accuracy.

Usage

To use the function in Excel:

=SIR(s_initial, i_initial, r_initial, beta, gamma, t_start, t_end, [timesteps], [solve_ivp_method])
  • s_initial (float, required): Initial number of susceptible individuals.
  • i_initial (float, required): Initial number of infected individuals.
  • r_initial (float, required): Initial number of recovered individuals.
  • beta (float, required): Infection rate parameter.
  • gamma (float, required): Recovery rate parameter.
  • t_start (float, required): Start time of integration.
  • t_end (float, required): End time of integration.
  • timesteps (integer, optional, default=10): Number of timesteps to solve for.
  • solve_ivp_method (string (enum), optional, default=RK45): Integration method (RK45, RK23, DOP853, Radau, BDF, LSODA).

The function returns a 2D table with a header row: t, S, I, R. Each subsequent row contains the time and corresponding values for susceptible, infected, and recovered individuals. If the input is invalid, an error message (string) is returned.

Examples

Example 1: Basic SIR Simulation

Inputs:

s_initiali_initialr_initialbetagammat_startt_endtimesteps
9901000.30.101010

Excel formula:

=SIR(990, 10, 0, 0.3, 0.1, 0, 10, 10)

Expected output:

tSIR
0.000990.00010.0000.000
1.111986.31812.4401.242
2.222981.76115.4532.786
3.333976.13519.1644.702
4.444969.20823.7177.075
5.556960.71329.27610.010
6.667950.34836.02713.625
7.778937.76944.16418.067
8.889922.60953.89223.499
10.000904.49465.39730.109

Example 2: RK23 Integration Method

Inputs:

s_initiali_initialr_initialbetagammat_startt_endtimestepsmethod
9901000.30.101010RK23

Excel formula:

=SIR(990, 10, 0, 0.3, 0.1, 0, 10, 10, "RK23")

Expected output:

tSIR
0.000990.00010.0000.000
1.111986.31912.4391.242
2.222981.76415.4522.785
3.333976.14019.1604.699
4.444969.22323.7077.070
5.556960.74029.26010.000
6.667950.38836.00113.611
7.778937.83644.12218.042
8.889922.70053.83523.466
10.000904.61465.32230.064

Example 3: Longer Simulation Time

Inputs:

s_initiali_initialr_initialbetagammat_startt_endtimesteps
9901000.30.105010

Excel formula:

=SIR(990, 10, 0, 0.3, 0.1, 0, 50, 10)

Expected output:

tSIR
0.000990.00010.0000.000
5.556960.71329.27610.010
11.111883.03678.86238.102
16.667719.319174.251106.430
22.222491.286275.392233.323
27.778299.172302.787398.041
33.333186.119258.033555.848
38.889127.446191.642680.912
44.44497.391132.333770.276
50.00081.20887.996830.795

Example 4: BDF Integration Method

Inputs:

s_initiali_initialr_initialbetagammat_startt_endtimestepsmethod
9901000.30.101010BDF

Excel formula:

=SIR(990, 10, 0, 0.3, 0.1, 0, 10, 10, "BDF")

Expected output:

tSIR
0.000990.00010.0000.000
1.111986.31812.4401.242
2.222981.76115.4532.786
3.333976.13319.1654.702
4.444969.20523.7187.077
5.556960.71029.27810.012
6.667950.34436.02613.630
7.778937.77044.15918.071
8.889922.61953.87923.502
10.000904.51565.37530.110

All outputs are rounded to 3 decimal places for display.

Python Code

from scipy.integrate import solve_ivp as scipy_solve_ivp import numpy as np def sir(s_initial, i_initial, r_initial, beta, gamma, t_start, t_end, timesteps=10, solve_ivp_method='RK45'): """ Solves the SIR system of ordinary differential equations for infection dynamics. Args: s_initial: Initial number of susceptible individuals (float). i_initial: Initial number of infected individuals (float). r_initial: Initial number of recovered individuals (float). beta: Infection rate parameter (float). gamma: Recovery rate parameter (float). t_start: Start time of integration (float). t_end: End time of integration (float). timesteps: Number of timesteps to solve for. Default is 10. solve_ivp_method: Integration method ('RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'). Default is 'RK45'. Returns: 2D list with header row: t, S, I, R. Each row contains time and variable values, or an error message (str) if input is invalid. This example function is provided as-is without any representation of accuracy. """ # Validate inputs try: s0 = float(s_initial) i0 = float(i_initial) r0 = float(r_initial) b = float(beta) g = float(gamma) t0 = float(t_start) tf = float(t_end) ntp = int(timesteps) except Exception: return "Invalid input: All initial values, parameters, and timesteps must be numbers." if any(x < 0 for x in [s0, i0, r0, b, g]): return "Invalid input: Initial values and parameters must be non-negative." if tf <= t0: return "Invalid input: t_end must be greater than t_start." if ntp <= 0: return "Invalid input: timesteps must be a positive integer." if solve_ivp_method not in ['RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA']: return "Invalid input: solve_ivp_method must be one of 'RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'." # Create time array for evaluation t_eval = np.linspace(t0, tf, ntp) # SIR ODE system def sir_ode(t, y): S, I, R = y N = S + I + R dSdt = -b * S * I / N dIdt = b * S * I / N - g * I dRdt = g * I return [dSdt, dIdt, dRdt] # Integrate try: sol = scipy_solve_ivp( sir_ode, [t0, tf], [s0, i0, r0], method=solve_ivp_method, t_eval=t_eval ) except Exception as e: return f"scipy.integrate.solve_ivp error: {e}" if not sol.success: return f"Integration failed: {sol.message}" # Return 2D list: header row, then each row is [t, S, I, R] at each time point header = ["t", "S", "I", "R"] result = [header] + [[float(sol.t[i]), float(sol.y[0][i]), float(sol.y[1][i]), float(sol.y[2][i])] for i in range(len(sol.t))] return result

Example Workbook

Link to Workbook 

Last updated on