This is a static copy of a profile report

Home

Function details for ff_ipwkbz_vf_vecsvThis is a static copy of a profile report

Home

ff_ipwkbz_vf_vecsv (Calls: 1, Time: 2.881 s)
Generated 13-Jul-2019 20:40:55 using performance time.
function in file C:\Users\fan\CodeDynaAsset\m_ipwkbz\solve\ff_ipwkbz_vf_vecsv.m
Copy to new window for comparing multiple runs

Parents (calling functions)
No parent
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
225
mt_val_wkb_interpolated = f_gr...
1290.592 s20.5%
241
ff_ipwkbz_evf(mt_val_wkb_inter...
1290.339 s11.8%
292
mt_ev_condi_z_max_interp_z = f...
19350.273 s9.5%
258
mt_w_kstar_interp_z = f_interp...
19350.262 s9.1%
276
ar_utility_update = f_grid_int...
19350.131 s4.5%
All other lines  1.284 s44.6%
Totals  2.881 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
ff_ipwkbz_evffunction1290.330 s11.4%
...coh,bprime,kprime)(coh-kprime-bprime)anonymous function38700.037 s1.3%
linspacefunction19350.018 s0.6%
meanfunction1290.012 s0.4%
Self time (built-ins, overhead, etc.)  2.485 s86.2%
Totals  2.881 s100% 
Code Analyzer results
No Code Analyzer messages.
Coverage results
Show coverage for parent directory
Total lines in function463
Non-code lines (comments, blank lines)253
Code lines (lines that can run)210
Code lines that did run84
Code lines that did not run126
Coverage (did run/can run)40.00 %
Function listing
time 
Calls 
 line
   7 
function result_map = ff_ipwkbz_vf_vecsv(varargin)
   8 
%% FF_IPWKBZ_VF_VECSV solve infinite horizon exo shock + endo asset problem
   9 
% This program solves the infinite horizon dynamic savings and risky
  10 
% capital asset problem with some ar1 shock. This is the two step solution
  11 
% with interpolation and with percentage asset grids version of
  12 
% <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_iwkz_vf_vecsv.html
  13 
% ff_iwkz_vf_vecsv>. See that file for more descriptions.
  14 
%
  15 
% @param param_map container parameter container
  16 
%
  17 
% @param support_map container support container
  18 
%
  19 
% @param armt_map container container with states, choices and shocks
  20 
% grids that are inputs for grid based solution algorithm
  21 
%
  22 
% @param func_map container container with function handles for
  23 
% consumption cash-on-hand etc.
  24 
%
  25 
% @return result_map container contains policy function matrix, value
  26 
% function matrix, iteration results, and policy function, value function
  27 
% and iteration results tables.
  28 
%
  29 
% keys included in result_map:
  30 
%
  31 
% * mt_val matrix states_n by shock_n matrix of converged value function grid
  32 
% * mt_pol_a matrix states_n by shock_n matrix of converged policy function grid
  33 
% * ar_val_diff_norm array if bl_post = true it_iter_last by 1 val function
  34 
% difference between iteration
  35 
% * ar_pol_diff_norm array if bl_post = true it_iter_last by 1 policy
  36 
% function difference between iterations
  37 
% * mt_pol_perc_change matrix if bl_post = true it_iter_last by shock_n the
  38 
% proportion of grid points at which policy function changed between
  39 
% current and last iteration for each element of shock
  40 
%
  41 
% @example
  42 
%
  43 
% @include
  44 
%
  45 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbz/paramfunc/ff_ipwkbz_evf.m ff_ipwkbz_evf>
  46 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbz/paramfunc/ffs_ipwkbz_set_default_param.m ffs_ipwkbz_set_default_param>
  47 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbz/paramfunc/ffs_ipwkbz_get_funcgrid.m ffs_ipwkbz_get_funcgrid>
  48 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_akz/solvepost/ff_akz_vf_post.m ff_akz_vf_post>
  49 
%
  50 

  51 

  52 
%% Default
  53 
% * it_param_set = 1: quick test
  54 
% * it_param_set = 2: benchmark run
  55 
% * it_param_set = 3: benchmark profile
  56 
% * it_param_set = 4: press publish button
  57 

  58 
it_param_set = 3;
  59 
bl_input_override = true;
  60 
[param_map, support_map] = ffs_ipwkbz_set_default_param(it_param_set);
  61 

  62 
% parameters can be set inside ffs_ipwkbz_set_default_param or updated here
  63 
% param_map('it_w_perc_n') = 50;
  64 
% param_map('it_ak_perc_n') = param_map('it_w_perc_n');
  65 
% param_map('it_z_n') = 15;
  66 
% param_map('fl_coh_interp_grid_gap') = 0.025;
  67 
% param_map('it_c_interp_grid_gap') = 0.001;
  68 
% param_map('fl_w_interp_grid_gap') = 0.25;
  69 
% param_map('it_w_perc_n') = 100;
  70 
% param_map('it_ak_perc_n') = param_map('it_w_perc_n');
  71 
% param_map('it_z_n') = 11;
  72 
% param_map('fl_coh_interp_grid_gap') = 0.1;
  73 
% param_map('it_c_interp_grid_gap') = 10^-4;
  74 
% param_map('fl_w_interp_grid_gap') = 0.1;
  75 

  76 
% get armt and func map
  77 
[armt_map, func_map] = ffs_ipwkbz_get_funcgrid(param_map, support_map, bl_input_override); % 1 for override
  78 
default_params = {param_map support_map armt_map func_map};
  79 

  80 
%% Parse Parameters 1
  81 

  82 
% if varargin only has param_map and support_map,
  83 
params_len = length(varargin);
  84 
[default_params{1:params_len}] = varargin{:};
  85 
param_map = [param_map; default_params{1}];
  86 
support_map = [support_map; default_params{2}];
  87 
if params_len >= 1 && params_len <= 2
  88 
    % If override param_map, re-generate armt and func if they are not
  89 
    % provided
  90 
    bl_input_override = true;
  91 
    [armt_map, func_map] = ffs_ipwkbz_get_funcgrid(param_map, support_map, bl_input_override);
  92 
else
  93 
    % Override all
  94 
    armt_map = [armt_map; default_params{3}];
  95 
    func_map = [func_map; default_params{4}];
  96 
end
  97 

  98 
% append function name
  99 
st_func_name = 'ff_ipwkbz_vf_vecsv';
 100 
support_map('st_profile_name_main') = [st_func_name support_map('st_profile_name_main')];
 101 
support_map('st_mat_name_main') = [st_func_name support_map('st_mat_name_main')];
 102 
support_map('st_img_name_main') = [st_func_name support_map('st_img_name_main')];
 103 

 104 
%% Parse Parameters 2
 105 

 106 
% armt_map
 107 
params_group = values(armt_map, {'ar_w_perc', 'ar_w_level', 'ar_z'});
 108 
[ar_w_perc, ar_w_level, ar_z] = params_group{:};
 109 
params_group = values(armt_map, {'ar_interp_c_grid', 'ar_interp_coh_grid', ...
 110 
    'ar_a_meshk', 'ar_k_mesha', ...
 111 
    'mt_interp_coh_grid_mesh_z', 'mt_z_mesh_coh_interp_grid',...
 112 
    'mt_interp_coh_grid_mesh_w_perc',...
 113 
    'mt_w_by_interp_coh_interp_grid'});
 114 
[ar_interp_c_grid, ar_interp_coh_grid, ar_a_meshk, ar_k_mesha, ...
 115 
    mt_interp_coh_grid_mesh_z, mt_z_mesh_coh_interp_grid, ...
 116 
    mt_interp_coh_grid_mesh_w_perc,...
 117 
    mt_w_by_interp_coh_interp_grid] = params_group{:};
 118 
params_group = values(armt_map, {'mt_coh_wkb', 'mt_z_mesh_coh_wkb'});
 119 
[mt_coh_wkb, mt_z_mesh_coh_wkb] = params_group{:};
 120 

 121 
% func_map
 122 
params_group = values(func_map, {'f_util_log', 'f_util_crra', 'f_cons'});
 123 
[f_util_log, f_util_crra, f_cons] = params_group{:};
 124 

 125 
% param_map
 126 
params_group = values(param_map, {'it_z_n', 'fl_crra', 'fl_beta', ...
 127 
    'fl_nan_replace', 'fl_c_min', 'bl_default', 'fl_default_wprime'});
 128 
[it_z_n, fl_crra, fl_beta, fl_nan_replace, fl_c_min, bl_default, fl_default_wprime] = params_group{:};
 129 
params_group = values(param_map, {'it_maxiter_val', 'fl_tol_val', 'fl_tol_pol', 'it_tol_pol_nochange'});
 130 
[it_maxiter_val, fl_tol_val, fl_tol_pol, it_tol_pol_nochange] = params_group{:};
 131 

 132 
% support_map
 133 
params_group = values(support_map, {'bl_profile', 'st_profile_path', ...
 134 
    'st_profile_prefix', 'st_profile_name_main', 'st_profile_suffix',...
 135 
    'bl_time', 'bl_display_defparam', 'bl_graph_evf', 'bl_display', 'it_display_every', 'bl_post'});
 136 
[bl_profile, st_profile_path, ...
 137 
    st_profile_prefix, st_profile_name_main, st_profile_suffix, ...
 138 
    bl_time, bl_display_defparam, bl_graph_evf, bl_display, it_display_every, bl_post] = params_group{:};
 139 
params_group = values(support_map, {'it_display_summmat_rowmax', 'it_display_summmat_colmax'});
 140 
[it_display_summmat_rowmax, it_display_summmat_colmax] = params_group{:};
 141 

 142 
%% Initialize Output Matrixes
 143 

 144 
mt_val_cur = zeros(length(ar_interp_coh_grid),length(ar_z));
 145 
mt_val = mt_val_cur - 1;
 146 
mt_pol_a = zeros(length(ar_interp_coh_grid),length(ar_z));
 147 
mt_pol_a_cur = mt_pol_a - 1;
 148 
mt_pol_k = zeros(length(ar_interp_coh_grid),length(ar_z));
 149 
mt_pol_k_cur = mt_pol_k - 1;
 150 
mt_pol_idx = zeros(length(ar_interp_coh_grid),length(ar_z));
 151 

 152 
% We did not need these in ff_oz_vf or ff_oz_vf_vec
 153 
% see
 154 
% <https://fanwangecon.github.io/M4Econ/support/speed/partupdate/fs_u_c_partrepeat_main.html
 155 
% fs_u_c_partrepeat_main> for why store using cells.
 156 
cl_u_c_store = cell([it_z_n, 1]);
 157 
cl_c_valid_idx = cell([it_z_n, 1]);
 158 
cl_w_kstar_interp_z = cell([it_z_n, 1]);
 159 
for it_z_i = 1:length(ar_z)
 160 
    cl_w_kstar_interp_z{it_z_i} = zeros([length(ar_w_perc), length(ar_interp_coh_grid)]) - 1;
 161 
end
 162 

 163 
%% Initialize Convergence Conditions
 164 

 165 
bl_vfi_continue = true;
 166 
it_iter = 0;
 167 
ar_val_diff_norm = zeros([it_maxiter_val, 1]);
 168 
ar_pol_diff_norm = zeros([it_maxiter_val, 1]);
 169 
mt_pol_perc_change = zeros([it_maxiter_val, it_z_n]);
 170 

 171 
%% Pre-calculate u(c)
 172 
% Interpolation, see
 173 
% <https://fanwangecon.github.io/M4Econ/support/speed/partupdate/fs_u_c_partrepeat_main.html
 174 
% fs_u_c_partrepeat_main> for why interpolate over u(c)
 175 

 176 
% Evaluate
 177 
if (fl_crra == 1)
 178 
    ar_interp_u_of_c_grid = f_util_log(ar_interp_c_grid);
 179 
    fl_u_cmin = f_util_log(fl_c_min);
 180 
