入门:Krusell & Smith(1998)

该模型描述了一个生产经济,其中家庭面临无法保险的个体异质性劳动收入风险。总体冲击是对全要素生产率的冲击。工具包能够求解模型稳态,并且可以求解未预期的总体冲击发生后确定性的线性/非线性转移路径。根据 Boppart,Krusell & Mitman (2018)Auclert 等,(2021),确定性转移路径刻画了总体冲击的一阶效应。

为便于比较,我们采用了 Den Haan,Judd & Juillard (2010) 中的模型设定及参数值。

模型

家庭具有异质性的就业状态 \(e\in\{0,1\}\) 及资本持有 \(a \in R^+\),并求解如下的贝尔曼方程:

\[\begin{split} v_t(e,a) = \max_{c,a'} \log(c)+ \beta\mathbb{E}[v_{t+1}(e',a')|e] \\s.t. \quad c+a' \leq (1+r_t)a + [(1-\tau)\overline{l}e + \mu(1-e)]w_t \\a'\geq 0, c \geq 0, \end{split}\]
(1)\[\]

其中 \(\bar{l}\) 是就业状态下的劳动供给,\(\tau\) 是劳动所得税率,\(\mu\) 是失业保险偿付率。\(r_t\)\(w_t\) 分别为利率和工资。家庭面临无借贷约束 \(a'\geq 0\)

代表性厂商使用资本与劳动进行生产:\(Y_t = Z_t K_t^{\alpha} L_t^{1-\alpha}\)。资本折旧率为 \(\delta\)。利率和工资由市场竞争决定。

\[\begin{split} r_t = \alpha Z_t K_t^{\alpha-1}L_t^{1-\alpha} - \delta \\ w_t = (1-\alpha)Z_tK_t^{\alpha}L_t^{-\alpha} \end{split}\]
(2)\[\]

给定家庭状态的初始分布 \(\Phi_0\),序列竞争均衡定义为:(1)家庭状态分布 \(\{\Phi_t\}_{t=0}^{\infty}\);(2)家庭值函数与策略函数 \(\{v_t,g_{c,t},g_{a',t}\}_{t=0}^{\infty}\);(3)总体数量与价格 \(\{K_t, L_t, r_t, w_t\}_{t=0}^{\infty}\) 的序列,使得:

  • \(\{v_t,g_{c,t},g_{a',t}\}\) 求解由 (1) 定义的家庭最优化问题;

  • 市场出清: \(K_t=\int a \ \mathrm{d}\Phi_t(e,a)\), \(L_t=\int \bar{l} e \ \mathrm{d}\Phi_t(e,a)\)。商品市场出清满足瓦尔拉斯定律。

  • \(r_t\)\(w_t\)(2) 确定。

  • 失业救济金来源于劳动所得税:\(w_t\int \bar{l} \tau e \ \mathrm{d}\Phi_t(e,a)=w_t\int (1-e)\mu \ \mathrm{d}\Phi_t(e,a)\)

  • \(\{\Phi_t\}\) 与策略函数 \(g_{a',t}\)\(e\) 的外生转移一致。

工具箱脚本(hmod)文件

模型可以由 KS_JEDC10.hmod 描述,如下所示:

 1% The parameters are from from den Haan, Judd, Juillard, 2010, "Computational Suite of models with heterogeneous agents: 
 2% Incomplete markets and aggregate uncertainty" Journal of Economic Dynamics and Control, 34, pp 1 - 3.
 3parameters beta r w;
 4beta = 0.99;        % subjective discount factor
 5r = 0.009;          % asset return
 6w = 0.89;           % wage rate
 7labor = 1.0/0.9;    % exogenous labor supply when working
 8mu = 0.15;          % unemployment insurance replacement ratio
 9
10var_shock e;
11shock_trans = [0.600000, 0.400000;
12               0.044445, 0.955555];
13e = [0.00;1.00];
14shock_invariant_dist = [0.1;0.9];
15e_bar = shock_invariant_dist(:).'*e(:); 
16L = labor*e_bar;
17unemp_rate = shock_invariant_dist(1);  % unemployment rate 
18tau = mu*unemp_rate/L; % labor income tax rate
19
20var_state a;
21a = exp(linspace(log(0.25), log(200 + 0.25), 500)) - 0.25;
22
23var_pre_vfi budget;
24budget = (1+r)*a + w*((1.0-tau)*e*labor + mu*(1- e));
25
26% var_policy defines the choice variable
27var_policy ap;
28initial ap 0.0;
29% var_aux defines varaibles that can be simply evaluated
30var_aux c;
31
32vfi;
33    c = budget - ap;
34    u = log(c);
35    Tv = u + beta*EXPECT(v(ap));
36    ap <= budget;
37    ap >= 0.0;
38end;
39
40var_agg K;
41K = 43.0; % initial guess
42alpha = 0.36;   % capital share
43delta = 0.025;  % depreciation
44
45var_agg_shock Z;
46Z = 1.0; % steady state value
47
48model;
49    % Aggregate conditions stated like Dynare
50    r = alpha * Z * K(-1)^(alpha-1) * L^(1-alpha) - delta;
51    w = (1-alpha) * Z * K(-1)^alpha * L^(-alpha);
52    K == ap; % asset demand = asset supply
53    % Allow box constraints for aggregate variables
54    K >= 38.0;
55    % post evaluation
56    Y = Z*(K(-1)^alpha)*(L^(1-alpha));
57    I = K - (1 - delta)*K(-1);
58    C = Y - I;
59end;

脚本文件的目标是定义一个 vfi(值函数迭代)模块,用于确定个体决策问题,并定义一个 model 模块,用于确定总体均衡条件。

vfi 模块之前需要定义用于求解个体问题所需的信息。模块中定义的信息将按照顺序进行解释。

1% The parameters are from from den Haan, Judd, Juillard, 2010, "Computational Suite of models with heterogeneous agents: 
2% Incomplete markets and aggregate uncertainty" Journal of Economic Dynamics and Control, 34, pp 1 - 3.
3parameters beta r w;
4beta = 0.99;        % subjective discount factor
5r = 0.009;          % asset return
6w = 0.89;           % wage rate
7labor = 1.0/0.9;    % exogenous labor supply when working
8mu = 0.15;          % unemployment insurance replacement ratio

该模块声明了 vfi 模块中使用的参数及其数值。

10var_shock e;
11shock_trans = [0.600000, 0.400000;
12               0.044445, 0.955555];
13e = [0.00;1.00];
14shock_invariant_dist = [0.1;0.9];
15e_bar = shock_invariant_dist(:).'*e(:); 
16L = labor*e_bar;
17unemp_rate = shock_invariant_dist(1);  % unemployment rate 
18tau = mu*unemp_rate/L; % labor income tax rate

该模块在 var_shock 中声明了个体外生状态及其数值,这些状态需要被定义为具有联合转移矩阵 shock_trans 的离散马尔科夫过程。给定失业保险偿付率 \(\mu\) 的校准,平衡预算的劳动所得税率 \(\tau\) 可以预先确定。

20var_state a;
21a = exp(linspace(log(0.25), log(200 + 0.25), 500)) - 0.25;

该模块在 var_state 中声明了个体的内生状态,并且指定了用于近似值函数及策略函数的离散格点值。对于多维状态,函数将在离散状态值的张量积上进行近似。

23var_pre_vfi budget;
24budget = (1+r)*a + w*((1.0-tau)*e*labor + mu*(1- e));

该模块定义了一些简单变量,这些变量是外生状态和/或内生状态的函数,可以在求解决策问题之前确定。在这里,预算被视为按照特定价格(价格被定义为参数)计算的资本与劳动收入之和。该模块是可选的。

26% var_policy defines the choice variable
27var_policy ap;
28initial ap 0.0;

将需要优化的变量(此处为未来资本持有 \(a'\))在 var_policy 中声明。辅助变量(此处为消费 \(c\))可以直接作为 var_shockvar_state 和/或 var_policy 的简单函数进行计算,并被声明为 var_aux

所有信息准备就绪之后,在 vfi 模块中的 vfi;end; 之间定义个体问题。

32vfi;
33    c = budget - ap;
34    u = log(c);
35    Tv = u + beta*EXPECT(v(ap));
36    ap <= budget;
37    ap >= 0.0;
38end;

vfi 模块从 var_state(此处为 \((e,a)\))和 var_policy(此处为 \(a'\))的值开始,定义 Tv 中的目标(被标注的行)。如所示,这一行遵循贝尔曼方程的自然语法,其中未来值函数 v 被视为已知,并在未来的内生状态值上调用。EXPECT 操作符用于求解未来外生状态的积分。

var_policy 的约束(此处为 \(0 \leq a'\leq budget\))以及任意的等式或不等式约束可以在定义目标之后进行说明。

所有的 var_aux(此处为 \(c\))都需要被定义。

脚本文件可以在定义 vfi 块后停止,因此工具箱只生成用于解决自包含决策问题的代码。

为了求解均衡,需要在 model 模块中定义一个总体变量方程组,在模块前定义的全部所需信息将按照顺序解释。

40var_agg K;
41K = 43.0; % initial guess
42alpha = 0.36;   % capital share
43delta = 0.025;  % depreciation

均衡系统的未知数需要声明为 var_agg(此处为 \(K\)),并指定其初始值。定义总体系统时使用的任何参数值(此处为 \(\alpha,\delta\))也需要被明确指定。

45var_agg_shock Z;
46Z = 1.0; % steady state value

总体冲击被声明为 var_agg_shock。总体冲击本质上是模型参数,并允许随时间变化。此处为总体 TFP,\(Z\)

所有信息准备就绪之后,总体均衡系统被定义为:

48model;
49    % Aggregate conditions stated like Dynare
50    r = alpha * Z * K(-1)^(alpha-1) * L^(1-alpha) - delta;
51    w = (1-alpha) * Z * K(-1)^alpha * L^(-alpha);
52    K == ap; % asset demand = asset supply
53    % Allow box constraints for aggregate variables
54    K >= 38.0;
55    % post evaluation
56    Y = Z*(K(-1)^alpha)*(L^(1-alpha));
57    I = K - (1 - delta)*K(-1);
58    C = Y - I;
59end;

model 模块的目标是定义表征总体均衡条件的方程系统。每个方程都用 “==” 定义,如代码块中突出显示的那样。在这里,系统由一个简单的方程组成,即资产市场出清条件 \(K_{t+1}=\int g_{a',t} d\Phi_t(e,a)\)var_policy 可用于方程定义之中,表示在 \(t\) 时刻基于分布的个体策略函数加总,行中的 ap 表示 \(\int g_{a',t} d\Phi_t(e,a)\)\(ap\) 被声明为 var_policy)。

在定义系统之前,需要按顺序计算中间变量 \(r,w\)。请注意,在定义方程之前,需要更新用于解决个体决策问题的参数(此处为 \(r\)\(w\)),以适应 var_agg 中的变化。对于变量的时间序列索引,符号遵循 Dynare 的惯例:将预先确定的总体变量作为滞后变量进行索引(此处使用 \(K(-1)\) 计算 \(r\)\(w\))。

可以对 var_agg 施加约束。这里指定了 \(K \geq 38\) 使得 \(r\) 有界,以确保值函数迭代能够收敛。

定义方程后,可以定义其他的总体均衡变量(此处最后三行定义了 \(Y,I,C\))。求解系统后会返回这些变量值。

使用工具箱

解析脚本文件后,工具箱会生成 MATLAB 文件,包括:solve_vfi.msolve_ss.msolve_trans_linear.msolve_trans_nonlinear.m 以及其他可以调用的函数,用于求解模型的稳态、平稳分布和转移路径。这些函数的使用方法如下所示。

解析 .hmod 文件

解析 .hmod 文件

假设 KS_JEDC10.hmod 已经位于工作文件夹中。在 MATLAB 中调用
clear_hans
hans KS_JEDC10
Parsing...ok! Compiling dpopt_vfi Building with 'MinGW64 Compiler (C++)'. MEX completed successfully.
ans = struct with fields:
parameters: {'beta' 'r' 'w'} var_shock: 'e' var_state: 'a' var_pre_vfi: 'budget' var_policy: 'ap' var_aux: 'c' var_agg: 'K' var_agg_shock: 'Z' var_agg_params: {'alpha' 'delta' 'L'} var_agg_assign: {'r' 'w'} var_agg_in_ind_params: {'r' 'w'} var_ind_in_eq: 'ap'
如上所示,HANS 解析 hmod 文件,编译 mex 文件,并返回一个描述模型的结构。
第一行中的 clear_hans 会清除之前生成的所有缓存文件。

求解静态均衡

调用生成的代码 solve_ss 求解静态均衡
tic;
ss_rslt = solve_ss;
Evaluating at var_agg: 43, VFI converged (metric_v) 0.00663442, (metric_pol) 0 in 489 iterations Range of a: 0, 18.9484 Equilbirium residual: 32.0071, Iteration Line Search Func-count ||f(x)||^2 fnorm(x) Norm of Step Step Size Algorithm 0 0 1 1.024452e+03 3.200706e+01 Evaluating at var_agg: 43.0043, VFI converged (metric_v) 0.000364795, (metric_pol) 0 in 290 iterations Range of a: 0, 18.9484 Equilbirium residual: 32.015, Evaluating at var_agg: 40.5, VFI converged (metric_v) 2.14285e-05, (metric_pol) 0 in 646 iterations Range of a: 0, 30.8489 Equilbirium residual: 26.1081, 1 1 3 6.816343e+02 2.610813e+01 2.500000e+00 1.437515e-01 Newton Evaluating at var_agg: 39.25, VFI converged (metric_v) 1.0435e-06, (metric_pol) 0 in 865 iterations Range of a: 0, 60.5201 Equilbirium residual: 20.2586, 2 1 4 4.104102e+02 2.025858e+01 1.250000e+00 1.129711e-01 Broyden Evaluating at var_agg: 38.625, VFI converged (metric_v) 1.17248e-07, (metric_pol) 0 in 991 iterations Range of a: 0, 128.441 Equilbirium residual: 13.1583, 3 1 5 1.731411e+02 1.315831e+01 6.250000e-01 1.443720e-01 Broyden Evaluating at var_agg: 38.3125, VFI converged (metric_v) 1.22019e-07, (metric_pol) 0 in 1034 iterations Range of a: 0, 200 Equilbirium residual: 2.91778, 4 1 6 8.513465e+00 2.917784e+00 3.125000e-01 2.698019e-01 Broyden Evaluating at var_agg: 38.2235, VFI converged (metric_v) 1.49177e-07, (metric_pol) 0 in 915 iterations Range of a: 0, 200 Equilbirium residual: -4.10224, 5 1 7 1.682838e+01 4.102240e+00 8.903913e-02 1.000000e+00 Broyden Evaluating at var_agg: 38.268, VFI converged (metric_v) 1.27167e-07, (metric_pol) 0 in 860 iterations Range of a: 0, 200 Equilbirium residual: -0.0836401, 5 2 8 6.995670e-03 8.364012e-02 4.451957e-02 5.000000e-01 Broyden Evaluating at var_agg: 38.2692, VFI converged (metric_v) 7.76193e-08, (metric_pol) 0 in 564 iterations Range of a: 0, 200 Equilbirium residual: 0.0116397, 6 1 9 1.354831e-04 1.163972e-02 1.240618e-03 1.000000e+00 Broyden Evaluating at var_agg: 38.2691, VFI converged (metric_v) 8.09795e-08, (metric_pol) 0 in 355 iterations Range of a: 0, 200 Equilbirium residual: 0.000535046, 7 1 10 2.862740e-07 5.350458e-04 1.515583e-04 1.000000e+00 Broyden Evaluating at var_agg: 38.2691, VFI converged (metric_v) 7.74544e-08, (metric_pol) 0 in 109 iterations Range of a: 0, 200 Equilbirium residual: 5.71076e-06, 8 1 11 3.261282e-11 5.710763e-06 7.302386e-06 1.000000e+00 Broyden Evaluating at var_agg: 38.2691, VFI result reused Range of a: 0, 200 Equilbirium residual: 5.71076e-06,
fprintf('Time used for solving the stationary equilibrium:\n');toc;
Time used for solving the stationary equilibrium: Elapsed time is 1.432989 seconds.
ss_rslt
ss_rslt = struct with fields:
vfi_rslt: [1×1 struct] stats: [1×1 struct] var_agg: [1×1 struct] dist: [2×500 double] parameters: [1×1 struct] var_agg_params: [1×1 struct] shock_trans: [2×2 double] shock_invariant_dist: [2×1 double] resid: 5.7108e-06 exit_flag: 1 rslt_type: 'ss' solver_output: [1×1 struct] ind_rslt_dict: [1×1 ArrayKeyMap]
如上所示,函数返回了一个描述求解出的静态均衡的结构。
我们可以查看均衡变量值:
ss_rslt.var_agg
ans = struct with fields:
K: 38.2691 Z: 1 r: 0.0099 w: 2.3769 Y: 3.7139 I: 0.9567 C: 2.7571
我们可以查看平稳分布
plot(ss_rslt.vfi_rslt.var_state.a, ss_rslt.dist);
xlabel('k');
ylabel('fractions');
以及策略函数
plot(ss_rslt.vfi_rslt.var_state.a, ss_rslt.vfi_rslt.var_policy.ap);
xlabel('a');
title('Policy functions for ap');
legend({'low e','high e'})

求解暂时性冲击后的转移路径

求解线性转移路径

我们首先构建生产率冲击序列。
T = 200;
shock_Z = 0.01; rho_Z = 0.9;
Z_t = 1 + shock_Z *rho_Z.^(0:(T-1));
figure;
plot(Z_t)
随后,我们将生产率冲击和解出的 ss_rslt 传递到 solve_trans_linear 中,求解线性化的转移路径。
options = struct;
options.T = T;
options.Z_t = Z_t;
tic;
trans_linear_rslt = solve_trans_linear(ss_rslt, options);
fprintf('Time used for solving the linearized transition path:\n');toc;
Time used for solving the linearized transition path: Elapsed time is 0.725552 seconds.
trans_linear_rslt
trans_linear_rslt = struct with fields:
var_agg_t: [1×1 struct] var_agg_shock_t: [1×1 struct] jacs_ind_wrt_agg: {[200×200 double] [200×200 double]} jac_eqs_of_var_agg: [200×200 double] irf_ssj: [200×200 double]
我们可以绘制转移路径(注意 K 是下一时期的资本)。
figure;
plot(trans_linear_rslt.var_agg_t.K)
title('K');
xlabel('time');

求解非线性转移路径

现在,我们将求解的 ss_rslt 传递给 solve_nonlinear_trans (init_ss, final_ss, options),以求解非线性转移路径。
请注意,我们将 ss_rslt 作为 init_ss 和 final_ss 传递。
tic;
trans_nonlinear_rslt = solve_trans_nonlinear(ss_rslt, ss_rslt, options);
Iteration Line Search Func-count ||f(x)||^2 fnorm(x) Norm of Step Step Size Algorithm 0 0 1 5.800552e-04 2.408433e-02 1 1 2 6.663947e-10 2.581462e-05 3.095308e-03 1.000000e+00 Broyden
fprintf('Time used for solving the nonlinear transition path:\n');toc;
Time used for solving the nonlinear transition path: Elapsed time is 1.320027 seconds.
trans_nonlinear_rslt
trans_nonlinear_rslt = struct with fields:
var_agg_t: [1×1 struct] var_agg_shock_t: [1×1 struct] T: 200 vfi_rslt: [1×1 struct] shock_trans: [2×2 double] exitflag: 1 HANS_x: [200×1 double] eqs_resid: [200×1 double] rslt_type: 'nonlinear_trans' solver_output: [1×1 struct]
我们比较非线性转移路径和线性转移路径的解。
figure;
plot(trans_linear_rslt.var_agg_t.K);
hold on;
plot(trans_nonlinear_rslt.var_agg_t.K, '--');
xlabel('time');
title('K');
legend({'Linear','Nonlinear'});
我们还可以查看转移路径上其他定义的均衡变量。
figure;
plot(trans_nonlinear_rslt.var_agg_t.w);
title('w');
xlabel('time');

求解永久性冲击后的转移路径

我们现在考虑一个未预期到的冲击,将 Z 永久提高100%。
我们首先求解新的静态均衡。
options = struct;
options.Z = 2.0;
ss_rslt_new = solve_ss(options);
Evaluating at var_agg: 43, VFI converged (metric_v) 0.0403421, (metric_pol) 0 in 413 iterations Range of a: 0, 200 Equilbirium residual: -160.841, Iteration Line Search Func-count ||f(x)||^2 fnorm(x) Norm of Step Step Size Algorithm 0 0 1 2.586975e+04 1.608408e+02 Evaluating at var_agg: 43.0043, VFI converged (metric_v) 0.00550782, (metric_pol) 0 in 199 iterations Range of a: 0, 200 Equilbirium residual: -160.836, Evaluating at var_agg: 195.495, VFI converged (metric_v) 0.0173235, (metric_pol) 0 in 251 iterations Range of a: 0, 25.1867 Equilbirium residual: 177.356, 1 1 3 3.145508e+04 1.773558e+02 1.524948e+02 1.000000e+00 Newton Evaluating at var_agg: 119.247, VFI converged (metric_v) 0.000418207, (metric_pol) 0 in 593 iterations Range of a: 0, 95.5869 Equilbirium residual: 75.8555, 1 2 4 5.754062e+03 7.585554e+01 7.624738e+01 5.000000e-01 Newton Evaluating at var_agg: 94.8119, VFI converged (metric_v) 9.83391e-07, (metric_pol) 0 in 1024 iterations Range of a: 0, 200 Equilbirium residual: -104.716, 2 1 5 1.096535e+04 1.047156e+02 2.443547e+01 1.000000e+00 Broyden Evaluating at var_agg: 107.03, VFI converged (metric_v) 9.58706e-08, (metric_pol) 0 in 1299 iterations Range of a: 0, 200 Equilbirium residual: -86.2799, 2 2 6 7.444222e+03 8.627991e+01 1.221774e+01 5.000000e-01 Broyden Evaluating at var_agg: 118.026, VFI converged (metric_v) 9.32533e-06, (metric_pol) 0 in 674 iterations Range of a: 0, 115.361 Equilbirium residual: 71.2133, 2 3 7 5.071333e+03 7.121329e+01 1.221774e+00 5.000000e-02 Broyden Evaluating at var_agg: 99.2833, VFI converged (metric_v) 9.8147e-08, (metric_pol) 0 in 1217 iterations Range of a: 0, 200 Equilbirium residual: -99.1582, 3 1 8 9.832350e+03 9.915820e+01 1.874234e+01 1.000000e+00 Broyden Evaluating at var_agg: 108.654, VFI converged (metric_v) 1.78346e-07, (metric_pol) 0 in 1192 iterations Range of a: 0, 200 Equilbirium residual: -81.0655, 3 2 9 6.571617e+03 8.106551e+01 9.371172e+00 5.000000e-01 Broyden Evaluating at var_agg: 117.088, VFI converged (metric_v) 5.73028e-06, (metric_pol) 0 in 713 iterations Range of a: 0, 137.358 Equilbirium residual: 66.8543, 3 3 10 4.469492e+03 6.685426e+01 9.371172e-01 5.000000e-02 Broyden Evaluating at var_agg: 102.716, VFI converged (metric_v) 1.82466e-07, (metric_pol) 0 in 1156 iterations Range of a: 0, 200 Equilbirium residual: -94.3721, 4 1 11 8.906088e+03 9.437207e+01 1.437252e+01 1.000000e+00 Broyden Evaluating at var_agg: 109.902, VFI converged (metric_v) 2.69193e-08, (metric_pol) 0 in 1337 iterations Range of a: 0, 200 Equilbirium residual: -73.9379, 4 2 12 5.466809e+03 7.393788e+01 7.186259e+00 5.000000e-01 Broyden Evaluating at var_agg: 116.37, VFI converged (metric_v) 4.568e-06, (metric_pol) 0 in 719 iterations Range of a: 0, 161.361 Equilbirium residual: 62.7817, 4 3 13 3.941536e+03 6.278166e+01 7.186259e-01 5.000000e-02 Broyden Evaluating at var_agg: 105.292, VFI converged (metric_v) 4.31381e-08, (metric_pol) 0 in 1283 iterations Range of a: 0, 200 Equilbirium residual: -90.0579, 5 1 14 8.110429e+03 9.005792e+01 1.107805e+01 1.000000e+00 Broyden Evaluating at var_agg: 110.831, VFI converged (metric_v) 4.6242e-08, (metric_pol) 0 in 1285 iterations Range of a: 0, 200 Equilbirium residual: -63.5917, 5 2 15 4.043907e+03 6.359172e+01 5.539026e+00 5.000000e-01 Broyden Evaluating at var_agg: 113.743, VFI converged (metric_v) 5.9994e-08, (metric_pol) 0 in 963 iterations Range of a: 0, 200 Equilbirium residual: 31.5864, 5 3 16 9.977013e+02 3.158641e+01 2.626473e+00 2.370880e-01 Broyden Evaluating at var_agg: 111.084, VFI converged (metric_v) 6.99602e-08, (metric_pol) 0 in 1145 iterations Range of a: 0, 200 Equilbirium residual: -59.2506, 6 1 17 3.510630e+03 5.925057e+01 2.659407e+00 1.000000e+00 Broyden Evaluating at var_agg: 112.414, VFI converged (metric_v) 4.37522e-08, (metric_pol) 0 in 1094 iterations Range of a: 0, 200 Equilbirium residual: -17.4686, 6 2 18 3.051521e+02 1.746860e+01 1.329704e+00 5.000000e-01 Broyden Evaluating at var_agg: 112.887, VFI converged (metric_v) 2.50023e-08, (metric_pol) 0 in 950 iterations Range of a: 0, 200 Equilbirium residual: 2.94162, 7 1 19 8.653100e+00 2.941615e+00 4.735105e-01 1.000000e+00 Broyden Evaluating at var_agg: 112.819, VFI converged (metric_v) 1.57584e-08, (metric_pol) 0 in 813 iterations Range of a: 0, 200 Equilbirium residual: 0.0719135, 8 1 20 5.171552e-03 7.191350e-02 6.824452e-02 1.000000e+00 Broyden Evaluating at var_agg: 112.817, VFI converged (metric_v) 1.43607e-08, (metric_pol) 0 in 488 iterations Range of a: 0, 200 Equilbirium residual: -0.000647376, 9 1 21 4.190962e-07 6.473764e-04 1.710179e-03 1.000000e+00 Broyden Evaluating at var_agg: 112.817, VFI converged (metric_v) 9.91224e-09, (metric_pol) 2.00672e-08 in 80 iterations Range of a: 0, 200 Equilbirium residual: -0.000487595, 10 1 22 2.377487e-07 4.875948e-04 1.525794e-05 1.000000e+00 Broyden Evaluating at var_agg: 112.817, VFI converged (metric_v) 9.96806e-09, (metric_pol) 1.00087e-08 in 203 iterations Range of a: 0, 200 Equilbirium residual: 0.00145568, 11 1 23 2.119016e-06 1.455684e-03 4.656163e-05 1.000000e+00 Broyden Evaluating at var_agg: 112.817, VFI converged (metric_v) 9.99162e-09, (metric_pol) 2.00287e-08 in 113 iterations Range of a: 0, 200 Equilbirium residual: 0.000980458, 11 2 24 9.612978e-07 9.804580e-04 2.328082e-05 5.000000e-01 Broyden Evaluating at var_agg: 112.817, VFI converged (metric_v) 9.94487e-09, (metric_pol) 2.00652e-08 in 146 iterations Range of a: 0, 200 Equilbirium residual: 9.24834e-05, 11 3 25 8.553178e-09 9.248339e-05 2.328082e-06 5.000000e-02 Broyden Evaluating at var_agg: 112.817, VFI result reused Range of a: 0, 200 Equilbirium residual: 9.24834e-05,
然后,我们求解从初始静态均衡到新静态均衡的转移路径。
options = struct;
T = 200;
options.Z_t = 2.0*ones(1,T); % shock hits at period 1
options.T = T;
tic;
trans_to_new_ss_rslt = solve_trans_nonlinear(ss_rslt, ss_rslt_new, options);
Iteration Line Search Func-count ||f(x)||^2 fnorm(x) Norm of Step Step Size Algorithm 0 0 1 5.361269e+05 7.322069e+02 1 1 2 1.831519e+04 1.353336e+02 2.746381e+02 1.000000e+00 Broyden 2 1 3 1.928935e+03 4.391964e+01 2.326839e+01 1.000000e+00 Broyden 3 1 4 1.277507e+00 1.130268e+00 4.819679e+00 1.000000e+00 Broyden 4 1 5 1.582870e-01 3.978530e-01 5.717419e-01 1.000000e+00 Broyden 5 1 6 1.003643e-04 1.001820e-02 1.033724e-01 1.000000e+00 Broyden 6 1 7 1.266697e-08 1.125476e-04 2.258355e-03 1.000000e+00 Broyden 7 1 8 3.681201e-11 6.067290e-06 5.298983e-05 1.000000e+00 Broyden
fprintf('Time for solving the nonlinear transition path after a permanent shock:\n');toc;
Time for solving the nonlinear transition path after a permanent shock: Elapsed time is 2.078643 seconds.
trans_to_new_ss_rslt
trans_to_new_ss_rslt = struct with fields:
var_agg_t: [1×1 struct] var_agg_shock_t: [1×1 struct] T: 200 vfi_rslt: [1×1 struct] shock_trans: [2×2 double] exitflag: 1 HANS_x: [200×1 double] eqs_resid: [200×1 double] rslt_type: 'nonlinear_trans' solver_output: [1×1 struct]
我们接下来查看非线性转移路径。
figure;
subplot(2,2,1);
plot(trans_to_new_ss_rslt.var_agg_t.K); title('K');
subplot(2,2,2);
plot(trans_to_new_ss_rslt.var_agg_t.C); title('C');
subplot(2,2,3);
plot(trans_to_new_ss_rslt.var_agg_t.w); title('w');
subplot(2,2,4);
plot(trans_to_new_ss_rslt.var_agg_t.r); title('r');

模拟个体样本

在平稳分布下模拟个体样本

我们可以在静态均衡中或沿转移路径模拟个体样本。
让我们从静态均衡开始。
tic;
simu_rslt = simulate_stochastic(ss_rslt);
period shock a ap cstate_transition_value_1 1000 1.899 37.77 37.77 2.752 37.77
fprintf('Time used for simulating individual samples at the stationary equilibrium:\n');toc;
Time used for simulating individual samples at the stationary equilibrium: Elapsed time is 0.805281 seconds.
simu_rslt
simu_rslt = struct with fields:
shock: [10000×1000 double] a: [10000×1000 double] ap: [10000×1000 double] c: [10000×1000 double] state_transition_value_1: [10000×1000 double]
如上所示,将 ss_rslt 传递给 simulate_stochastic 将返回一组模拟的个体样本。
打印的信息是打印当期各变量的均值。
默认情况下,它在1000个周期内模拟10,000个样本,并从平稳分布中提取的随机状态值开始。
我们可以覆盖 num_samples 和 num_periods:
simu_options = struct;
simu_options.num_samples = 2e4;
simu_options.num_periods = 2e3;
tic;
simu_rslt = simulate_stochastic(ss_rslt, simu_options);
period shock a ap cstate_transition_value_1 1000 1.898 37.94 37.94 2.754 37.94 2000 1.9 37.59 37.59 2.749 37.59
fprintf('Time used for simulating 2e4 individual samples for 2e3 periods at the stationary equilibrium:\n');toc;
Time used for simulating 2e4 individual samples for 2e3 periods at the stationary equilibrium: Elapsed time is 2.538545 seconds.
我们可以将模拟的个体样本直方图与基于非随机模拟构建的直方图进行比较。
figure;
subplot(1,2,1);
histogram(simu_rslt.a(:,end),ss_rslt.vfi_rslt.var_state.a,'Normalization','probability');
xlim([-10,210]);ylim([0,0.014]);
subplot(1,2,2);
plot(ss_rslt.vfi_rslt.var_state.a, sum(ss_rslt.dist,1)');
xlim([-10,210]);ylim([0,0.014]);

在转移路径中模拟个体样本

为了模拟转移路径中的个体样本,我们需要指定初始状态变量值。
让我们指定它们来自平稳分布。
simulate_initials = struct;
% Use the last period of the simulated results at the stationary distirubtion
simulate_initials.shock = simu_rslt.shock(:,end);
simulate_initials.a = simu_rslt.a(:,end);
我们现在将初始值传递给选项,并按照至新静态均衡的转移路径模拟个体样本。
simu_options = struct;
simu_options.num_samples = 2e4; % to be consistent with size of initial values
simu_options.simulate_initials = simulate_initials;
simu_trans_rslt = simulate_stochastic(trans_to_new_ss_rslt, simu_options);
period shock a ap cstate_transition_value_1 0200 1.899 114.4 114.4 8.145 114.4
随后,我们比较从个体样本和非随机模拟中构建的总体变量。
figure;
plot(trans_to_new_ss_rslt.var_agg_t.c,'-');
hold on;
plot(mean(simu_trans_rslt.c),'--');
legend({'Determinstic', 'Stochastic'},'Location','Best');
title('c');
xlabel('t');

接下来做什么?

了解工具箱算法的详细信息。

查看工具箱 API 参考

更多示例: