This is a static copy of a profile report

Home

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

Home

ff_az_ds (Calls: 1, Time: 5.177 s)
Generated 03-Jul-2019 20:14:13 using performance time.
function in file C:\Users\fan\CodeDynaAsset\m_az\solve\ff_az_ds.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
268
it_a_prime_idx = find(ar_a == ...
11362501.784 s34.5%
284
mt_dist_az(it_a_prime_idx, it_...
170437500.684 s13.2%
278
fl_ztoz_trans =  mt_z_trans(it...
170437500.640 s12.4%
281
fl_zfromza = fl_cur_za_prob*fl...
170437500.629 s12.2%
285
end 
170437500.628 s12.1%
All other lines  0.811 s15.7%
Totals  5.177 s100% 
Children (called functions)
No children
Code Analyzer results
Line numberMessage
140The value assigned here to 'func_map' appears to be unused. Consider replacing it by ~.
320The value assigned to variable 'it_iter_last' might be unused.
Coverage results
Show coverage for parent directory
Total lines in function353
Non-code lines (comments, blank lines)256
Code lines (lines that can run)97
Code lines that did run43
Code lines that did not run54
Coverage (did run/can run)44.33 %
Function listing
time 
Calls 
 line
   7 
function [result_map] = ff_az_ds(varargin)
   8 
%% FF_AZ_DS finds the stationary asset distributions
   9 
% Building on the Asset Dynamic Programming Problem
  10 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html
  11 
% ff_az_vf_vecsv>, here we solve for the asset distribution. This version
  12 
% of the program uses loops.
  13 
%
  14 
% This finds the asset distribution induced by the policy functions. Note
  15 
% that the asset distribution is a joint discrete random variable. We
  16 
% derive f(a,z), where f is the joint discrete random variables probability
  17 
% mass. Then we can derive f(a'(a,z)), f(c(a,z)) directly. The procedure
  18 
% here does not involve simulation. Simulation could also be used to derive
  19 
% these distributions, but given the discrete grid based solution
  20 
% algorithm, there is no need to introduce simulation and associated errors
  21 
% once we have fixed the shock process that generates randomness.
  22 
%
  23 
% The code here works when we are looking for the distribution of f(a,z),
  24 
% where a'(a,z), meaning that the a next period is determined by _a_ last
  25 
% period and some shock. Given this, the _a'_ is fixed for all _z'_. If
  26 
% however, the outcome of interest is such that: y'(y,z,z'), meaning that
  27 
% y' is different depending on realized z', the code below does not work,
  28 
% rather, this code
  29 
% <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_iwkz_ds.html
  30 
% ff_iwkz_ds> should be used.
  31 
%
  32 
% The function here accomplishes two tasks: (1) deriving the asset
  33 
% distribution as a discrete random variable over the states (2)
  34 
% calculating various statistics based on the discrete joint random
  35 
% variable's probability mass function for various outcomes of the model
  36 
%
  37 
% Distributions of Interest:
  38 
%
  39 
% * $p(a,z)$
  40 
% * $p(Y=y, z) = \sum_{a} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  41 
% * $p(Y=y, a) = \sum_{z} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  42 
% * $p(Y=y) = \sum_{a,z} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  43 
%
  44 
% Statistics include:
  45 
%
  46 
% * $\mu_y = \sum_{y} p(Y=y) \cdot y$
  47 
% * $\sigma_y = \sqrt{ \sum_{y} p(Y=y) \cdot \left( y - \mu_y \right)^2}$
  48 
% * $p(y=0)$
  49 
% * $p(y=\max(y))$
  50 
% * percentiles: $min_{y} \left\{ P(Y \le y) - percentile \mid P(Y \le y) \ge percentile \right\}$
  51 
% * fraction of outcome held by up to percentiles: $E(Y<y)/E(Y)$
  52 
%
  53 
% @param param_map container parameter container
  54 
%
  55 
% @param support_map container support container
  56 
%
  57 
% @param armt_map container container with states, choices and shocks
  58 
% grids that are inputs for grid based solution algorithm
  59 
%
  60 
% @param func_map container container with function handles for
  61 
% consumption cash-on-hand etc.
  62 
%
  63 
% @return result_map container contains policy function matrix, value
  64 
% function matrix, iteration results, and policy function, value function
  65 
% and iteration results tables.
  66 
%
  67 
% new keys included in result_map in addition to the output from
  68 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html
  69 
% ff_az_vf_vecsv> are various distribution statistics for each model
  70 
% outcome, keys include *cl_mt_pol_a*, *cl_mt_pol_c*, *cl_mt_pol_coh*, etc,
  71 
% these include:
  72 
%
  73 
% * the first element of each of these cell array is y(a,z), the
  74 
% outcome/choice at the state space points
  75 
% * the second element of the cell is another container, which contains
  76 
% statistics computed for f(y) based on y(a,z) and f(a,z), f(y) is the
  77 
% probability mass function for outcome y given the stationary distribution
  78 
% f(a,z). The second element container also includes f(y) itself as well as
  79 
% f(y,z).
  80 
% * additionally, result_map also stores some of the statistics for
  81 
% different variables jointly together. (a) *tb_outcomes_meansdperc*: where
  82 
% each row is a different outcome of the model, and each table column
  83 
% stores a different statistics of interest. (b) *tb_outcomes_fracheld*:
  84 
% which measures the fraction of asset held by different people.
  85 
%
  86 
% @example
  87 
%
  88 
%    % Get Default Parameters
  89 
%    it_param_set = 6;
  90 
%    [param_map, support_map] = ffs_az_set_default_param(it_param_set);
  91 
%    % Change Keys in param_map
  92 
%    param_map('it_a_n') = 500;
  93 
%    param_map('it_z_n') = 11;
  94 
%    param_map('fl_a_max') = 100;
  95 
%    param_map('fl_w') = 1.3;
  96 
%    % Change Keys support_map
  97 
%    support_map('bl_display') = false;
  98 
%    support_map('bl_post') = true;
  99 
%    support_map('bl_display_final') = false;
 100 
%    % Call Program with external parameters that override defaults
 101 
%    ff_az_ds(param_map, support_map);
 102 
%
 103 
% @include
 104 
%
 105 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html ff_az_vf_vecsv>
 106 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/solvepost/html/ff_az_ds_post_stats.html ff_az_ds_post_stats>
 107 
% * <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_stats.html fft_disc_rand_var_stats>
 108 
% * <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_mass2outcomes.html fft_disc_rand_var_mass2outcomes>
 109 
%
 110 
% @seealso
 111 
%
 112 
% * derive distribution f(y'(y,z)) one asset *loop*: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_ds.html ff_az_ds>
 113 
% * derive distribution f(y'({x,y},z)) two assets *loop*: <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_akz_ds.html ff_akz_ds>
 114 
% * derive distribution f(y'({x,y},z, *z'*)) two assets *loop*: <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_iwkz_ds.html ff_iwkz_ds>
 115 
% * derive distribution f(y'({y},z)) or f(y'({x,y},z)) *vectorized*: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_ds_vec.html ff_az_ds_vec>
 116 
% * derive distribution f(y'({y},z, *z'*)) or f(y'({x,y},z, *z'*)) *vectorized*: <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_iwkz_ds_vec.html ff_iwkz_ds_vec>
 117 
% * derive distribution f(y'({y},z)) or f(y'({x,y},z)) *semi-analytical*: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_ds_vecsv.html ff_az_ds_vecsv>
 118 
% * derive distribution f(y'({y},z, *z'*)) or f(y'({x,y},z, *z'*)) *semi-analytical*: <https://fanwangecon.github.io/CodeDynaAsset/m_akz/solve/html/ff_iwkz_ds_vecsv.html ff_iwkz_ds_vecsv>
 119 
%
 120 

 121 
%% Default
 122 
% Program can be externally invoked with _az_, _abz_ or various other
 123 
% programs. By default, program invokes using _az_ model programs:
 124 
%
 125 
% # it_subset = 5 is basic invoke quick test
 126 
% # it_subset = 6 is invoke full test
 127 
% # it_subset = 7 is profiling invoke
 128 
% # it_subset = 8 is matlab publish
 129 
% # it_subset = 9 is invoke operational (only final stats) and coh graph
 130 
%
 131 

 132 
params_len = length(varargin);
 133 
bl_input_override = 0;
 134 
if (params_len == 6)
 135 
    bl_input_override = varargin{6};
 136 
end
 137 

 138 
if (bl_input_override)
 139 
    % if invoked from outside override fully
 140 
    [param_map, support_map, armt_map, func_map, result_map, ~] = varargin{:};
 141 

 142 
else
 143 
    % default invoke
 144 
    close all;
 145 
    
 146 
    it_param_set = 7;
 147 
    bl_input_override = true;
 148 

 149 
    % 1. Generate Parameters
 150 
    [param_map, support_map] = ffs_az_set_default_param(it_param_set);
 151 

 152 
    % Note: param_map and support_map can be adjusted here or outside to override defaults
 153 
    % param_map('it_a_n') = 750;
 154 
    % param_map('it_z_n') = 15;
 155 

 156 
    % 2. Generate function and grids
 157 
    [armt_map, func_map] = ffs_az_get_funcgrid(param_map, support_map, bl_input_override); % 1 for override
 158 
    
 159 
    % 3. Solve value and policy function using az_vf_vecsv, if want to solve
 160 
    % other models, solve outside then provide result_map as input
 161 
    [result_map] = ff_az_vf_vecsv(param_map, support_map, armt_map, func_map);    
 162 
    
 163 