else
 181 
    ar_interp_u_of_c_grid = f_util_crra(ar_interp_c_grid);
 182 
    fl_u_cmin = f_util_crra(fl_c_min);
 183 
end
 184 
ar_interp_u_of_c_grid(ar_interp_c_grid <= fl_c_min) = fl_u_cmin;
 185 

 186 
% Get Interpolant
 187 
f_grid_interpolant_spln = griddedInterpolant(ar_interp_c_grid, ar_interp_u_of_c_grid, 'spline', 'nearest');
 188 

 189 
%% Iterate Value Function
 190 
% Loop solution with 4 nested loops
 191 
%
 192 
% # loop 1: over exogenous states
 193 
% # loop 2: over endogenous states
 194 
% # loop 3: over choices
 195 
% # loop 4: add future utility, integration--loop over future shocks
 196 
%
 197 

 198 
% Start Profile
 199 
if (bl_profile)
 200 
    close all;
 201 
    profile off;
 202 
    profile on;
< 0.001 
      1 
 203
end 
 204 

 205 
% Start Timer
< 0.001 
      1 
 206
if (bl_time) 
< 0.001 
      1 
 207
    tic; 
< 0.001 
      1 
 208
end 
 209 

 210 
% Value Function Iteration
< 0.001 
      1 
 211
