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, [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.
  • method (string, 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_endmethod
9901000.30.1010RK45

Excel formula:

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

Expected output:

tSIR
0.000990.00010.0000.000
0.001989.99610.0030.001
0.016989.95410.0310.016
0.157989.52710.3140.159
1.571984.54813.6111.841
6.066956.20032.22111.579
10.000904.49465.39730.109

Example 2: RK23 Integration Method

Inputs:

s_initiali_initialr_initialbetagammat_startt_endmethod
9901000.30.1010RK23

Excel formula:

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

Expected output:

tSIR
0.000990.00010.0000.000
0.001989.99610.0030.001
0.016989.95410.0310.016
0.157989.52710.3140.159
0.786987.47911.6710.850
1.841983.43814.3452.217
3.195976.90818.6554.438
4.756967.01625.1547.830
6.469952.38034.70712.913
8.318930.82048.63520.545
10.000904.61465.32230.064

Example 3: Longer Simulation Time

Inputs:

s_initiali_initialr_initialbetagammat_startt_endmethod
9901000.30.1050RK45

Excel formula:

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

Expected output:

tSIR
0.000990.00010.0000.000
0.001989.99610.0030.001
0.016989.95410.0310.016
0.157989.52710.3140.159
1.571984.54813.6111.841
6.066956.20032.22111.579
12.535850.22199.05650.722
21.257530.979261.666207.355
30.611232.342285.918481.740
40.187118.526176.649704.825
50.00081.20887.996830.795

Example 4: BDF Integration Method

Inputs:

s_initiali_initialr_initialbetagammat_startt_endmethod
9901000.30.1010BDF

Excel formula:

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

Expected output:

tSIR
0.000990.00010.0000.000
0.000989.99910.0000.000
0.000989.99910.0010.000
0.002989.99510.0030.002
0.003989.99110.0060.003
0.014989.96010.0270.014
0.024989.92810.0480.024
0.035989.89610.0690.035
0.131989.60510.2620.133
0.228989.30810.4590.233
0.324989.00510.6600.335
0.781987.49511.6610.845
1.238985.84512.7531.402
1.695984.04513.9442.011
2.152982.08015.2422.677
3.749973.70620.7625.532
5.347962.44028.1489.412
6.944947.42237.92214.656
8.542927.64750.66321.690
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 from typing import List, Union def sir( s_initial: float, i_initial: float, r_initial: float, beta: float, gamma: float, t_start: float, t_end: float, method: str = 'RK45' ) -> Union[List[List[float]], str]: """ 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). method: Integration method to use (str): 'RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'. Default is 'RK45'. Returns: 2D list of solution values for S, I, and R at each time point, 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) except Exception: return "Invalid input: All initial values and parameters 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 method not in ['RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA']: return "Invalid input: method must be one of 'RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'." # 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=method ) 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