This is a static copy of a profile report

Home

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

Home

ff_ipwkbzr_fibs_vf_vecsv (Calls: 1, Time: 102.067 s)
Generated 15-Jul-2019 20:58:06 using performance time.
function in file C:\Users\fan\CodeDynaAsset\m_fibs\m_ipwkbzr_solve\ff_ipwkbzr_fibs_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
349
cl_mt_coh_wkb_mesh_z_r_infbr{i...
65553.743 s52.7%
429
ff_ipwkbzr_fibs_evf(clmt_val_w...
13112.632 s12.4%
493
mt_w_ev_interp_z_wneg = f_inte...
98253.324 s3.3%
487
mt_w_kstar_interp_z_wneg = f_i...
98253.306 s3.2%
509
mt_w_kstar_interp_z(~mt_bl_w_p...
98252.021 s2.0%
All other lines  27.041 s26.5%
Totals  102.067 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
ff_ipwkbzr_fibs_evffunction13112.528 s12.3%
...coh,bprime,kprime)(coh-kprime-bprime)anonymous function196500.274 s0.3%
linspacefunction98250.135 s0.1%
meanfunction1310.012 s0.0%
Self time (built-ins, overhead, etc.)  89.119 s87.3%
Totals  102.067 s100% 
Code Analyzer results
Line numberMessage
79Use of brackets [] is unnecessary. Use parentheses to group, if needed.
90Use of brackets [] is unnecessary. Use parentheses to group, if needed.
149The value assigned here to 'ar_w_level' appears to be unused. Consider replacing it by ~.
172The value assigned here to 'mt_w_perc_mesh_interp_coh_grid' appears to be unused. Consider replacing it by ~.
Coverage results
Show coverage for parent directory
Total lines in function789
Non-code lines (comments, blank lines)447
Code lines (lines that can run)342
Code lines that did run121
Code lines that did not run221
Coverage (did run/can run)35.38 %
Function listing
time 
Calls 
 line
   7 
function result_map = ff_ipwkbzr_fibs_vf_vecsv(varargin)
   8 
%% FF_IPWKBZ_FIBS_VF_VECSV solve infinite horizon exo shock + endo asset problem
   9 
% This is a modified version of
  10 
% <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/solve/html/ff_ipwkbzr_vf_vecsv.html
  11 
% ff_ipwkbzr_vf_vecsv>, to see how this function solves the formal and
  12 
% savings risky and safe asset problem with formal and informal choices,
  13 
% compare the code here and from
  14 
% <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/solve/html/ff_ipwkbzr_vf_vecsv.html
  15 
% ff_ipwkbzr_vf_vecsv> side by side.
  16 
%
  17 
% @param param_map container parameter container
  18 
%
  19 
% @param support_map container support container
  20 
%
  21 
% @param armt_map container container with states, choices and shocks
  22 
% grids that are inputs for grid based solution algorithm
  23 
%
  24 
% @param func_map container container with function handles for
  25 
% consumption cash-on-hand etc.
  26 
%
  27 
% @return result_map container contains policy function matrix, value
  28 
% function matrix, iteration results, and policy function, value function
  29 
% and iteration results tables.
  30 
%
  31 
% keys included in result_map:
  32 
%
  33 
% * mt_val matrix states_n by shock_n matrix of converged value function grid
  34 
% * mt_pol_a matrix states_n by shock_n matrix of converged policy function grid
  35 
% * ar_val_diff_norm array if bl_post = true it_iter_last by 1 val function
  36 
% difference between iteration
  37 
% * ar_pol_diff_norm array if bl_post = true it_iter_last by 1 policy
  38 
% function difference between iterations
  39 
% * mt_pol_perc_change matrix if bl_post = true it_iter_last by shock_n the
  40 
% proportion of grid points at which policy function changed between
  41 
% current and last iteration for each element of shock
  42 
%
  43 
% @example
  44 
%
  45 
% @include
  46 
%
  47 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbzr/paramfunc/ff_ipwkbzr_evf.m ff_ipwkbzr_evf>
  48 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbzr/paramfunc/ffs_ipwkbzr_set_default_param.m ffs_ipwkbzr_set_default_param>
  49 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_ipwkbzr/paramfunc/ffs_ipwkbzr_get_funcgrid.m ffs_ipwkbzr_get_funcgrid>
  50 
% * <https://github.com/FanWangEcon/CodeDynaAsset/blob/master/m_akz/solvepost/ff_akz_vf_post.m ff_akz_vf_post>
  51 
%
  52 

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

  59 
it_param_set = 4;
  60 
[param_map, support_map] = ffs_ipwkbzr_fibs_set_default_param(it_param_set);
  61 

  62 
% parameters can be set inside ffs_ipwkbzr_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('fl_coh_interp_grid_gap') = 0.025;
  66 
% param_map('it_c_interp_grid_gap') = 0.001;
  67 
% param_map('fl_w_interp_grid_gap') = 0.25;
  68 
% param_map('it_w_perc_n') = 100;
  69 
% param_map('it_ak_perc_n') = param_map('it_w_perc_n');
  70 
% param_map('fl_z_r_infbr_n') = 5;
  71 
% param_map('it_z_wage_n') = 15;
  72 
% param_map('it_z_n') = param_map('it_z_wage_n') * param_map('fl_z_r_infbr_n');
  73 
% param_map('fl_coh_interp_grid_gap') = 0.1;
  74 
% param_map('it_c_interp_grid_gap') = 10^-4;
  75 
% param_map('fl_w_interp_grid_gap') = 0.1;
  76 

  77 
st_param_which = 'default';
  78 

  79 
if (ismember(st_param_which, ['default']))
  80 
    
  81 
    % default
  82 

  83 
elseif ismember(st_param_which, ['ff_ipwkbzr_vf_vecsv', 'ff_ipwkbzrr_vf_vecsv'])
  84 

  85 
    param_map('fl_r_fsv') = 0.0;
  86 
    param_map('fl_r_fbr') = 1.000;
  87 
    param_map('bl_bridge') = false;
  88 
    param_map('it_coh_bridge_perc_n') = 1;
  89 
    
  90 
    if ismember(st_param_which, ['ff_ipwkbzr_vf_vecsv'])
  91 

  92 
        % ff_ipwkbzr_evf default
  93 
        param_map('fl_z_r_infbr_min') = 0.025;
  94 
        param_map('fl_z_r_infbr_max') = 0.025;
  95 
        param_map('fl_z_r_infbr_n') = 1;
  96 

  97 
        param_map('fl_r_save') = 0.025;
  98 

  99 
    end
 100 
    
 101 
    param_map('it_z_n') = param_map('it_z_wage_n') * param_map('fl_z_r_infbr_n');    
 102 
    
 103 
end
 104 

 105 
% get armt and func map
 106 
params_len = length(varargin);
 107 
if params_len <= 2
 108 
    [armt_map, func_map] = ffs_ipwkbzr_fibs_get_funcgrid(param_map, support_map); % 1 for override
 109 
    default_params = {param_map support_map armt_map func_map};
 110 
end
 111 

 112 
%% Parse Parameters 1
 113 

 114 
% if varargin only has param_map and support_map,
 115 
[default_params{1:params_len}] = varargin{:};
 116 
param_map = [param_map; default_params{1}];
 117 
support_map = [support_map; default_params{2}];
 118 
if params_len >= 1 && params_len <= 2
 119 
    % If override param_map, re-generate armt and func if they are not
 120 
    % provided
 121 
    [armt_map, func_map] = ffs_ipwkbzr_fibs_get_funcgrid(param_map, support_map);
 122 
else
 123 
    armt_map = default_params{3};
 124 
    func_map = default_params{4};
 125 
end
 126 

 127 
% append function name
 128 
st_func_name = 'ff_ipwkbzr_fibs_vf_vecsv';
 129 
support_map('st_profile_name_main') = [st_func_name support_map('st_profile_name_main')];
 130 
support_map('st_mat_name_main') = [st_func_name support_map('st_mat_name_main')];
 131 
support_map('st_img_name_main') = [st_func_name support_map('st_img_name_main')];
 132 

 133 
%% Parse Parameters 2, Asset Arrays
 134 
% Dimensions of Various Grids: I for level grid, M for shock grid, P for
 135 
% percent grid
 136 
%
 137 
% # ar_interp_c_grid: 1 by I^c, 1st stage consumption interpolation
 138 
% # ar_interp_coh_grid: 1 by I^{coh}, 1st stage value function V(coh,z)
 139 
% # ar_w_perc: 1 by P^{W=k+b}, 1st stage w \in {w_perc(coh)} choice set
 140 
% # ar_w_level: 1 by I^{W=k+b}, 2nd stage k*(w,z) w grid
 141 
% # ar_ak_perc: 1 by P^{k and b}, 2nd stage k \in {ask_perc(w,z)} set
 142 
%
 143 

 144 
params_group = values(armt_map, {...
 145 
    'ar_interp_c_grid', 'ar_interp_coh_grid', ...
 146 
    'ar_w_perc', 'ar_w_level', 'ar_w_level_full', 'ar_ak_perc', ...
 147 
    'ar_coh_bridge_perc'});
 148 
[ar_interp_c_grid, ar_interp_coh_grid, ...
 149 
    ar_w_perc, ar_w_level, ar_w_level_full, ar_ak_perc, ...
 150 
    ar_coh_bridge_perc] = params_group{:};
 151 

 152 
%% Parse Parameters 2, interp_coh related matrixes
 153 
% Dimensions of Various Grids: I for level grid, M for shock grid, P for
 154 
% percent grid. These are grids for 1st stage solution
 155 
%
 156 
% # mt_interp_coh_grid_mesh_z_wage: I^{coh} by M^w
 157 
% # mt_z_wage_mesh_interp_coh_grid: I^{coh} by M^w
 158 
% # mt_interp_coh_grid_mesh_w_perc: I^{coh} by P^{LAM=k+b}
 159 
% # mt_w_perc_mesh_interp_coh_grid: I^{coh} by P^{LAM=k+b}
 160 
%
 161 

 162 
params_group = values(armt_map, {...
 163 
    'mt_interp_coh_grid_mesh_z_wage', ...
 164 
    'mt_interp_coh_grid_mesh_w_perc', ...
 165 
    'mt_z_wage_mesh_interp_coh_grid', ...
 166 
    'mt_w_perc_mesh_interp_coh_grid', ...
 167 
    'mt_interp_coh_grid_mesh_z', 'mt_z_mesh_interp_coh_grid' ...
 168 
    'cl_mt_coh_wkb_mesh_z_r_infbr', 'mt_z_mesh_coh_wkb_seg'});
 169 
[mt_interp_coh_grid_mesh_z_wage, ...
 170 
    mt_interp_coh_grid_mesh_w_perc, ...
 171 
    mt_z_wage_mesh_interp_coh_grid, ...
 172 
    mt_w_perc_mesh_interp_coh_grid, ...
 173 
    mt_interp_coh_grid_mesh_z, mt_z_mesh_interp_coh_grid, ...
 174 
    cl_mt_coh_wkb_mesh_z_r_infbr, mt_z_mesh_coh_wkb_seg] = params_group{:};
 175 

 176 
%% Parse Parameters 3, reachable cash-on-hand
 177 
% Dimensions of Various Grids: I for level grid, M for shock grid, P for
 178 
% percent grid. These are grids for 1st stage solution
 179 
%
 180 
% # mt_coh_wkb: (I^k x I^{w+%repay} x M^r) by (M^z)
 181 
% # mt_z_wage_mesh_coh_wkb: (I^k x I^{w+%repay} x M^r) by (M^z)
 182 
%
 183 

 184 
params_group = values(armt_map, {'mt_coh_wkb', 'mt_z_wage_mesh_coh_wkb'});
 185 
[mt_coh_wkb, mt_z_wage_mesh_coh_wkb] = params_group{:};
 186 

 187 
%% Parse Parameters 4, percentage of w for bridge repayment parameters
 188 
%
 189 
% Note, w=k'+b', where w < 0:
 190 
%
 191 
%   mt_w_perc_mesh_interp_coh_grid = ((ar_interp_coh_grid-fl_min_mt_coh)'*ar_w_perc)' + fl_min_mt_coh;
 192 
%   mt_bl_w_perc_mesh_interp_coh_grid_wneg = (mt_w_perc_mesh_interp_coh_grid < 0);
 193 
%   mt_w_perc_mesh_interp_coh_grid_wneg = mt_w_perc_mesh_interp_coh_grid(mt_bl_w_perc_mesh_interp_coh_grid_wneg);
 194 
%   mt_w_perc_mesh_interp_coh_grid_wpos = mt_w_perc_mesh_interp_coh_grid(~mt_bl_w_perc_mesh_interp_coh_grid_wneg);
 195 
%
 196 
% And for negative w levels meshed with bridge shares:
 197 
%
 198 
%   [mt_w_level_neg_mesh_coh_bridge_perc, mt_coh_bridge_perc_mesh_w_level_neg] = ...
 199 
%        ndgrid(ar_w_level_neg, ar_coh_bridge_perc);
 200 
%
 201 
% And for percent of w NOT going to bridge:
 202 
%
 203 
%   mt_coh_w_perc_ratio = (1-(mt_interp_coh_grid_mesh_w_perc./mt_w_perc_mesh_interp_coh_grid));
 204 
%   mt_coh_w_perc_ratio(mt_interp_coh_grid_mesh_w_perc >= 0) = 1;
 205 
%   mt_coh_w_perc_ratio_wneg = mt_coh_w_perc_ratio(mt_bl_w_perc_mesh_interp_coh_grid_wneg);
 206 
%
 207 

 208 
params_group = values(armt_map, {
 209 
 'mt_w_level_neg_mesh_coh_bridge_perc', 'mt_coh_bridge_perc_mesh_w_level_neg',...
 210 
    'mt_bl_w_perc_mesh_interp_coh_grid_wneg', ...
 211 
    'mt_w_perc_mesh_interp_coh_grid_wneg', 'mt_w_perc_mesh_interp_coh_grid_wpos', ...
 212 
    'mt_coh_w_perc_ratio_wneg'});
 213 
[mt_w_level_neg_mesh_coh_bridge_perc,    mt_coh_bridge_perc_mesh_w_level_neg, ...
 214 
     mt_bl_w_perc_mesh_interp_coh_grid_wneg, ...
 215 
     mt_w_perc_mesh_interp_coh_grid_wneg,   mt_w_perc_mesh_interp_coh_grid_wpos, ...
 216 
     mt_coh_w_perc_ratio_wneg] ...
 217 
        = params_group{:};
 218 

 219 
%% Parse Parameters 6, other asset arrays
 220 

 221 
params_group = values(armt_map, {'ar_z_r_infbr_mesh_wage_w1r2'});
 222 
[ar_z_r_infbr_mesh_wage_w1r2] = params_group{:};
 223 

 224 
params_group = values(armt_map, {'ar_a_meshk', 'ar_k_mesha'});
 225 
[ar_a_meshk, ar_k_mesha] = params_group{:};
 226 

 227 
%% Parse Parameters 7, Others
 228 

 229 
% func_map
 230 
params_group = values(func_map, {'f_util_log', 'f_util_crra', 'f_cons'});
 231 
[f_util_log, f_util_crra, f_cons] = params_group{:};
 232 

 233 
% param_map
 234 
params_group = values(param_map, {'fl_crra', 'fl_beta', ...
 235 
    'fl_nan_replace', 'fl_c_min',  'bl_bridge', 'bl_default', 'fl_default_wprime'});
 236 
[fl_crra, fl_beta, fl_nan_replace, fl_c_min, bl_bridge, bl_default, fl_default_wprime] = params_group{:};
 237 
params_group = values(param_map, {'it_maxiter_val', 'fl_tol_val', 'fl_tol_pol', 'it_tol_pol_nochange'});
 238 
[it_maxiter_val, fl_tol_val, fl_tol_pol, it_tol_pol_nochange] = params_group{:};
 239 
params_group = values(param_map, {'it_z_n', 'fl_z_r_infbr_n', 'it_z_wage_n'});
 240 
[it_z_n, fl_z_r_infbr_n, it_z_wage_n] = params_group{:};
 241 
params_group = values(param_map, {'st_v_coh_z_interp_method'});
 242 
[st_v_coh_z_interp_method] = params_group{:};
 243 

 244 
% support_map
 245 
params_group = values(support_map, {'bl_profile', 'st_profile_path', ...
 246 
    'st_profile_prefix', 'st_profile_name_main', 'st_profile_suffix',...
 247 
    'bl_time', 'bl_display_defparam', 'bl_graph_evf', 'bl_display', 'it_display_every', 'bl_post'});
 248 
[bl_profile, st_profile_path, ...
 249 
    st_profile_prefix, st_profile_name_main, st_profile_suffix, ...
 250 
    bl_time, bl_display_defparam, bl_graph_evf, bl_display, it_display_every, bl_post] = params_group{:};
 251 
params_group = values(support_map, {'it_display_summmat_rowmax', 'it_display_summmat_colmax'});
 252 
[it_display_summmat_rowmax, it_display_summmat_colmax] = params_group{:};
 253 

 254 
%% Initialize Output Matrixes
 255 

 256 
mt_val_cur = zeros(length(ar_interp_coh_grid),it_z_n);
 257 
mt_val = mt_val_cur - 1;
 258 
mt_pol_a = zeros(length(ar_interp_coh_grid),it_z_n);
 259 
mt_pol_a_cur = mt_pol_a - 1;
 260 
mt_pol_k = zeros(length(ar_interp_coh_grid),it_z_n);
 261 
mt_pol_k_cur = mt_pol_k - 1;
 262 
mt_pol_idx = zeros(length(ar_interp_coh_grid),it_z_n);
 263 

 264 
% collect optimal borrowing formal and informal choices
 265 
% mt_pol_b_with_r: cost to t+1 consumption from borrowing in t
 266 
mt_pol_b_with_r = zeros(length(ar_interp_coh_grid),it_z_n);
 267 
mt_pol_b_bridge = zeros(length(ar_interp_coh_grid),it_z_n);
 268 
mt_pol_inf_borr_nobridge = zeros(length(ar_interp_coh_grid),it_z_n);
 269 
mt_pol_for_borr = zeros(length(ar_interp_coh_grid),it_z_n);
 270 
mt_pol_for_save = zeros(length(ar_interp_coh_grid),it_z_n);
 271 

 272 
% We did not need these in ff_oz_vf or ff_oz_vf_vec
 273 
% see
 274 
% <https://fanwangecon.github.io/M4Econ/support/speed/partupdate/fs_u_c_partrepeat_main.html
 275 
% fs_u_c_partrepeat_main> for why store using cells.
 276 
cl_u_c_store = cell([it_z_n, 1]);
 277 
cl_c_valid_idx = cell([it_z_n, 1]);
 278 
cl_w_kstar_interp_z = cell([it_z_n, 1]);
 279 
for it_z_i = 1:it_z_n
 280 
    cl_w_kstar_interp_z{it_z_i} = zeros([length(ar_w_perc), length(ar_interp_coh_grid)]) - 1;
 281 
end
 282 

 283 
clmt_val_wkb_interpolated = cell([fl_z_r_infbr_n, 1]);
 284 

 285 
%% Initialize Convergence Conditions
 286 

 287 
bl_vfi_continue = true;
 288 
it_iter = 0;
 289 
ar_val_diff_norm = zeros([it_maxiter_val, 1]);
 290 
ar_pol_diff_norm = zeros([it_maxiter_val, 1]);
 291 
mt_pol_perc_change = zeros([it_maxiter_val, it_z_n]);
 292 

 293 
%% Pre-calculate u(c)
 294 
% Interpolation, see
 295 
% <https://fanwangecon.github.io/M4Econ/support/speed/partupdate/fs_u_c_partrepeat_main.html
 296 
% fs_u_c_partrepeat_main> for why interpolate over u(c)
 297 

 298 
% Evaluate
 299 
if (fl_crra == 1)
 300 
    ar_interp_u_of_c_grid = f_util_log(ar_interp_c_grid);
 301 
    fl_u_cmin = f_util_log(fl_c_min);
 302 
else
 303 
    ar_interp_u_of_c_grid = f_util_crra(ar_interp_c_grid);
 304 
    fl_u_cmin = f_util_crra(fl_c_min);
 305 
end
 306 
ar_interp_u_of_c_grid(ar_interp_c_grid <= fl_c_min) = fl_u_cmin;
 307 

 308 
% Get Interpolant
 309 
f_grid_interpolant_spln = griddedInterpolant(ar_interp_c_grid, ar_interp_u_of_c_grid, 'spline', 'nearest');
 310 

 311 
%% Iterate Value Function
 312 
% Loop solution with 4 nested loops
 313 
%
 314 
% # loop 1: over exogenous states
 315 
% # loop 2: over endogenous states
 316 
% # loop 3: over choices
 317 
% # loop 4: add future utility, integration--loop over future shocks
 318 
%
 319 

 320 
% Start Profile
 321 
if (bl_profile)
 322 
    close all;
 323 
    profile off;
 324 
    profile on;
< 0.001 
      1 
 325
end 
 326 

 327 
% Start Timer
< 0.001 
      1 
 328
if (bl_time) 
< 0.001 
      1 
 329
    tic; 
< 0.001 
      1 
 330
end 
 331 

 332 
% Value Function Iteration
< 0.001 
      1 
 333
while bl_vfi_continue 
< 0.001 
    131 
 334
    it_iter = it_iter + 1; 
 335 
    
 336 
    %% Interpolate V(coh, Z) 1: Store in Cell
 337 
    % Interpolate reacahble V(coh(k'(w),b'(w),zr,zw'),zw',zr')) given v(coh, z)
 338 

  0.003 
    131 
 339
    if (strcmp(st_v_coh_z_interp_method, "method_cell")) 
 340 
        
  0.148 
    131 
 341
        f_grid_interpolant_value = griddedInterpolant(... 
    131 
 342
            mt_z_mesh_interp_coh_grid', mt_interp_coh_grid_mesh_z', ... 
    131 
 343
            mt_val_cur', 'linear', 'nearest'); 
 344 

< 0.001 
    131 
 345
        for it_z_r_infbr_ctr = 1:1:fl_z_r_infbr_n 
 346 

 53.744 
    655 
 347
            clmt_val_wkb_interpolated{it_z_r_infbr_ctr} = ... 
    655 
 348
                f_grid_interpolant_value(mt_z_mesh_coh_wkb_seg,... 
    655 
 349
                                         cl_mt_coh_wkb_mesh_z_r_infbr{it_z_r_infbr_ctr}); 
  0.002 
    655 
 350
        end 
< 0.001 
    131 
 351
    end         
 352 
    
 353 
    %% Interpolate V(coh, Z) 5: Matrix Store    
 354 
    % Interpolate reacahble V(coh(k'(w),b'(w),zr,zw'),zw',zr')) given v(coh, z)
 355 
    % This is the same as <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/solve/html/ff_ipwkbzr_vf_vecsv.html
 356 
    % ff_ipwkbzr_vf_vecsv>. For the FIBS problem, the cash-on-hand
 357 
    % interpolation grid stays the same, and the shock grid stays the same
 358 
    % as well. The results will not be the same, for example, the coh_grid
 359 
    % max is the max of reachable cash-on-hand levels (min is however just
 360 
    % the borrowing bound).
 361 
    
  0.003 
    131 
 362
    if (strcmp(st_v_coh_z_interp_method, "method_mat_seg")) 
 363 
        
 364 
        % 1. Number of W/B/K Choice Combinations
 365 
        it_ak_perc_n = length(ar_ak_perc);
 366 
        it_w_interp_n = length(ar_w_level_full);
 367 
        it_wak_n = it_w_interp_n*it_ak_perc_n;
 368 

 369 
        % 2. Initialize V(coh(k'(w),b'(w),zr,zw'),zw',zr'))
 370 
        % mt_val_wkb_interpolated is: (I^k x I^w x M^r) by (M^z x M^r)
 371 
        % reachable cash-on-hand (as rows) and shocks next period given choices
 372 
        % and shocks next period.
 373 
        clmt_val_wkb_interpolated = zeros([it_wak_n*fl_z_r_infbr_n, it_z_n]);
 374 

 375 
        % 3. Loop over possible shocks over interest rate
 376 
        for it_z_r_infbr_ctr = 1:1:fl_z_r_infbr_n
 377 

 378 
            % 4. Interpolate V(coh(k',b',z',r),z',r') for a specific r'
 379 
            % v(coh,z) solved on ar_interp_coh_grid, ar_z grids, see
 380 
            % ffs_ipwkbzr_get_funcgrid.m. Generate interpolant based on that, Then
 381 
            % interpolate for the coh reachable levels given the k(w,z) percentage
 382 
            % choice grids in the second stage of the problem.
 383 
            %
 384 
            % Note mt_val_cur/mt_val dimension is based on interpolant
 385 
            % cash-on-hand for rows, and meshed shocks for columns. The meshed
 386 
            % shock structure, see
 387 
            % <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/paramfunc/html/ffs_ipwkbzr_get_funcgrid.html
 388 
            % ffs_ipwkbzr_get_funcgrid> for details on how the shock grids are
 389 
            % formed.
 390 

 391 
            % Get current z_r_infbr from mt_val
 392 
            it_mt_val_col_start = it_z_wage_n*(it_z_r_infbr_ctr-1) + 1;
 393 
            it_mt_val_col_end   = it_mt_val_col_start + it_z_wage_n - 1;
 394 
            mt_val_cur_rcolseg =  mt_val_cur(:, it_mt_val_col_start:it_mt_val_col_end);
 395 

 396 
            % Generate Interpolant for v(coh,z)
 397 
            % mt_z_wage_mesh_interp_coh_grid is: (I^{coh_interp}) by (M^z)
 398 
            f_grid_interpolant_value = griddedInterpolant(...
 399 
                mt_z_wage_mesh_interp_coh_grid', mt_interp_coh_grid_mesh_z_wage', ...
 400 
                mt_val_cur_rcolseg', 'linear', 'nearest');
 401 

 402 
            % Interpolate V(coh(k',b',z',r),z',r') for a specific r'
 403 
            % mt_z_wage_mesh_coh_wkb and mt_coh_wkb are: (I^k x I^w x M^r) by (M^z)
 404 
            mt_val_wkb_interpolated_seg = f_grid_interpolant_value(mt_z_wage_mesh_coh_wkb, mt_coh_wkb);
 405 
            clmt_val_wkb_interpolated(:, it_mt_val_col_start:it_mt_val_col_end) = mt_val_wkb_interpolated_seg;
 406 

 407 
        end
 408 
    end
 409 

 410 
    %% Solve Second Stage Problem k*(w,z)
 411 
    % This is again the same as <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/solve/html/ff_ipwkbzr_vf_vecsv.html
 412 
    % ff_ipwkbzr_vf_vecsv>. But the output matrix sizes are different.
 413 
    % Previously, they were (length(ar_w_level)) by (it_z_n). Now
 414 
    % have this thing which is stored (length(ar_w_level_full)) by
 415 
    % (it_z_n). _ar_w_level_full_ includes not just different levels
 416 
    % of _ar_w_level_, but also repeats the elements of _ar_w_level_ that
 417 
    % are < 0 by _it_coh_bridge_perc_n_ times, starting with what
 418 
    % corresponds to 100 percent of w should go to cover bridge loan, until
 419 
    % 0 percent for w < 0, which then proceeds to w > 0. So the last
 420 
    % segment of _ar_w_level_full_ is the same as ar_w_level:
 421 
    % ar_w_level_full((end-length(ar_w_level)+1):end) = ar_w_level.
 422 
    
  0.016 
    131 
 423
    support_map('bl_graph_evf') = false; 
< 0.001 
    131 
 424
    if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
      1 
 425
        support_map('bl_graph_evf') = bl_graph_evf; 
< 0.001 
      1 
 426
    end 
< 0.001 
    131 
 427
    bl_input_override = true; 
 12.632 
    131 
 428
    [mt_ev_condi_z_max, ~, mt_ev_condi_z_max_kp, ~] = ... 
    131 
 429
        ff_ipwkbzr_fibs_evf(clmt_val_wkb_interpolated, param_map, support_map, armt_map, bl_input_override); 
 430 

 431 
    %% Solve First Stage Problem w*(z) given k*(w,z)
 432 
    % Refer to
 433 
    % <https://fanwangecon.github.io/CodeDynaAsset/m_ipwkbzr/solve/html/ff_ipwkbzr_fibs_vf_vecsv.html
 434 
    % ff_ipwkbzr_fibs_vf_vecsv> where the problem was solved without formal and
 435 
    % informal choices that allow for bridge loans to see line by line how
 436 
    % code differ. Some of the comments from that file are not here to save
 437 
    % space. Comments here address differences and are specific to formal
 438 
    % and informal choices. 
 439 
    
 440 
    % loop 1: over exogenous states
< 0.001 
    131 
 441
    for it_z_i = 1:it_z_n 
 442 

 443 
        %% A. Interpolate FULL to get k*(coh_level, w_perc, z), b*(k,w) based on k*(coh_perc, w_level)
 444 
        % additionally, Interpolate FULL EV(k*(coh_level, w_perc, z), w -
 445 
        % b*|z) based on EV(k*(coh_perc, w_level))
 446 
        %
 447 
        % we solved the second period problem in ff_ipwkbzr_fibs_fibs_evf.m
 448 
        % above. To use results, we need to interpolate in the following
 449 
        % way to obtain *mt_w_kstar_interp_z* as well as
 450 
        % *mt_ev_condi_z_max_interp_z*:
 451 
        %
 452 
        % # Interp STG1A: for $w > 0$, 1D interpolate over w level, given z
 453 
        % # Interp STG1B: for $w < 0$, 2D interpolate over w level and coh
 454 
        % perceng, given z
 455 
        %
 456 
        
 457 
        % 1. Negative Elements of w grid expanded by w percentages for bridge        
  0.035 
   9825 
 458
        ar_bl_w_level_full_neg = (ar_w_level_full < 0); 
 459 
        
 460 
        % 2. Current Positve w and negative w optimal k choices
  0.038 
   9825 
 461
        it_wneg_mt_row = sum(ar_bl_w_level_full_neg)/length(ar_coh_bridge_perc); 
 462 
        % for mt_ev_condi_z_max_kp
  0.122 
   9825 
 463
        ar_ev_condi_z_max_kp_wpos = mt_ev_condi_z_max_kp(~ar_bl_w_level_full_neg, it_z_i)'; 
  0.085 
   9825 
 464
        ar_ev_condi_z_max_kp_wneg = mt_ev_condi_z_max_kp(ar_bl_w_level_full_neg, it_z_i)'; 
  0.035 
   9825 
 465
        mt_ev_condi_z_max_kp_wneg = reshape(ar_ev_condi_z_max_kp_wneg, [it_wneg_mt_row, length(ar_coh_bridge_perc)]); 
 466 
        % for mt_ev_condi_z_max
  0.094 
   9825 
 467
        ar_ev_condi_z_max_wpos = mt_ev_condi_z_max(~ar_bl_w_level_full_neg, it_z_i)'; 
  0.080 
   9825 
 468
        ar_ev_condi_z_max_wneg = mt_ev_condi_z_max(ar_bl_w_level_full_neg, it_z_i)'; 
  0.016 
   9825 
 469
        mt_ev_condi_z_max_wneg = reshape(ar_ev_condi_z_max_wneg, [it_wneg_mt_row, length(ar_coh_bridge_perc)]); 
 470 
        
 471 
        % 2. Interp STG1A for w > 0        
  0.084 
   9825 
 472
        ar_w_level_full_pos = ar_w_level_full(~ar_bl_w_level_full_neg); 
 473 
        % Interpolation for mt_ev_condi_z_max_kp 
  0.413 
   9825 
 474
        f_interpolante_w_level_pos_kstar_z = griddedInterpolant(ar_w_level_full_pos, ar_ev_condi_z_max_kp_wpos, 'linear', 'nearest');        
  1.909 
   9825 
 475
        mt_w_kstar_interp_z_wpos = f_interpolante_w_level_pos_kstar_z(mt_w_perc_mesh_interp_coh_grid_wpos(:)); 
  0.140 
   9825 
 476
        mt_w_astar_interp_z_wpos = mt_w_perc_mesh_interp_coh_grid_wpos(:) - mt_w_kstar_interp_z_wpos; 
 477 
        % Interpolation for mt_ev_condi_z_max
  0.461 
   9825 
 478
        f_interpolante_w_level_pos_ev_z = griddedInterpolant(ar_w_level_full_pos, ar_ev_condi_z_max_wpos, 'linear', 'nearest');        
  1.642 
   9825 
 479
        mt_w_ev_interp_z_wpos = f_interpolante_w_level_pos_ev_z(mt_w_perc_mesh_interp_coh_grid_wpos(:)); 
 480 
                
 481 
        % 3. Interp STG1B for w <= 0 
  0.003 
   9825 
 482
        if (bl_bridge) 
 483 
            % Interpolation for mt_ev_condi_z_max_kp
  0.669 
   9825 
 484
            f_interpolante_w_level_neg_kstar_z = griddedInterpolant(... 
   9825 
 485
                mt_coh_bridge_perc_mesh_w_level_neg', mt_w_level_neg_mesh_coh_bridge_perc', ... 
   9825 
 486
                mt_ev_condi_z_max_kp_wneg', 'linear', 'nearest'); 
  3.306 
   9825 
 487
            mt_w_kstar_interp_z_wneg = f_interpolante_w_level_neg_kstar_z(mt_coh_w_perc_ratio_wneg(:), mt_w_perc_mesh_interp_coh_grid_wneg(:)); 
  0.191 
   9825 
 488
            mt_w_astar_interp_z_wneg = mt_w_perc_mesh_interp_coh_grid_wneg(:) - mt_w_kstar_interp_z_wneg; 
 489 
            % Interpolation for mt_ev_condi_z_max
  0.716 
   9825 
 490
            f_interpolante_w_level_neg_ev_z = griddedInterpolant(... 
   9825 
 491
                mt_coh_bridge_perc_mesh_w_level_neg', mt_w_level_neg_mesh_coh_bridge_perc', ... 
   9825 
 492
                mt_ev_condi_z_max_wneg', 'linear', 'nearest'); 
  3.324 
   9825 
 493
            mt_w_ev_interp_z_wneg = f_interpolante_w_level_neg_ev_z(mt_coh_w_perc_ratio_wneg(:), mt_w_perc_mesh_interp_coh_grid_wneg(:)); 
 494 
        else
 495 
            ar_w_level_full_neg = ar_w_level_full(ar_bl_w_level_full_neg);
 496 
            % Interpolation for mt_ev_condi_z_max_kp 
 497 
            f_interpolante_w_level_neg_kstar_z = griddedInterpolant(ar_w_level_full_neg, ar_ev_condi_z_max_kp_wneg, 'linear', 'nearest');       
 498 
            mt_w_kstar_interp_z_wneg = f_interpolante_w_level_neg_kstar_z(mt_w_perc_mesh_interp_coh_grid_wneg(:));
 499 
            mt_w_astar_interp_z_wneg = mt_w_perc_mesh_interp_coh_grid_wneg(:) - mt_w_kstar_interp_z_wneg;
 500 
            % Interpolation for mt_ev_condi_z_max
 501 
            f_interpolante_w_level_neg_ev_z = griddedInterpolant(ar_w_level_full_neg, ar_ev_condi_z_max_wneg, 'linear', 'nearest');       
 502 
            mt_w_ev_interp_z_wneg = f_interpolante_w_level_neg_ev_z(mt_w_perc_mesh_interp_coh_grid_wneg(:));            
  0.002 
   9825 
 503
        end 
 504 
                
 505 
        % 4. Combine positive and negative aggregate savings matrix
 506 
        % check: mt_w_by_interp_coh_interp_grid vs mt_w_astar_interp_z + mt_w_kstar_interp_z
 507 
        % combine for mt_ev_condi_z_max_kp
  0.728 
   9825 
 508
        mt_w_kstar_interp_z = zeros(size(mt_bl_w_perc_mesh_interp_coh_grid_wneg)); 
  2.021 
   9825 
 509
        mt_w_kstar_interp_z(~mt_bl_w_perc_mesh_interp_coh_grid_wneg) = mt_w_kstar_interp_z_wpos; 
  1.452 
   9825 
 510
        mt_w_kstar_interp_z(mt_bl_w_perc_mesh_interp_coh_grid_wneg)  = mt_w_kstar_interp_z_wneg; 
  1.203 
   9825 
 511
        mt_w_astar_interp_z = zeros(size(mt_bl_w_perc_mesh_interp_coh_grid_wneg)); 
  2.015 
   9825 
 512
        mt_w_astar_interp_z(~mt_bl_w_perc_mesh_interp_coh_grid_wneg) = mt_w_astar_interp_z_wpos; 
  1.403 
   9825 
 513
        mt_w_astar_interp_z(mt_bl_w_perc_mesh_interp_coh_grid_wneg)  = mt_w_astar_interp_z_wneg;                 
 514 
        % combine for mt_ev_condi_z_max
  1.179 
   9825 
 515
        mt_ev_condi_z_max_interp_z = zeros(size(mt_bl_w_perc_mesh_interp_coh_grid_wneg)); 
  2.014 
   9825 
 516
        mt_ev_condi_z_max_interp_z(~mt_bl_w_perc_mesh_interp_coh_grid_wneg) = mt_w_ev_interp_z_wpos; 
  1.431 
   9825 
 517
        mt_ev_condi_z_max_interp_z(mt_bl_w_perc_mesh_interp_coh_grid_wneg)  = mt_w_ev_interp_z_wneg; 
 518 
        
 519 
        % 5. changes in w_perc kstar choices
  0.420 
   9825 
 520
        mt_w_kstar_diff_idx = (cl_w_kstar_interp_z{it_z_i} ~= mt_w_kstar_interp_z); 
 521 

 522 
        %% B. Calculate UPDATE u(c) Update: u(c(coh_level, w_perc)) given k*_interp, b*_interp
  1.677 
   9825 
 523
        ar_c = f_cons(mt_interp_coh_grid_mesh_w_perc(mt_w_kstar_diff_idx), ... 
   9825 
 524
                      mt_w_astar_interp_z(mt_w_kstar_diff_idx), ... 
   9825 
 525
                      mt_w_kstar_interp_z(mt_w_kstar_diff_idx)); 
 526 

  0.055 
   9825 
 527
        ar_it_c_valid_idx = (ar_c <= fl_c_min); 
 528 
        % EVAL current utility: N by N, f_util defined earlier
  0.852 
   9825 
 529
        ar_utility_update = f_grid_interpolant_spln(ar_c); 
 530 

 531 
        % Update Storage
  0.004 
   9825 
 532
        if (it_iter == 1) 
  0.001 
     75 
 533
            cl_u_c_store{it_z_i} = reshape(ar_utility_update, [length(ar_w_perc), length(ar_interp_coh_grid)]); 
< 0.001 
     75 
 534
            cl_c_valid_idx{it_z_i} = reshape(ar_it_c_valid_idx, [length(ar_w_perc), length(ar_interp_coh_grid)]); 
  0.002 
   9750 
 535
        else 
  0.424 
   9750 
 536
            cl_u_c_store{it_z_i}(mt_w_kstar_diff_idx) = ar_utility_update; 
  0.358 
   9750 
 537
            cl_c_valid_idx{it_z_i}(mt_w_kstar_diff_idx) = ar_it_c_valid_idx; 
  0.001 
   9825 
 538
        end 
  0.680 
   9825 
 539
        cl_w_kstar_interp_z{it_z_i} = mt_w_kstar_interp_z; 
 540 
        
 541 
        %% D. Compute FULL U(coh_level, w_perc, z) over all w_perc
  0.407 
   9825 
 542
        mt_utility = cl_u_c_store{it_z_i} + fl_beta*mt_ev_condi_z_max_interp_z; 
 543 

 544 
        % Index update
 545 
        % using the method below is much faster than index replace
 546 
        % see <https://fanwangecon.github.io/M4Econ/support/speed/index/fs_subscript.html fs_subscript>
  0.009 
   9825 
 547
        mt_it_c_valid_idx = cl_c_valid_idx{it_z_i}; 
 548 
        % Default or Not Utility Handling
  0.003 
   9825 
 549
        if (bl_default) 
 550 
            % if default: only today u(cmin), transition out next period, debt wiped out
  0.361 
   9825 
 551
            fl_v_default = fl_u_cmin + fl_beta*f_interpolante_w_level_pos_ev_z(fl_default_wprime); 
  0.326 
   9825 
 552
            mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_v_default*(mt_it_c_valid_idx); 
 553 
        else
 554 
            % if default is not allowed: v = u(cmin)
 555 
            mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_nan_replace*(mt_it_c_valid_idx);
  0.002 
   9825 
 556
        end 
 557 
        
 558 
        % percentage algorithm does not have invalid (check to make sure
 559 
        % min percent is not 0 in ffs_ipwkbzr_fibs_get_funcgrid.m)
 560 
        % mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_u_neg_c*(mt_it_c_valid_idx);
 561 

 562 
        %% E. Optimize Over Choices: max_{w_perc} U(coh_level, w_perc, z)
 563 
        % Optimization: remember matlab is column major, rows must be
 564 
        % choices, columns must be states
 565 
        % <https://en.wikipedia.org/wiki/Row-_and_column-major_order COLUMN-MAJOR>
  0.823 
   9825 
 566
        [ar_opti_val_z, ar_opti_idx_z] = max(mt_utility); 
 567 

 568 
        % Generate Linear Opti Index
  0.050 
   9825 
 569
        [it_choies_n, it_states_n] = size(mt_utility); 
  0.189 
   9825 
 570
        ar_add_grid = linspace(0, it_choies_n*(it_states_n-1), it_states_n); 
  0.013 
   9825 
 571
        ar_opti_linear_idx_z = ar_opti_idx_z + ar_add_grid; 
 572 

  0.107 
   9825 
 573
        ar_opti_aprime_z = mt_w_astar_interp_z(ar_opti_linear_idx_z); 
  0.102 
   9825 
 574
        ar_opti_kprime_z = mt_w_kstar_interp_z(ar_opti_linear_idx_z); 
  0.113 
   9825 
 575
        ar_opti_c_z = f_cons(ar_interp_coh_grid, ar_opti_aprime_z, ar_opti_kprime_z); 
 576 

 577 
        % Handle Default is optimal or not
  0.002 
   9825 
 578
        if (bl_default) 
 579 
            % if defaulting is optimal choice, at these states, not required
 580 
            % to default, non-default possible, but default could be optimal
  0.320 
   9825 
 581
            fl_default_opti_kprime = f_interpolante_w_level_pos_kstar_z(fl_default_wprime); 
  0.053 
   9825 
 582
            ar_opti_aprime_z(ar_opti_c_z <= fl_c_min) = fl_default_wprime - fl_default_opti_kprime; 
  0.026 
   9825 
 583
            ar_opti_kprime_z(ar_opti_c_z <= fl_c_min) = fl_default_opti_kprime; 
 584 
        else
 585 
            % if default is not allowed, then next period same state as now
 586 
            % this is absorbing state, this is the limiting case, single
 587 
            % state space point, lowest a and lowest shock has this.
 588 
            ar_opti_aprime_z(ar_opti_c_z <= fl_c_min) = min(ar_a_meshk);
 589 
            ar_opti_kprime_z(ar_opti_c_z <= fl_c_min) = min(ar_k_mesha);
  0.001 
   9825 
 590
        end 
 591 

 592 
        %% F. Store Results
  0.047 
   9825 
 593
        mt_val(:,it_z_i) = ar_opti_val_z; 
  0.035 
   9825 
 594
        mt_pol_a(:,it_z_i) = ar_opti_aprime_z; 
  0.035 
   9825 
 595
        mt_pol_k(:,it_z_i) = ar_opti_kprime_z; 
  0.004 
   9825 
 596
        if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
     75 
 597
            mt_pol_idx(:,it_z_i) = ar_opti_linear_idx_z; 
< 0.001 
     75 
 598
        end 
 599 

  0.004 
   9825 
 600
    end 
 601 

 602 
    %% Check Tolerance and Continuation
 603 

 604 
    % Difference across iterations
  0.380 
    131 
 605
    ar_val_diff_norm(it_iter) = norm(mt_val - mt_val_cur); 
  0.740 
    131 
 606
    ar_pol_diff_norm(it_iter) = norm(mt_pol_a - mt_pol_a_cur) + norm(mt_pol_k - mt_pol_k_cur); 
  0.020 
    131 
 607
    ar_pol_a_perc_change = sum((mt_pol_a ~= mt_pol_a_cur))/(length(ar_interp_coh_grid)); 
  0.016 
    131 
 608
    ar_pol_k_perc_change = sum((mt_pol_k ~= mt_pol_k_cur))/(length(ar_interp_coh_grid)); 
  0.017 
    131 
 609
    mt_pol_perc_change(it_iter, :) = mean([ar_pol_a_perc_change;ar_pol_k_perc_change]); 
 610 

 611 
    % Update
  0.008 
    131 
 612
    mt_val_cur = mt_val; 
  0.006 
    131 
 613
    mt_pol_a_cur = mt_pol_a; 
  0.006 
    131 
 614
    mt_pol_k_cur = mt_pol_k; 
 615 

 616 
    % Print Iteration Results
< 0.001 
    131 
 617
    if (bl_display && (rem(it_iter, it_display_every)==0)) 
 618 
        fprintf('VAL it_iter:%d, fl_diff:%d, fl_diff_pol:%d\n', ...
 619 
            it_iter, ar_val_diff_norm(it_iter), ar_pol_diff_norm(it_iter));
 620 
        tb_valpol_iter = array2table([mean(mt_val_cur,1);...
 621 
                                      mean(mt_pol_a_cur,1); ...
 622 
                                      mean(mt_pol_k_cur,1); ...
 623 
                                      mt_val_cur(length(ar_interp_coh_grid),:); ...
 624 
                                      mt_pol_a_cur(length(ar_interp_coh_grid),:); ...
 625 
                                      mt_pol_k_cur(length(ar_interp_coh_grid),:)]);
 626 
        tb_valpol_iter.Properties.VariableNames = strcat('z', string((1:size(mt_val_cur,2))));
 627 
        tb_valpol_iter.Properties.RowNames = {'mval', 'map', 'mak', 'Hval', 'Hap', 'Hak'};
 628 
        disp('mval = mean(mt_val_cur,1), average value over a')
 629 
        disp('map  = mean(mt_pol_a_cur,1), average choice over a')
 630 
        disp('mkp  = mean(mt_pol_k_cur,1), average choice over k')
 631 
        disp('Hval = mt_val_cur(it_ameshk_n,:), highest a state val')
 632 
        disp('Hap = mt_pol_a_cur(it_ameshk_n,:), highest a state choice')
 633 
        disp('mak = mt_pol_k_cur(it_ameshk_n,:), highest k state choice')
 634 
        disp(tb_valpol_iter);
 635 
    end
 636 

 637 
    % Continuation Conditions:
 638 
    % 1. if value function convergence criteria reached
 639 
    % 2. if policy function variation over iterations is less than
 640 
    % threshold
< 0.001 
    131 
 641
    if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
      1 
 642
        bl_vfi_continue = false; 
  0.002 
    130 
 643
    elseif ((it_iter == it_maxiter_val) || ... 
    130 
 644
            (ar_val_diff_norm(it_iter) < fl_tol_val) || ... 
    130 
 645
            (sum(ar_pol_diff_norm(max(1, it_iter-it_tol_pol_nochange):it_iter)) < fl_tol_pol)) 
 646 
        % Fix to max, run again to save results if needed
< 0.001 
      1 
 647
        it_iter_last = it_iter; 
< 0.001 
      1 
 648
        it_iter = it_maxiter_val; 
< 0.001 
      1 
 649
    end 
 650 

< 0.001 
    131 
 651
end 
 652 

 653 
% End Timer
< 0.001 
      1 
 654
if (bl_time) 
< 0.001 
      1 
 655
    toc; 
< 0.001 
      1 
 656
end 
 657 

 658 
% End Profile
< 0.001 
      1 
 659
if (bl_profile) 
  0.005 
      1 
 660
    profile off 
 661 
    profile viewer
 662 
    st_file_name = [st_profile_prefix st_profile_name_main st_profile_suffix];
 663 
    profsave(profile('info'), strcat(st_profile_path, st_file_name));
 664 
end
 665 

 666 
%% Process Optimal Choices 1: Formal and Informal Choices 
 667 

 668 
result_map = containers.Map('KeyType','char', 'ValueType','any');
 669 
result_map('mt_val') = mt_val;
 670 
result_map('mt_pol_idx') = mt_pol_idx;
 671 

 672 
% Find optimal Formal Informal Choices. Could have saved earlier, but was
 673 
% wasteful of resources
 674 
for it_z_i = 1:it_z_n
 675 
    for it_coh_interp_j = 1:length(ar_interp_coh_grid)
 676 
        
 677 
        fl_coh = mt_interp_coh_grid_mesh_z(it_coh_interp_j, it_z_i);
 678 
        fl_a_opti = mt_pol_a(it_coh_interp_j, it_z_i);
 679 
        
 680 
        fl_z_r_infbr = ar_z_r_infbr_mesh_wage_w1r2(it_z_i);        
 681 
        param_map('fl_r_inf') = fl_z_r_infbr;
 682 
        
 683 
        % call formal and informal function.
 684 
        [fl_max_c, fl_opti_b_bridge, fl_opti_inf_borr_nobridge, fl_opti_for_borr, fl_opti_for_save] = ...
 685 
            ffs_fibs_min_c_cost_bridge(fl_a_opti, fl_coh, ...
 686 
            param_map, support_map, armt_map, func_map, bl_input_override);
 687 
        
 688 
        % store savings and borrowing formal and inf optimal choices
 689 
        mt_pol_b_with_r(it_coh_interp_j,it_z_i) = fl_max_c;
 690 
        mt_pol_b_bridge(it_coh_interp_j,it_z_i) = fl_opti_b_bridge;
 691 
        mt_pol_inf_borr_nobridge(it_coh_interp_j,it_z_i) = fl_opti_inf_borr_nobridge;
 692 
        mt_pol_for_borr(it_coh_interp_j,it_z_i) = fl_opti_for_borr;
 693 
        mt_pol_for_save(it_coh_interp_j,it_z_i) = fl_opti_for_save;
 694 
        
 695 
    end
 696 
end
 697 

 698 
%% Process Optimal Choices 2: Store a, k, c, coh Results
 699 
%
 700 
% # *mt_interp_coh_grid_mesh_z*: Cash-on-hand period _t_.
 701 
% # *mt_pol_a*: Safe asset choice, principles only for ipwkbzr_fibs
 702 
% # *cl_mt_pol_a_principleonly*: mt_pol_a is stored in
 703 
% cl_mt_pol_a_principle only. This is a shortcut because we need to keep
 704 
% cl_mt_pol_a for mt_pol_b_with_r for the _ds_ code.
 705 
% # *cl_mt_pol_a*: stores _mt_pol_b_with_r_ which has principles and
 706 
% interest rates, to be used with _ds_ code. 
 707 
% # *mt_pol_a*: Safe asset choice, principles only for ipwkbzr_fibs
 708 
% # *cl_mt_pol_k*: Risky asset choice, principles only for ipwkbzr_fibs
 709 
% # *cl_mt_pol_c*: Consumption in _t_ given choices.
 710 
% # *cl_pol_b_with_r*: Consumption cost of _mt_pol_a_ in _t+1_, given the
 711 
% formal and informal choices that are optimal to minimize this consumption
 712 
% cost. 
 713 
%
 714 

 715 
result_map('cl_mt_coh') = {mt_interp_coh_grid_mesh_z, zeros(1)};
 716 
result_map('cl_mt_pol_k') = {mt_pol_k, zeros(1)};
 717 
mt_c = f_cons(mt_interp_coh_grid_mesh_z, mt_pol_a, mt_pol_k);
 718 
mt_c(mt_c <= fl_c_min) = fl_c_min;
 719 
result_map('cl_mt_pol_c') = {mt_c, zeros(1)};
 720 

 721 
result_map('cl_mt_pol_a') = {mt_pol_b_with_r, zeros(1)};
 722 
result_map('cl_mt_pol_a_principleonly') = {mt_pol_a, zeros(1)};
 723 

 724 
%% Process Optimal Choices 3: Store Formal and Informal Choices
 725 
result_map('cl_mt_pol_b_bridge') = {mt_pol_b_bridge, zeros(1)};
 726 
result_map('cl_mt_pol_inf_borr_nobridge') = {mt_pol_inf_borr_nobridge, zeros(1)};
 727 
result_map('cl_mt_pol_for_borr') = {mt_pol_for_borr, zeros(1)};
 728 
result_map('cl_mt_pol_for_save') = {mt_pol_for_save, zeros(1)};
 729 

 730 
% Get Discrete Choice Outcomes
 731 
result_map = ffs_fibs_identify_discrete(result_map, bl_input_override);
 732 
result_map('cl_mt_it_for_only_nbdg') = {result_map('mt_it_for_only_nbdg'), zeros(1)};
 733 
result_map('cl_mt_it_inf_only_nbdg') = {result_map('mt_it_inf_only_nbdg'), zeros(1)};
 734 
result_map('cl_mt_it_frin_brr_nbdg') = {result_map('mt_it_frin_brr_nbdg'), zeros(1)};
 735 
result_map('cl_mt_it_fr_brrsv_nbdg') = {result_map('mt_it_fr_brrsv_nbdg'), zeros(1)};
 736 
result_map('cl_mt_it_frmsavng_only') = {result_map('mt_it_frmsavng_only'), zeros(1)};
 737 

 738 
%% Process Optimal Choices 4: List of Variable Names to be processed by distributional codes
 739 
% this list is needed for the ds codes to generate distribution,
 740 
% distributional statistcs will be computed for elements in the list here. 
 741 

 742 
result_map('ar_st_pol_names') = ...
 743 
    ["cl_mt_coh", "cl_mt_pol_a", "cl_mt_pol_k", "cl_mt_pol_c", "cl_mt_pol_a_principleonly", ...
 744 
     "cl_mt_pol_b_bridge", "cl_mt_pol_inf_borr_nobridge", "cl_mt_pol_for_borr", "cl_mt_pol_for_save", ...
 745 
     "cl_mt_it_for_only_nbdg", "cl_mt_it_inf_only_nbdg", "cl_mt_it_frin_brr_nbdg", ...
 746 
     "cl_mt_it_fr_brrsv_nbdg", "cl_mt_it_frmsavng_only"];
 747 

 748 
%% Post Solution Graph and Table Generation
 749 

 750 
if (bl_post)
 751 
    bl_input_override = true;
 752 
    result_map('ar_val_diff_norm') = ar_val_diff_norm(1:it_iter_last);
 753 
    result_map('ar_pol_diff_norm') = ar_pol_diff_norm(1:it_iter_last);
 754 
    result_map('mt_pol_perc_change') = mt_pol_perc_change(1:it_iter_last, :);
 755 
    
 756 
    armt_map('mt_coh_wkb_ori') = mt_coh_wkb;
 757 
    armt_map('ar_a_meshk_ori') = ar_a_meshk;
 758 
    armt_map('ar_k_mesha_ori') = ar_k_mesha;
 759 
    
 760 
    armt_map('mt_coh_wkb') = mt_interp_coh_grid_mesh_z;
 761 
    armt_map('it_ameshk_n') = length(ar_interp_coh_grid);
 762 
    armt_map('ar_a_meshk') = mt_interp_coh_grid_mesh_z(:,1);
 763 
    armt_map('ar_k_mesha') = zeros(size(mt_interp_coh_grid_mesh_z(:,1)) + 0);
 764 
    
 765 
    % Standard AZ graphs
 766 
    result_map = ff_akz_vf_post(param_map, support_map, armt_map, func_map, result_map, bl_input_override);    
 767 
    
 768 
    % Graphs for results_map with FIBS contents
 769 
    armt_map('ar_a') = ar_interp_coh_grid;    
 770 
    result_map = ff_az_fibs_vf_post(param_map, support_map, armt_map, func_map, result_map, bl_input_override);
 771 

 772 
end
 773 

 774 
%% Display Various Containers
 775 

 776 
if (bl_display_defparam)
 777 
    
 778 
    %% Display 1 support_map    
 779 
    fft_container_map_display(support_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 780 
        
 781 
    %% Display 2 armt_map
 782 
    fft_container_map_display(armt_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 783 

 784 
    %% Display 3 param_map
 785 
    fft_container_map_display(param_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 786 
    
 787 
    %% Display 4 func_map
 788 
    fft_container_map_display(func_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 789 
    
 790 
    %% Display 5 result_map
 791 
    fft_container_map_display(result_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 792 
    
 793 
end
 794 

 795 
end

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