while bl_vfi_continue 
< 0.001 
    129 
 212
    it_iter = it_iter + 1; 
 213 

 214 
    %% Interpolate (1) reacahble v(coh(k(w,z),b(w,z),z),z) given v(coh, z)
 215 
    % v(coh,z) solved on ar_interp_coh_grid, ar_z grids, see
 216 
    % ffs_ipwkbz_get_funcgrid.m. Generate interpolant based on that, Then
 217 
    % interpolate for the coh reachable levels given the k(w,z) percentage
 218 
    % choice grids in the second stage of the problem
 219 

 220 
    % Generate Interpolant for v(coh,z)
  0.044 
    129 
 221
    f_grid_interpolant_value = griddedInterpolant(... 
    129 
 222
        mt_z_mesh_coh_interp_grid', mt_interp_coh_grid_mesh_z', mt_val_cur', 'linear', 'nearest'); 
 223 

 224 
    % Interpolate for v(coh(k(w,z),b(w,z),z),z)
  0.592 
    129 
 225
    mt_val_wkb_interpolated = f_grid_interpolant_value(mt_z_mesh_coh_wkb, mt_coh_wkb); 
 226 
%     ar_val_wkb_interpolated = f_grid_interpolant_value(mt_z_mesh_coh_wkb(:), mt_coh_wkb(:));
 227 
%     mt_val_wkb_interpolated = reshape(ar_val_wkb_interpolated, size(mt_z_mesh_coh_wkb));
 228 

 229 
    %% Solve Second Stage Problem k*(w,z)
 230 
    % This is the key difference between this function and
 231 
    % <https://fanwangecon.github.io/CodeDynaAsset/m_akz/paramfunc/html/ffs_akz_set_functions.html
 232 
    % ffs_akz_set_functions> which solves the two stages jointly
 233 
    % Interpolation first, because solution coh grid is not the same as all
 234 
    % points reachable by k and b choices given w.
  0.011 
    129 
 235
    support_map('bl_graph_evf') = false; 
< 0.001 
    129 
 236
    if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
      1 
 237
        support_map('bl_graph_evf') = bl_graph_evf; 
< 0.001 
      1 
 238
    end 
< 0.001 
    129 
 239
    bl_input_override = true; 
  0.339 
    129 
 240
    [mt_ev_condi_z_max, ~, mt_ev_condi_z_max_kp, ~] = ... 
    129 
 241
        ff_ipwkbz_evf(mt_val_wkb_interpolated, param_map, support_map, armt_map, bl_input_override); 
 242 

 243 
    %% Solve First Stage Problem w*(z) given k*(w,z)
 244 

 245 
    % loop 1: over exogenous states
< 0.001 
    129 
 246
    for it_z_i = 1:length(ar_z) 
 247 

 248 
        %% A. Interpolate FULL to get k*(w_perc, z), b*(k,w) based on k*(w_level, z)
 249 
        % Generate interpolant for (2) k*(ar_w_perc) from k*(ar_w_level,z)
 250 
        % There are two w=k'+b' arrays. ar_w_level is the level even grid based
 251 
        % on which we solve the 2nd stage problem in ff_ipwkbz_evf.m. Here for
 252 
        % each coh level, we have a different vector of w levels, but the same
 253 
        % vector of percentage ws. So we need to interpolate to get the optimal
 254 
        % k* and b* choices at each percentage level of w.
  0.066 
   1935 
 255
        f_interpolante_w_level_kstar_z = griddedInterpolant(ar_w_level, mt_ev_condi_z_max_kp(:, it_z_i)', 'linear', 'nearest'); 
 256 

 257 
        % Interpolate (2), shift from w_level to w_perc
  0.262 
   1935 
 258
        mt_w_kstar_interp_z = f_interpolante_w_level_kstar_z(mt_w_by_interp_coh_interp_grid); 
  0.028 
   1935 
 259
        mt_w_astar_interp_z = mt_w_by_interp_coh_interp_grid - mt_w_kstar_interp_z; 
 260 

 261 
        % changes in w_perc kstar choices
  0.032 
   1935 
 262
        mt_w_kstar_diff_idx = (cl_w_kstar_interp_z{it_z_i} ~= mt_w_kstar_interp_z); 
 263 

 264 
        %% B. Calculate UPDATE u(c): u(c(coh_level, w_perc)) given k*_interp, b*_interp
 265 
        % Note that compared to
 266 
        % <https://fanwangecon.github.io/CodeDynaAsset/m_akz/paramfunc/html/ffs_akz_set_functions.html
 267 
        % ffs_akz_set_functions> the mt_c here is much smaller the same
 268 
        % number of columns (states) as in the ffs_akz_set_functions file,
 269 
        % but the number of rows equal to ar_w length.
  0.250 
   1935 
 270
        ar_c = f_cons(mt_interp_coh_grid_mesh_w_perc(mt_w_kstar_diff_idx), ... 
   1935 
 271
                      mt_w_astar_interp_z(mt_w_kstar_diff_idx), ... 
   1935 
 272
                      mt_w_kstar_interp_z(mt_w_kstar_diff_idx)); 
 273 

  0.008 
   1935 
 274
        ar_it_c_valid_idx = (ar_c <= fl_c_min); 
 275 
        % EVAL current utility: N by N, f_util defined earlier
  0.131 
   1935 
 276
        ar_utility_update = f_grid_interpolant_spln(ar_c); 
 277 

 278 
        % Update Storage
< 0.001 
   1935 
 279
        if (it_iter == 1) 
< 0.001 
     15 
 280
            cl_u_c_store{it_z_i} = reshape(ar_utility_update, [length(ar_w_perc), length(ar_interp_coh_grid)]); 
< 0.001 
     15 
 281
            cl_c_valid_idx{it_z_i} = reshape(ar_it_c_valid_idx, [length(ar_w_perc), length(ar_interp_coh_grid)]); 
< 0.001 
   1920 
 282
        else 
  0.069 
   1920 
 283
            cl_u_c_store{it_z_i}(mt_w_kstar_diff_idx) = ar_utility_update; 
  0.059 
   1920 
 284
            cl_c_valid_idx{it_z_i}(mt_w_kstar_diff_idx) = ar_it_c_valid_idx; 
< 0.001 
   1935 
 285
        end 
  0.075 
   1935 
 286
        cl_w_kstar_interp_z{it_z_i} = mt_w_kstar_interp_z; 
 287 

 288 
        %% C. Interpolate FULL EV(k*(coh_level, w_perc, z), w - b*|z) based on EV(k*(w_level, z))
 289 
        % Generate Interpolant for (3) EV(k*(ar_w_perc),Z)
  0.068 
   1935 
 290
        f_interpolante_ev_condi_z_max_z = griddedInterpolant(ar_w_level, mt_ev_condi_z_max(:, it_z_i)', 'linear', 'nearest'); 
 291 
        % Interpolate (3), EVAL add on future utility, N by N + N by N
  0.273 
   1935 
 292
        mt_ev_condi_z_max_interp_z = f_interpolante_ev_condi_z_max_z(mt_w_by_interp_coh_interp_grid); 
 293 

 294 
        %% D. Compute FULL U(coh_level, w_perc, z) over all w_perc
  0.037 
   1935 
 295
        mt_utility = cl_u_c_store{it_z_i} + fl_beta*mt_ev_condi_z_max_interp_z; 
 296 

 297 
        % Index update
 298 
        % using the method below is much faster than index replace
 299 
        % see <https://fanwangecon.github.io/M4Econ/support/speed/index/fs_subscript.html fs_subscript>
  0.001 
   1935 
 300
        mt_it_c_valid_idx = cl_c_valid_idx{it_z_i}; 
 301 
        % Default or Not Utility Handling
< 0.001 
   1935 
 302
        if (bl_default) 
 303 
            % if default: only today u(cmin), transition out next period, debt wiped out
  0.035 
   1935 
 304
            fl_v_default = fl_u_cmin + fl_beta*f_interpolante_ev_condi_z_max_z(fl_default_wprime); 
  0.045 
   1935 
 305
            mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_v_default*(mt_it_c_valid_idx); 
 306 
        else
 307 
            % if default is not allowed: v = u(cmin)
 308 
            mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_nan_replace*(mt_it_c_valid_idx);
< 0.001 
   1935 
 309
        end 
 310 

 311 
        % percentage algorithm does not have invalid (check to make sure
 312 
        % min percent is not 0 in ffs_ipwkbz_get_funcgrid.m)
 313 
        % mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_u_neg_c*(mt_it_c_valid_idx);
 314 

 315 
        %% E. Optimize Over Choices: max_{w_perc} U(coh_level, w_perc, z)
 316 
        % Optimization: remember matlab is column major, rows must be
 317 
        % choices, columns must be states
 318 
        % <https://en.wikipedia.org/wiki/Row-_and_column-major_order COLUMN-MAJOR>
  0.121 
   1935 
 319
        [ar_opti_val_z, ar_opti_idx_z] = max(mt_utility); 
 320 

 321 
        % Generate Linear Opti Index
  0.007 
   1935 
 322
        [it_choies_n, it_states_n] = size(mt_utility); 
  0.027 
   1935 
 323
        ar_add_grid = linspace(0, it_choies_n*(it_states_n-1), it_states_n); 
  0.002 
   1935 
 324
        ar_opti_linear_idx_z = ar_opti_idx_z + ar_add_grid; 
 325 

  0.019 
   1935 
 326
        ar_opti_aprime_z = mt_w_astar_interp_z(ar_opti_linear_idx_z); 
  0.011 
   1935 
 327
        ar_opti_kprime_z = mt_w_kstar_interp_z(ar_opti_linear_idx_z); 
  0.016 
   1935 
 328
        ar_opti_c_z = f_cons(ar_interp_coh_grid, ar_opti_aprime_z, ar_opti_kprime_z); 
 329 

 330 
        % Handle Default is optimal or not
< 0.001 
   1935 
 331
        if (bl_default) 
 332 
            % if defaulting is optimal choice, at these states, not required
 333 
            % to default, non-default possible, but default could be optimal
  0.044 
   1935 
 334
            fl_default_opti_kprime = f_interpolante_w_level_kstar_z(fl_default_wprime); 
  0.009 
   1935 
 335
            ar_opti_aprime_z(ar_opti_c_z <= fl_c_min) = fl_default_wprime - fl_default_opti_kprime; 
  0.005 
   1935 
 336
            ar_opti_kprime_z(ar_opti_c_z <= fl_c_min) = fl_default_opti_kprime; 
 337 
        else
 338 
            % if default is not allowed, then next period same state as now
 339 
            % this is absorbing state, this is the limiting case, single
 340 
            % state space point, lowest a and lowest shock has this.
 341 
            ar_opti_aprime_z(ar_opti_c_z <= fl_c_min) = min(ar_a_meshk);
 342 
            ar_opti_kprime_z(ar_opti_c_z <= fl_c_min) = min(ar_k_mesha);
< 0.001 
   1935 
 343
        end 
 344 

 345 
        %% F. Store Results
  0.008 
   1935 
 346
        mt_val(:,it_z_i) = ar_opti_val_z; 
  0.005 
   1935 
 347
        mt_pol_a(:,it_z_i) = ar_opti_aprime_z; 
  0.005 
   1935 
 348
        mt_pol_k(:,it_z_i) = ar_opti_kprime_z; 
  0.001 
   1935 
 349
        if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
     15 
 350
            mt_pol_idx(:,it_z_i) = ar_opti_linear_idx_z; 
< 0.001 
     15 
 351
        end 
 352 

  0.001 
   1935 
 353
    end 
 354 

 355 
    %% Check Tolerance and Continuation
 356 

 357 
    % Difference across iterations
  0.048 
    129 
 358
    ar_val_diff_norm(it_iter) = norm(mt_val - mt_val_cur); 
  0.071 
    129 
 359
    ar_pol_diff_norm(it_iter) = norm(mt_pol_a - mt_pol_a_cur) + norm(mt_pol_k - mt_pol_k_cur); 
  0.009 
    129 
 360
    ar_pol_a_perc_change = sum((mt_pol_a ~= mt_pol_a_cur))/(length(ar_interp_coh_grid)); 
  0.007 
    129 
 361
    ar_pol_k_perc_change = sum((mt_pol_k ~= mt_pol_k_cur))/(length(ar_interp_coh_grid)); 
  0.016 
    129 
 362
    mt_pol_perc_change(it_iter, :) = mean([ar_pol_a_perc_change;ar_pol_k_perc_change]); 
 363 

 364 
    % Update
  0.004 
    129 
 365
    mt_val_cur = mt_val; 
  0.002 
    129 
 366
    mt_pol_a_cur = mt_pol_a; 
  0.002 
    129 
 367
    mt_pol_k_cur = mt_pol_k; 
 368 

 369 
    % Print Iteration Results
< 0.001 
    129 
 370
    if (bl_display && (rem(it_iter, it_display_every)==0)) 
 371 
        fprintf('VAL it_iter:%d, fl_diff:%d, fl_diff_pol:%d\n', ...
 372 
            it_iter, ar_val_diff_norm(it_iter), ar_pol_diff_norm(it_iter));
 373 
        tb_valpol_iter = array2table([mean(mt_val_cur,1);...
 374 
                                      mean(mt_pol_a_cur,1); ...
 375 
                                      mean(mt_pol_k_cur,1); ...
 376 
                                      mt_val_cur(length(ar_interp_coh_grid),:); ...
 377 
                                      mt_pol_a_cur(length(ar_interp_coh_grid),:); ...
 378 
                                      mt_pol_k_cur(length(ar_interp_coh_grid),:)]);
 379 
        tb_valpol_iter.Properties.VariableNames = strcat('z', string((1:size(mt_val_cur,2))));
 380 
        tb_valpol_iter.Properties.RowNames = {'mval', 'map', 'mak', 'Hval', 'Hap', 'Hak'};
 381 
        disp('mval = mean(mt_val_cur,1), average value over a')
 382 
        disp('map  = mean(mt_pol_a_cur,1), average choice over a')
 383 
        disp('mkp  = mean(mt_pol_k_cur,1), average choice over k')
 384 
        disp('Hval = mt_val_cur(it_ameshk_n,:), highest a state val')
 385 
        disp('Hap = mt_pol_a_cur(it_ameshk_n,:), highest a state choice')
 386 
        disp('mak = mt_pol_k_cur(it_ameshk_n,:), highest k state choice')
 387 
        disp(tb_valpol_iter);
 388 
    end
 389 

 390 
    % Continuation Conditions:
 391 
    % 1. if value function convergence criteria reached
 392 
    % 2. if policy function variation over iterations is less than
 393 
    % threshold
< 0.001 
    129 
 394
    if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
      1 
 395
        bl_vfi_continue = false; 
  0.002 
    128 
 396
    elseif ((it_iter == it_maxiter_val) || ... 
    128 
 397
            (ar_val_diff_norm(it_iter) < fl_tol_val) || ... 
    128 
 398
            (sum(ar_pol_diff_norm(max(1, it_iter-it_tol_pol_nochange):it_iter)) < fl_tol_pol)) 
 399 
        % Fix to max, run again to save results if needed
< 0.001 
      1 
 400
        it_iter_last = it_iter; 
< 0.001 
      1 
 401
        it_iter = it_maxiter_val; 
< 0.001 
      1 
 402
    end 
 403 

  0.001 
    129 
 404
end 
 405 

 406 
% End Timer
< 0.001 
      1 
 407
if (bl_time) 
< 0.001 
      1 
 408
    toc; 
< 0.001 
      1 
 409
end 
 410 

 411 
% End Profile
< 0.001 
      1 
 412
if (bl_profile) 
  0.006 
      1 
 413
    profile off 
 414 
    profile viewer
 415 
    st_file_name = [st_profile_prefix st_profile_name_main st_profile_suffix];
 416 
    profsave(profile('info'), strcat(st_profile_path, st_file_name));
 417 
end
 418 

 419 
%% Process Optimal Choices
 420 

 421 
result_map = containers.Map('KeyType','char', 'ValueType','any');
 422 
result_map('mt_val') = mt_val;
 423 
result_map('mt_pol_idx') = mt_pol_idx;
 424 

 425 
result_map('cl_mt_coh') = {mt_interp_coh_grid_mesh_z, zeros(1)};
 426 
result_map('cl_mt_pol_a') = {mt_pol_a, zeros(1)};
 427 
result_map('cl_mt_pol_k') = {mt_pol_k, zeros(1)};
 428 
result_map('cl_mt_pol_c') = {f_cons(mt_interp_coh_grid_mesh_z, mt_pol_a, mt_pol_k), zeros(1)};
 429 
result_map('ar_st_pol_names') = ["cl_mt_coh", "cl_mt_pol_a", "cl_mt_pol_k", "cl_mt_pol_c"];
 430 

 431 

 432 
if (bl_post)
 433 
    bl_input_override = true;
 434 
    result_map('ar_val_diff_norm') = ar_val_diff_norm(1:it_iter_last);
 435 
    result_map('ar_pol_diff_norm') = ar_pol_diff_norm(1:it_iter_last);
 436 
    result_map('mt_pol_perc_change') = mt_pol_perc_change(1:it_iter_last, :);
 437 

 438 
    % graphing based on coh_wkb, but that does not match optimal choice
 439 
    % matrixes for graphs.
 440 
    armt_map('mt_coh_wkb') = mt_interp_coh_grid_mesh_z;
 441 
    armt_map('it_ameshk_n') = length(ar_interp_coh_grid);
 442 
    armt_map('ar_a_meshk') = mt_interp_coh_grid_mesh_z(:,1);
 443 
    armt_map('ar_k_mesha') = zeros(size(mt_interp_coh_grid_mesh_z(:,1)) + 0);
 444 

 445 
    result_map = ff_akz_vf_post(param_map, support_map, armt_map, func_map, result_map, bl_input_override);
 446 
end
 447 

 448 
%% Display Various Containers
 449 

 450 
if (bl_display_defparam)
 451 

 452 
    %% Display 1 support_map
 453 
    fft_container_map_display(support_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 454 

 455 
    %% Display 2 armt_map
 456 
    fft_container_map_display(armt_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 457 

 458 
    %% Display 3 param_map
 459 
    fft_container_map_display(param_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 460 

 461 
    %% Display 4 func_map
 462 
    fft_container_map_display(func_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 463 

 464 
    %% Display 5 result_map
 465 
    fft_container_map_display(result_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 466 

 467 
end
 468 

 469 
end

Other subfunctions in this file are not included in this listing.