end
 164 

 165 
%% Parse Parameters
 166 

 167 
% append function name
 168 
st_func_name = 'ff_az_ds';
 169 
support_map('st_profile_name_main') = [st_func_name support_map('st_profile_name_main')];
 170 
support_map('st_mat_name_main') = [st_func_name support_map('st_mat_name_main')];
 171 
support_map('st_img_name_main') = [st_func_name support_map('st_img_name_main')];
 172 

 173 
% result_map
 174 
% ar_st_pol_names is from section _Process Optimal Choices_ in the value
 175 
% function code.
 176 
params_group = values(result_map, {'cl_mt_pol_a'});
 177 
[cl_mt_pol_a] = params_group{:};
 178 
mt_pol_a = deal(cl_mt_pol_a{1});
 179 

 180 
% armt_map
 181 
params_group = values(armt_map, {'ar_a', 'mt_z_trans', 'ar_z'});
 182 
[ar_a, mt_z_trans, ar_z] = params_group{:};
 183 

 184 
% param_map
 185 
params_group = values(param_map, {'it_a_n', 'it_z_n'});
 186 
[it_a_n, it_z_n] = params_group{:};
 187 
params_group = values(param_map, {'it_maxiter_dist', 'fl_tol_dist'});
 188 
[it_maxiter_dist, fl_tol_dist] = params_group{:};
 189 

 190 
% support_map
 191 
params_group = values(support_map, {'bl_profile_dist', 'st_profile_path', ...
 192 
    'st_profile_prefix', 'st_profile_name_main', 'st_profile_suffix',...
 193 
    'bl_time', 'bl_display_dist', 'it_display_every'});
 194 
[bl_profile_dist, st_profile_path, ...
 195 
    st_profile_prefix, st_profile_name_main, st_profile_suffix, ...
 196 
    bl_time, bl_display_dist, it_display_every] = params_group{:};
 197 

 198 
%% Start Profiler and Timer
 199 

 200 
% Start Profile
 201 
if (bl_profile_dist)
 202 
    close all;
 203 
    profile off;
 204 
    profile on;
< 0.001 
      1 
 205
end 
 206 

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

 212 
%% *f(a,z)*: Initialize Output Matrixes
 213 
% Initialize the distribution to be uniform
 214 

< 0.001 
      1 
 215
mt_dist_az_init = ones(length(ar_a),length(ar_z))/length(ar_a)/length(ar_z); 
< 0.001 
      1 
 216
mt_dist_az_cur = mt_dist_az_init; 
< 0.001 
      1 
 217
mt_dist_az_zeros = zeros(length(ar_a),length(ar_z)); 
 218 

 219 
%% *f(a,z)*: Initialize Convergence Conditions
 220 

