This is a work-in-progress Matlab package consisting of functions that solve the dynamic life cycle model in Nygård, Sørensen and Wang (2021). The paper is titled Optimal allocations to heterogeneous agents with an application to the COVID-19 stimulus checks. Nygård, Sørensen and Wang (2021) supersedes two prior papers, Nygård, Sørensen and Wang (2020) as well as Wang (2020). The code companion presents solutions to the dynamic life-cycle problem, and methods for evaluating the marginal gains from allocating additional stimulus checks. Tested with Matlab 2020a.
All functions are parts of a matlab toolbox that can be installed:
Download and install the Matlab toolbox: PrjOptiSNW.mltbx
The Code Companion can also be accessed via the bookdown site and PDF linked below:
This files below consists of a collection of mlx based vignettes for functions that are available from PrjOptiSNW. Each Vignette file contains various examples for invoking each function.
The package relies on MEconTools, which needs to be installed first. The package does not include allocation functions, only simulation code to generate the value of each stimulus check increments for households. Allocation functions rely the R optimal allocation package PrjOptiAlloc.
The files below largely document contents in the Matlab-based PrjOptiSNW folder of the repository. The AllocateR folder contains additional documentation for various functions and files that solve allocation problems based on functions in the R PrjOptiAlloc package and solutions csv files generated by the dynamic programming files from the Matlab-based PrjOptiSNW folder. Some additional results for the paper are included in the additional_results folder.
Please contact FanWangEcon for issues or problems.
In addition to downloading and installing PrjOptiSNW.mltbx, can also:
# Clone Package from Git Bash
cd "C:/Downloads"
git clone https://github.com/fanwangecon/PrjOptiSNW.git
Install the Package from inside Matlab:
# Install Matlab Toolbox PrjOptiSNW
toolboxFile = 'C:/Downloads/PrjOptiSNW/PrjOptiSNW.mltbx';
# toolboxFile = 'C:/Users/fan/PrjOptiSNW/PrjOptiSNW.mltbx';
agreeToLicense = true;
installedToolbox = matlab.addons.toolbox.installToolbox(toolboxFile, agreeToLicense)
- Household Problem and Distributions: mlx | m | pdf | html
- Summarize the household's dynamic programming problem and the distributions across heterogeneous households groups.
- Values of Checks Conditional on 2019 Information: mlx | m | pdf | html
- Summarize the computation of expecations relevant for planning objectives given information avaiable in 2019.
- The Stimulus Check Planning Problem: mlx | m | pdf | html
- Summarize several allocation problem that condition allocations on income, marital status, the number of children less than 18, and possibly age.
- Model Parameters: mlx | m | pdf | html
- Model parameters, transition matrices, permanent heterogeneities.
- PrjOptiSNW: snw_mp_param()
- Model Controls Parameters: mlx | m | pdf | html
- Parameters to control display options etc.
- PrjOptiSNW: snw_mp_control()
- Policy and Value Functions Dynamic Life Cycle Vectorized Bisection: mlx | m | pdf | html
- Solving for policy and value functions from 18 to 100 years of age, at 1 year interval.
- Households face persistent productivity shocks for household heads, stochastic shocks for spousal income, exogenous children under age 17 transition probability, and age-specific household-head survival probabilities.
- The household can have up to four children under age 17, and has permanent heterogeneity in marital status and education types.
- Problem solved for exact savings choices using vectorized bisection from from MEconTools.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Small Test Looped Minimizer Routine to Solve for Exact Savings Choices: mlx | m | pdf | html
- Solve for the exact savings choices using matlab minimizer in an iterative loop.
- The code demonstrates the solution structure. We use snwx_vfi_bisec_vec() with vectorized bisection for working implementations.
- Due to speed, only show testing results at small grid without spousal shocks.
- PrjOptiSNW: snw_vfi_main()
- Small Test Looped over States Grid Search Solution: mlx | m | pdf | html
- The savings choice grid is the same as the savings states grid. Solve for optimal savings choices using grid-search. Loop over the state space, at each state-space point, vectorized optimization.
- Our problem requires very high precision to solve for the marginal gains to households from each increment of stimulus checks. We rely on the exact solution method from snwx_vfi_bisec_vec() for the working code.
- Due to speed, only show testing results at small grid without spousal shocks.
- PrjOptiSNW: snw_vfi_main_grid_search()
- Small Test Vectorized Bisection Solve for Exact Savings Choices: mlx | m | pdf | html
- Vectorized bisection exact solution code tested with small grid to compare to alternative solutiom methods.
- Small grid without spousal shocks.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Small Test Spousal Shocks Test Vectorized Bisection Solve for Exact Savings Choices: mlx | m | pdf | html
- Vectorized bisection exact solution code tested with small grid to compare to alternative solutiom methods.
- Small grid with spousal shocks. There are three shocks: persistent household head income shock, i.i.d. spousal income shock, and persistent kids count transition shocks.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Policy and Value Functions Dynamic Life Cycle if Unemployed: mlx | m | pdf | html
- Solving the dynamic programming problem conditional on having an one period unemployment shock (MIT).
- There is an unemployment shock in 2020. We first solve for the policy and value functions without the unemployment shock.
- Using the value function from the world without the 2020 covid unemployment shock as future values, we solve for optimal choices in 2020 given a COVID unemployment shock.
- The COVID shock lowers the realization of household's stochastic income process proportionally, but the lost income might be replenished by unemployment benefits up to 100 percent. Unemployment benefits have to be paid for by taxes.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Policy and Value Functions 2008 given 2009 Shock Expectation: mlx | m | pdf | html
- Solving the dynamic programming problem conditional on having an one period unemployment shock that is expected with known unemployment probability.
- Unemployment probability is a function of the realized state-space next year, specifically, it is determined by age and education.
- Bush 2008 checks were received by households in expectation of forth-coming unemployment shocks, ex-ante the realization of shocks. During COVID, the shocks were received ex-post the realization of shocks. In both cases, stimulus checks were determined based on ex-ante information.
- PrjOptiSNW: snw_v08p08_jaeemk()
- Policy and Value Functions Dynamic Life Cycle Given Trump Stimulus: mlx | m | pdf | html
- Solve for policy and value functions given the first two rounds of CARES Act checks.
- The distribution induced by the CARES Act policy functions are used as the distribtuion of savings for households receiving the 3rd round of checks from the American Rescue Plan
- PrjOptiSNW: snw_vfi_main_bisec_vec_stimulus()
- Assets and Demographic Distributions with Grid Search: mlx | m | pdf | html
- Grid search solution using grid search for savings choices, the savings state-space grid is the same as the savings choice-grid. Exact choice solution from snw_ds_main() generates significantly smoother distributions.
- PrjOptiSNW: snw_ds_main_grid_search()
- Assets and Demographic Distributions with Continuous Exact Savings Choices (Loop): mlx | m | pdf | html
- Simulate the life cycle distribution of assets, consumptions, and demographic patterns up to age 100, given exogenous initial distributions at age 18. Solves for budget clearing tax rates given distributional results. Uses vectorized bisection to solve for exact savings choices, looped distribution code.
- PrjOptiSNW: snw_ds_main()
- Assets and Demographic Distributions with Continuous Exact Savings Choices (Vectorized): mlx | m | pdf | html
- Simulate the life cycle distributions. This is the fully vectorized version of snw_ds_main().
- Given distributions, snw_ds_aggregation() provides aggregate statistics.
- Distribution of individuals by age induced by age-specific mortality probability.
- PrjOptiSNW: snw_ds_main_vec() + snw_ds_aggregation()
- Assets and Demographic Distributions (vectorized) with One Period MIT Shock: mlx | m | pdf | html
- Simulate the life cycle distributions. This calls the vectorized snwx_ds_bisec_vec() distributional function.
- Feed in a 6th parameter to snwx_ds_bisec_vec() which is the current (steady-state) distribution across state-space. The policy functions are optimal choices in a period with MIT shock. Solve for the distribution induced by the one-period MIT shock's policy function given steady-state distribution.
- This is used to model the distributional effects of CARES Act, the two rounds of Trump Stimulus Checks, on household asset distribution when then receive the Biden stimulus checks from the the American Recovery Act. In effect, we have two MIT shock periods.
- PrjOptiSNW: snw_ds_main_vec()
- Marginal Gain Per Check 2020 Employed: mlx | m | pdf | html
- Evaluate the marginal gain per check in 2020 if household head is employed.
- Solve for the increase in savings that is equivalent to the impact of an additional check on a household's resource available in 2020, given tax and interest rates considerations.
- PrjOptiSNW: snw_a4chk_wrk_bisec_vec()
- Marginal Gain Per Check 2020 Unemployed: mlx | m | pdf | html
- Evaluate the marginal gain per check in 2020 if household head is unemployed.
- Solve for the increase in savings that is equivalent to the impact of an additional check on a household's resource available in 2020, given tax and interest rates considerations.
- PrjOptiSNW: snw_a4chk_unemp_bisec_vec()
- Value in 2020 Given Age, Savings, Shocks, Kids, Educaiton and Marriage: mlx | m | pdf | html
- Expected value and expected consumption from 2020 for a household given at a particular age (18-100), with a particular savings level, at a particular combination of household head and spouse income shocks, with 0 to 4 children, high or low Education status, and married or not married.
- This uses the unemployment probability and generates the average value given the probability of the unemployment state that is dependent on the state-space.
- PrjOptiSNW: snw_evuvw20_jaeemk()
- Expected Value in 2019 Given Age, Savings, Shocks, Kids, Educaiton and Marriage: mlx | m | pdf | html
- Expected value and expected consumption from 2019 for a household at a particular age (18-99), savings level, shocks combinations, kids/education/marriage status, given 2019 optimal savings choices, income shock transition probability as well as household children count transition probabilities.
- PrjOptiSNW: snw_evuvw19_jaeemk_foc()
- 2008 Value and Optimal Savings and Consumption Given Stimulus: mlx | m | pdf | html
- Compute the difference in Value and Consumption under differing levels of Bush Stimulus. We assume that the stimulus is provided ex-ante of the 2009 great recession shocks, which are expected by households (not MIT shock as under COVID).
- This is simialr to SNW_EVUVW20_JAEEMK, but for the 2008 Bush stimulus. SNW_V08P08_JAEEMK already solved for optimal policy and value functions in 2008, given expected unemployment shock in 2009. In this function, given some stimulus amount, we use SNW_A4CHK_WRK_BISEC_VEC to compute the updated optimal V and C in 2008 given the stimulus amount, based on the alues for V and C without stimulus computed by SNW_V08P08_JAEEMK.
- PrjOptiSNW: snw_v08_jaeemk()
- Expected Value in 2007 Given Age, Savings, Shocks, Kids, Educaiton and Marriage: mlx | m | pdf | html
- Expected value and expected consumption from 2007 for a household at a particular age (18-99), savings level, shocks combinations, kids/education/marriage status, given 2007 optimal savings choices, income shock transition probability as well as household children count transition probabilities.
- PrjOptiSNW: snw_evuvw19_jaeemk_foc()
- Expected Value from 2019 Given Age, Kids, Income and Marriage: mlx | m | pdf | html
- Expected Value from 2019 Given Age, Kids, Income and Marriage.
- Each 2019 income group consists of individuals with varying productivity shocks, savings, and from lower and higher education groups.
- PrjOptiSNW: snw_evuvw19_jmky()
- Expected Value from 2019/2020 Given Age, Kids, Income and Marriage for All Checks: mlx | m | pdf | html
- Expected Value from 2019/2020 (Trump/Biden Checks) Given Age, Kids, Income and Marriage for All Checks.
- This is the gateway function that solves policy functions, derive distributions, computes value in 2020 with and without unemployment shocks with varying check levels, derives 2019 planner expected values given household optimization and shocks, and finds the mass of individuals in different income/age/marital-status bins, and saves the simulated value of check results for the planner.
- PrjOptiSNW: snw_evuvw19_jmky_allchecks()
- Expected Value from 2007 Given Age, Kids, Income and Marriage for All Checks: mlx | m | pdf | html
- Expected Value from 2007 Given Age, Kids, Income and Marriage for All Checks.
- This is the gateway function that solves policy functions. The function derives distributions, computes value in 2008 with varying check levels, given unemployment expectation in 2009. It finds the 2007 planner expected values given household optimization and shocks, and finds the mass of individuals in different income/age/marital-status bins, and saves the simulated value of check results for the planner.
- PrjOptiSNW: snw_evuvw19_jmky_allchecks()
- Solve for Budget Clearing Tax Rates: mlx | m | pdf | html
- Given stimulus checks and unemployment insurance costs, solve for tax rate that clears the budget given household resource availability.
- PrjOptiSNW: snw_find_tax_rate(), snw_tax_hh()
- The Two Rounds of Trump CARES Stimulus Check Amounts: mlx | m | pdf | html
- Under the Trump CARES Act, given the number of children and marital status and income, the amounts of stimulus checks that households receive.
- PrjOptiSNW: snw_stimulus_checks(),
- The Biden American Recovery Act Stimulus Check Amounts: mlx | m | pdf | html
- Under the Biden American Rescue Plan Act of 2021, given the number of children and marital status and income, the amounts of stimulus checks that households receive.
- PrjOptiSNW: snw_stimulus_checks_biden(),
- Taxable Income and Tax Liabilities in 2008 (Bush Stimulus): mlx | m | pdf | html
- The 2008 Bush stimulus is a rebate based on how much tax was paid, so we need to know taxable income and tax liability. These differ by income, household marital status, and the count of children.
- Given an array of pre-tax income values, we compute for from 0 to 4 kids and both married and unmarried taxable-income and tax-liability at all points along the income array.
- Deductions are from 2008 income (2008 IRS f1040). Tax brackets from 2008 are here (2008 IRS 1040tt).
- PrjOptiSNW: snw_tax_liability(),
- The Biden American Recovery Act Stimulus Check Amounts: mlx | m | pdf | html
- Under the Bush Economic Stimulus Act of 2008, given the number of children and marital status and income, the amounts of stimulus checks that households receive.
- PrjOptiSNW: snw_stimulus_checks_bush(),
- Calibrate Discount Factor and Normalize GDP: mlx | m | pdf | html
- We calibrate the model so that the Asset/Savings/Capital to GDP/Income ratio is 3.
- We normalize the model so that median household income is equal to 1 in the model.
- PrjOptiSNW: snw_calibrate_beta_norm_gdp()
- Calibrate Lockdown Period Proportional Utility Loss MIT Shock COVID: mlx | m | pdf | html
- There is one MIT shock period in which households face a one-period change in the current utility of consumption due to lock down.
- Solve the model and evaluate the effects on aggregate consumption (during the MIT shock period) with different proportional adjustments on consumption given differing intertemperal preference assumptions.
- PrjOptiSNW: snw_calibrate_beta_norm_gdp()
- UI Benefit Unemployment Lost Wage Recovery Parameter b Calibration: mlx | m | pdf | html
- The ratio of UI benefits to wages and salary is 2.1 percent in 2009. 0 < xi < 1 governs the duration of unemployment shock for those unemployed. This equals to 0.532 in 2009 (xi = 0 no wages earned).
- We solve for total wage earnings from unemployed and employed in 2009, for employed, same as under steady-state. For unemployed, they lose (1 - xi) share of the wage they would otherwise have earned. Our unemployment probability in 2009 is conditional on age and edu groups (SNW_UNEMP_2008.m) computed based on rectiilnear restriction.
- We know total UI amount (multiply its share of total "Wages and salary" by total "wages and salary". We know how much wage was lost due to xi. The ratio of these two levels is b, which is the parameter that is the share of lost-wage recovered.
- PrjOptiSNW: snw_calibrate_2009_b()
- Distributional Statistics by Household Structure and Income Groups: mlx | m | pdf | html
- Summarize overall model distributional and inequality statistics from covid-less times.
- Statistics, including first check MPC, by marital status, children count, and income groups.
- See snwx_evuvw19_jmky_mpc_allocated_m for summarizing function over optimal allocation results.
- Value and Consumption Low vs Higher Interest Rates Results Comparison: mlx | m | pdf | html
- Solves for V and C for individuals at lower (2 percent) and higher (4 percent) savings interest rate.
- An increase change in the savings rate generates both an income effect (higher resources) and also changes relative price of consumption today vs tomorrow; households value/welfare increase and might overall consume more or less depending on their state-space.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Value and Consumption Low vs Higher Unemployment Insurance Comparison: mlx | m | pdf | html
- This function solves for the V(states, unemployed) assuming individuals suffer from unemployment spell, but with different UI (unemployment benefits). Higher UI benefits leads to value/welfare and also higher consumption.
- PrjOptiSNW: snw_vfi_bisec_vec()
- Value and Consumption Low vs Higher Discount Factor Comparison: mlx | m | pdf | html
- This function solves for the V(states) for individuals at lower and higher discount factor . We allow for heterogeneity in the model to consider both patient and impatient households. The key difference is that patient households are more willing to save and will consume less.
- PrjOptiSNW: snw_vfi_bisec_vec()