header

Replication of Chari, Kirpalani, and Phelan (2021)

This project was conducted as a final assignment for the PhD course Numerical Methods at Bocconi University in Fall 2021.

This package replicates the main figures of Chari, Kirpalani, and Phelan (2021): "The hammer and the scalpel: On the economics of indiscriminate versus targeted isolation policies during pandemics", published in the Review of Economic Dynamics. The paper is available here, and the original replication material in Matlab here.

The authors develop a theoretical model that combines epidemic transmission and economic outcomes. They study the effect of different government responses, such as quarantining, testing, contact-tracing, and isolation.

Installation

This package is not listed as an official Julia package. If you wish to use it, you may clone this Github repository to your machine. You then have two options:

Use as a package: Start up Julia in the directory HammerScalpel.jl and go into the package editor by typing ]. Then, activate a new environment and install all necessary dependencies for HammerScalpel by typing

activate .
instantiate

After pressing backspace, go back into Julia's standard command mode and type

using HammerScalpel

The functions should now be ready to go.

Use as ordinary code: Play around with the files main.jl or main_parallel.jl, which run the code in sequential and parallelized form, respectively.

Using the package

If you wish run the replication from beginning to end, simply type

solveModel()

This will call all necessary functions in the correct order. Specifically, it first computes the no-intervention outcome using nopolicy, and the respective outcomes under the various policies using withpolicy. Then, it plots the evolution of the model under different policies over time using createFig5, createFig6, and createFig7.

Since solving the model may take a while, you have the option to run them more efficiently on multiple CPU cores at the same time. To do so, type

solveModel(nprocs)

where nprocs specifies the number of logical cores on your CPU.

If you just want to check my results without running the simulations yourself, you may use stored outcomes that I obtained under default parameters. You can recreate the figures by running

createFig5()
createFig6()
createFig7()

Documentation

HammerScalpel.solveModelFunction
solveModel(; TT=52, ndims=20, thetai=0.38, thetas=0.0044)
solveModel(nprocs:Int64; TT=52, ndims=20, thetai=0.38, thetas=0.0044)

Solve the model for all possible policy choices and replicate Figures 5, 6, and 7 in Chari, Kirpalani, and Phelan (2021). The function calls nopolicy and withpolicy with the relevant keywords, and uses the outputs to generate the figures using createFig5, createFig6, and createFig7.

Arguments:

  • nprocs::Int64: Optional. If specified, uses the module Distributed for parallelizing computations among nprocs workers.
  • TT::Integer: Number of periods.
  • ndims::Integer: Number of grid points in each dimension.
  • thetai::Float: Probability that infected person sends "infected" signal.
  • thetas::Float: Probability that non-infected person sends "infected" signal.
source
HammerScalpel.nopolicyFunction
nopolicy(;TT=52)

Simulate the model in Chari, Kirpalani, and Phelan (2021) for TT periods under no government response. The output is a Dict containing the necessary variables and time-series for generating the figures.

source
HammerScalpel.withpolicyMethod
withpolicy(policy; TT=52, ndims=20, thetai=0.38, thetas=0.0044)
withpolicy(policy, nprocs; TT=52, ndims=20, thetai=0.38, thetas=0.0044)

Solve the model under a user-specified government policy. In all cases, the government quarantines individuals that are known to be infected. The output is a Dict containing the necessary variables and time-series for generating the figures.

Arguments:

  • policy::String: Label for the government policy. Takes values
    • notest: no testing at all.
    • untargettest: random testing.
    • targettest: targeted testing under access to contact-tracing technology.
    • isolate: no testing, but isolation of certain fraction of population.
  • nprocs::Int64: Optional. If specified, uses the module Distributed for parallelizing the computations. Requires prior setup of nprocs workers.
  • TT::Integer: Number of periods.
  • ndims::Integer: Number of grid points in each dimension.
  • algorithm: NLopt optimization algorithm.
  • thetai::Float: Probability that infected person sends "infected" signal.
  • thetas::Float: Probability that non-infected person sends "infected" signal.
source
HammerScalpel.createFig5Method
createFig5(noint, notest, untarget)
createFig5()

Replicate Figure 5 in Chari, Kirpalani, and Phelan (2021). If no arguments are provided, then stored results obtained with default parameters are used.

Arguments:

source

Implementation details

Optimization algorithm: The authors originally use the algorithm SQP for maximizing the Bellman equation in each iteration, which in this case requires approximating gradients and Hessian. For some policies, the NLopt algorithms LN_BOBYQA and LN_SBPLX find the same solution with greater speed. Therefore, although the replication results hold when using SQP everywhere, I use those two algorithms when applicable.

Forced stops: When using the SQP implementation of NLopt, called LN_SLSQP, for optimization, the algorithm sometimes fails to converge, which is indicated by the return message FORCED_STOP (<1.5% of attempts). This is because the gradient of the objective cannot be computed in some edge cases. The authors solve this problem by adding a global optimization step in those cases. I chose not to do so because these additional steps slow down the computations a lot. Therefore, some of my figures are more jagged than those generated by the original Matlab code.

Dimensionality: The authors originally use 40 grid points for each control variable. In this replication, I reduced them to 20 for computational efficiency, which is why some of the time series are not exactly identical to the original and may look a bit jagged.

Inconsistencies: In my replications of Figures 6 and 7, the time series for $R_0$ features a sharp increases for policies "targeted" and "isolate" around T=40 and T=50, respectively, which are not present in the published paper. I verified that these inconsistencies are also present when replicating the figures with the original Matlab code.