< 0.001 
      1 
 221
bl_histiter_continue = true; 
< 0.001 
      1 
 222
it_iter = 0; 
< 0.001 
      1 
 223
ar_dist_diff_norm = zeros([it_maxiter_dist, 1]); 
< 0.001 
      1 
 224
mt_dist_perc_change = zeros([it_maxiter_dist, it_z_n]); 
 225 

 226 
%% *f(a,z)*: Derive Stationary Distribution
 227 
% Iterate over the discrete joint random variable variables (a,z)
 228 
%
 229 
% We are looking for the distribution of: $p(a,z)$ where $a'(a,z)$, meaning
 230 
% that the a next period is determined by a last period and some shock.
 231 
% Given this, the $a'$ is fixed for all $z'$
 232 
%
 233 
% To make the code work for life-cycle model:
 234 
% # _mt_dist_az_init_: Initialize with potentially exogenous initial asset
 235 
% distribution
 236 
% # _mt_dist_az_: change mt_dist_az to tensor with a third dimension for
 237 
% age
 238 
% # at the beginning of the third loop over ar_z, get mass at current age,
 239 
% meaning: fl_cur_za_prob = ts_dist_az(it_a_prime_idx, it_zp_q, age)
 240 
% # at the end of the third loop over ar_z, add accumulated mass to next
 241 
% period, meaning: ts_dist_az(it_a_prime_idx, it_zp_q, age+1) =+ fl_zfromza
 242 
%
 243 

< 0.001 
      1 
 244
while (bl_histiter_continue) 
 245 
    
< 0.001 
    101 
 246
    it_iter = it_iter + 1; 
 247 
    
 248 
    %% *f(a,z)*: Iterate over Probability mass for Discrete Random Variable
 249 
    % compared to
 250 
    % <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf.html
 251 
    % ff_az_vf>, we basically have the same set of loops. There, there were
 252 
    % four loops, here there are three loops. We eliminated the loop over
 253 
    % next period choices, because here we already know optimal choices
 254 
    
 255 
    % initialize empty
< 0.001 
    101 
 256
    mt_dist_az = mt_dist_az_zeros; 
 257 
    
 258 
    % loop 1: over exogenous states
< 0.001 
    101 
 259
    for it_z_i = 1:length(ar_z) 
 260 
        
 261 
        % loop 2: over endogenous states
< 0.001 
   1515 
 262
        for it_a_j = 1:length(ar_a) 
 263 
            
 264 
            % f(a'|a) = 1 for only one a'
 265 
            % in dynamic programming problem, had a loop over choices, now
 266 
            % already have optimal choices, do not need to loop
  0.044 
1136250 
 267
            fl_aprime = mt_pol_a(it_a_j, it_z_i);            
  1.784 
1136250 
 268
            it_a_prime_idx = find(ar_a == fl_aprime); 
 269 
            
 270 
            % loop 3: loop over future shocks
 271 
            % E_{a,z}(f(a',z'|a,z)*f(a,z))
  0.053 
1136250 
 272
            for it_zp_q = 1:length(ar_z) 
 273 
                
 274 
                % current probablity at (a,z)
  0.613 
17043750 
 275
                fl_cur_za_prob = mt_dist_az_cur(it_a_j, it_z_i); 
 276 
                
 277 
                % f(z'|z) transition
  0.640 
17043750 
 278
                fl_ztoz_trans =  mt_z_trans(it_z_i, it_zp_q); 
 279 
                
 280 
                % f(a',z'|a,z)*f(a,z) 
  0.629 
17043750 
 281
                fl_zfromza = fl_cur_za_prob*fl_ztoz_trans; 
 282 
                
 283 
                % cumulating
  0.684 
17043750 
 284
                mt_dist_az(it_a_prime_idx, it_zp_q) = mt_dist_az(it_a_prime_idx, it_zp_q) + fl_zfromza; 
  0.628 
17043750 
 285
            end  
 286 
            
  0.041 
1136250 
 287
        end 
 288 
        
< 0.001 
   1515 
 289
    end 
 290 
   
 291 
    
 292 
    %% *f(a,z)*: Check Tolerance and Continuation
 293 
    
 294 
    % Difference across iterations
  0.041 
    101 
 295
    ar_dist_diff_norm(it_iter) = norm(mt_dist_az - mt_dist_az_cur); 
  0.008 
    101 
 296
    mt_dist_perc_change(it_iter, :) = sum((mt_dist_az ~= mt_dist_az))/(it_a_n); 
 297 
    
 298 
    % Update
  0.003 
    101 
 299
    mt_dist_az_cur = mt_dist_az;     
 300 
    
 301 
    % Print Iteration Results
< 0.001 
    101 
 302
    if (bl_display_dist && (rem(it_iter, it_display_every)==0)) 
 303 
        fprintf('Dist it_iter:%d, fl_dist_diff:%d\n', it_iter, ar_dist_diff_norm(it_iter));
 304 
        tb_hist_iter = array2table([sum(mt_dist_az_cur,1); std(mt_dist_az_cur,1); ...
 305 
                                    mt_dist_az_cur(1,:); mt_dist_az_cur(it_a_n,:)]);
 306 
        tb_hist_iter.Properties.VariableNames = strcat('z', string((1:size(mt_dist_az,2))));
 307 
        tb_hist_iter.Properties.RowNames = {'mdist','sddist', 'Ldist', 'Hdist'};
 308 
        disp('mdist = sum(mt_dist_az_cur,1) = sum_{a}(p(a)|z)')
 309 
        disp('sddist = std(mt_pol_a_cur,1) = std_{a}(p(a)|z)')
 310 
        disp('Ldist = mt_dist_az_cur(1,:) = p(min(a)|z)')
 311 
        disp('Hdist = mt_dist_az_cur(it_a_n,:) = p(max(a)|z)')
 312 
        disp(tb_hist_iter);
 313 
    end
 314 

 315 
    % Continuation Conditions:
< 0.001 
    101 
 316
    if (it_iter == (it_maxiter_dist + 1)) 
< 0.001 
      1 
 317
        bl_histiter_continue = false; 
< 0.001 
    100 
 318
    elseif ((it_iter == it_maxiter_dist) || ... 
    100 
 319
            (ar_dist_diff_norm(it_iter) < fl_tol_dist)) 
< 0.001 
      1 
 320
        it_iter_last = it_iter; 
< 0.001 
      1 
 321
        it_iter = it_maxiter_dist; 
< 0.001 
      1 
 322
    end 
 323 
    
< 0.001 
    101 
 324
end 
 325 

 326 
%% End Time and Profiler
 327 

 328 
% End Timer
< 0.001 
      1 
 329
if (bl_time) 
< 0.001 
      1 
 330
    toc; 
< 0.001 
      1 
 331
end 
 332 

 333 
% End Profile
< 0.001 
      1 
 334
if (bl_profile_dist) 
  0.004 
      1 
 335
    profile off 
 336 
    profile viewer
 337 
    st_file_name = [st_profile_prefix st_profile_name_main st_profile_suffix];
 338 
    profsave(profile('info'), strcat(st_profile_path, st_file_name));
 339 
end
 340 

 341 

 342 
%% *f(y), f(c), f(a)*: Generate Key Distributional Statistics for Each outcome
 343 
% Having derived f(a,z) the probability mass function of the joint discrete
 344 
% random variables, we now obtain distributional statistics. Note that we
 345 
% know f(a,z), and we also know relevant policy functions a'(a,z), c(a,z),
 346 
% or other policy functions. We can simulate any choices that are a
 347 
% function of the random variables (a,z), using f(a,z). We call function
 348 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solvepost/html/ff_az_ds_post_stats.html
 349 
% ff_az_ds_post_stats> which uses
 350 
% <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_stats.html
 351 
% fft_disc_rand_var_stats> and
 352 
% <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_mass2outcomes.html
 353 
% fft_disc_rand_var_mass2outcomes> to compute various statistics of
 354 
% interest.
 355 

 356 
bl_input_override = true;
 357 
result_map = ff_az_ds_post_stats(support_map, result_map, mt_dist_az, bl_input_override);
 358 

 359 
end

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