This is a static copy of a profile report

Home

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

Home

ff_az_ds_vecsv (Calls: 1, Time: 0.870 s)
Generated 03-Jul-2019 20:31:52 using performance time.
function in file C:\Users\fan\CodeDynaAsset\m_az\solve\ff_az_ds_vecsv.m
Copy to new window for comparing multiple runs

Parents (calling functions)

Function NameFunction TypeCalls
ff_akz_ds_vecsvscript1
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
341
[V, ~] = eigs(mt_full_trans_ma...
10.493 s56.6%
439
result_map = ff_az_ds_post_sta...
10.344 s39.5%
292
mt_full_trans_mat = sparse(i, ...
10.028 s3.2%
441
end
10.001 s0.2%
251
mt_pol_idx_mesh_max = mt_pol_i...
10.001 s0.1%
All other lines  0.004 s0.4%
Totals  0.870 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
eigsfunction10.424 s48.8%
ff_az_ds_post_statsfunction10.336 s38.6%
dealfunction10.001 s0.1%
Self time (built-ins, overhead, etc.)  0.109 s12.6%
Totals  0.870 s100% 
Code Analyzer results
Line numberMessage
136The value assigned here to 'func_map' appears to be unused. Consider replacing it by ~.
177The value assigned here to 'ar_st_pol_names' appears to be unused. Consider replacing it by ~.
178The value assigned to variable 'mt_pol_a' might be unused.
195The value assigned here to 'bl_display_final_dist' appears to be unused. Consider replacing it by ~.
195The value assigned here to 'bl_post' appears to be unused. Consider replacing it by ~.
Coverage results
Show coverage for parent directory
Total lines in function435
Non-code lines (comments, blank lines)343
Code lines (lines that can run)92
Code lines that did run53
Code lines that did not run39
Coverage (did run/can run)57.61 %
Function listing
time 
Calls 
 line
   7 
function [result_map] = ff_az_ds_vecsv(varargin)
   8 
%% FF_AZ_DS_VECSV finds the stationary asset distributions analytically
   9 
% Here, we implement the iteration free semi-analytical method for finding
  10 
% asset distributions. The method analytically give the exact
  11 
% stationary distribution induced by the policy function from the dynamic
  12 
% programming problem, conditional on discretizations.
  13 
%
  14 
% See the appedix of
  15 
% <https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3316939 Wang (2019)>
  16 
% which develops details on how this works. Suppose endo state size is N and
  17 
% shock is size M, then our transition matrix is (NxM) by (NxM). We know
  18 
% the coh(a,z) value associated with each element of the (NxM) by 1 array.
  19 
% We also know f(a'(a,z),z'|z) transition probability. We contruct a markov
  20 
% chain that has (NxM) states. Specifically:
  21 
%
  22 
% * We need to transform: mt_pol_idx. This matrix is indexing 1 through N,
  23 
% we need for it to index 1 through (NxM).
  24 
% * Then we need to duplicate the transition matrix fro shocks.
  25 
% * Transition Matrix is *sparse*
  26 
%
  27 
% Once we have the all states meshed markov transition matrix, then we can
  28 
% use standard methods to find the stationary distribution. Three options
  29 
% are offered here that provide identical solutions:
  30 
%
  31 
% # The Eigenvector Approach: very fast
  32 
% # The Projection Approach: medium
  33 
% # The Power Approach: very slow (especially with sparse matrix)
  34 
%
  35 
% The program here builds on the Asset Dynamic Programming Problem
  36 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html
  37 
% ff_az_vf_vecsv>, here we solve for the asset distribution using
  38 
% vectorized codes.
  39 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_ds.html
  40 
% ff_az_ds> shows looped codes for finding asset distribution. The solution
  41 
% is the same. Both *ff_az_ds* and *ff_az_ds_vec* using
  42 
% optimized-vectorized dynamic programming code from ff_az_vf_vecsv. The
  43 
% idea here is that in addition to vectornizing the dynamic programming
  44 
% funcion, we can also vectorize the distribution code here.
  45 
%
  46 
% Distributions of Interest:
  47 
%
  48 
% * $p(a,z)$
  49 
% * $p(Y=y, z) = \sum_{a} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  50 
% * $p(Y=y, a) = \sum_{z} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  51 
% * $p(Y=y) = \sum_{a,z} \left( 1\left\{Y(a,z)=y\right\} \cdot p(a,z) \right)$
  52 
%
  53 
% Statistics include:
  54 
%
  55 
% * $\mu_y = \sum_{y} p(Y=y) \cdot y$
  56 
% * $\sigma_y = \sqrt{ \sum_{y} p(Y=y) \cdot \left( y - \mu_y \right)^2}$
  57 
% * $p(y=0)$
  58 
% * $p(y=\max(y))$
  59 
% * percentiles: $min_{y} \left\{ P(Y \le y) - percentile \mid P(Y \le y) \ge percentile \right\}$
  60 
% * fraction of outcome held by up to percentiles: $E(Y<y)/E(Y)$
  61 
%
  62 
% @param param_map container parameter container
  63 
%
  64 
% @param support_map container support container
  65 
%
  66 
% @param armt_map container container with states, choices and shocks
  67 
% grids that are inputs for grid based solution algorithm
  68 
%
  69 
% @param func_map container container with function handles for
  70 
% consumption cash-on-hand etc.
  71 
%
  72 
% @return result_map container contains policy function matrix, value
  73 
% function matrix, iteration results, and policy function, value function
  74 
% and iteration results tables.
  75 
%
  76 
% new keys included in result_map in addition to the output from
  77 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html
  78 
% ff_az_vf_vecsv> are various distribution statistics for each model
  79 
% outcome, keys include *cl_mt_pol_a*, *cl_mt_pol_c*, *cl_mt_pol_coh*, etc.
  80 
%
  81 
% @example
  82 
%
  83 
%    % Get Default Parameters
  84 
%    it_param_set = 6;
  85 
%    [param_map, support_map] = ffs_az_set_default_param(it_param_set);
  86 
%    % Change Keys in param_map
  87 
%    param_map('it_a_n') = 500;
  88 
%    param_map('it_z_n') = 11;
  89 
%    param_map('fl_a_max') = 100;
  90 
%    param_map('fl_w') = 1.3;
  91 
%    % Change Keys support_map
  92 
%    support_map('bl_display') = false;
  93 
%    support_map('bl_post') = true;
  94 
%    support_map('bl_display_final') = false;
  95 
%    % Call Program with external parameters that override defaults
  96 
%    ff_az_ds_vecsv(param_map, support_map);
  97 
%
  98 
%
  99 
% @include
 100 
%
 101 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html ff_az_vf_vecsv>
 102 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/solvepost/html/ff_az_ds_post_stats.html ff_az_ds_post_stats>
 103 
% * <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_stats.html fft_disc_rand_var_stats>
 104 
% * <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_mass2outcomes.html fft_disc_rand_var_mass2outcomes>
 105 
%
 106 
% @seealso
 107 
%
 108 
% * 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>
 109 
% * 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>
 110 
% * 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>
 111 
% * 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>
 112 
% * 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>
 113 
% * 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>
 114 
% * 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>
 115 
%
 116 

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

< 0.001 
      1 
 128
params_len = length(varargin); 
< 0.001 
      1 
 129
bl_input_override = 0; 
< 0.001 
      1 
 130
if (params_len == 6) 
< 0.001 
      1 
 131
    bl_input_override = varargin{6}; 
< 0.001 
      1 
 132
end 
 133 

< 0.001 
      1 
 134
if (bl_input_override) 
 135 
    % if invoked from outside override fully
< 0.001 
      1 
 136
    [param_map, support_map, armt_map, func_map, result_map, ~] = varargin{:}; 
 137 

 138 
else
 139 
    % default invoke
 140 
    close all;
 141 

 142 
    it_param_set = 8;
 143 
    bl_input_override = true;
 144 

 145 
    % 1. Generate Parameters
 146 
    [param_map, support_map] = ffs_az_set_default_param(it_param_set);
 147 

 148 
    % Note: param_map and support_map can be adjusted here or outside to override defaults
 149 
    % param_map('it_a_n') = 750;
 150 
    % param_map('it_z_n') = 15;
 151 

 152 
    param_map('st_analytical_stationary_type') = 'eigenvector';
 153 
%     param_map('st_analytical_stationary_type') = 'projection';
 154 
%     param_map('st_analytical_stationary_type') = 'power';
 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 

< 0.001 
      1 
 163
end 
 164 

 165 
%% Parse Parameters
 166 

 167 
% append function name
< 0.001 
      1 
 168
st_func_name = 'ff_az_ds_vecsv'; 
< 0.001 
      1 
 169
support_map('st_profile_name_main') = [st_func_name support_map('st_profile_name_main')]; 
< 0.001 
      1 
 170
support_map('st_mat_name_main') = [st_func_name support_map('st_mat_name_main')]; 
< 0.001 
      1 
 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.
< 0.001 
      1 
 176
params_group = values(result_map, {'cl_mt_pol_a', 'mt_pol_idx', 'ar_st_pol_names'}); 
< 0.001 
      1 
 177
[cl_mt_pol_a, mt_pol_idx, ar_st_pol_names] = params_group{:}; 
< 0.001 
      1 
 178
mt_pol_a = deal(cl_mt_pol_a{1}); 
 179 

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

 184 
% param_map
< 0.001 
      1 
 185
params_group = values(param_map, { 'it_trans_power_dist', 'st_analytical_stationary_type'}); 
< 0.001 
      1 
 186
[it_trans_power_dist, st_analytical_stationary_type] = params_group{:}; 
 187 

 188 

 189 
% support_map
< 0.001 
      1 
 190
params_group = values(support_map, {'bl_profile_dist', 'st_profile_path', ... 
 191 
    'st_profile_prefix', 'st_profile_name_main', 'st_profile_suffix',...
 192 
    'bl_time', 'bl_display_final_dist', 'bl_post'});
< 0.001 
      1 
 193
[bl_profile_dist, st_profile_path, ... 
      1 
 194
    st_profile_prefix, st_profile_name_main, st_profile_suffix, ... 
      1 
 195
    bl_time, bl_display_final_dist, bl_post] = params_group{:}; 
 196 

 197 
%% Start Profiler and Timer
 198 

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

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

 211 
%% Get Size of Endogenous and Exogenous State
 212 
% The key idea is that all information for policy function is captured by
 213 
% _mt_pol_idx_ matrix, its rows are the number of endogenous states, and
 214 
% its columns are the exogenous shocks.
 215 

< 0.001 
      1 
 216
[it_endostates_rows_n, it_exostates_cols_n] = size(mt_pol_idx); 
 217 

 218 
%% 1. Generate Max Index in (NxM) from (N) array.
 219 
% Suppose we have: 
 220 
%
 221 
%   mt_pol_idx =
 222 
% 
 223 
%      1     1     2
 224 
%      2     2     2
 225 
%      3     3     3
 226 
%      4     4     4
 227 
%      4     5     5
 228 
%
 229 
% These become:
 230 
%
 231 
%   mt_pol_idx_mesh_max = 
 232 
% 
 233 
%      1     6    11
 234 
%      2     7    12
 235 
%      3     8    13
 236 
%      4     9    14
 237 
%      5    10    15
 238 
%      1     6    11
 239 
%      2     7    12
 240 
%      3     8    13
 241 
%      4     9    14
 242 
%      5    10    15
 243 
%      1     6    11
 244 
%      2     7    12
 245 
%      3     8    13
 246 
%      4     9    14
 247 
%      5    10    15
 248 
%
 249 

 250 
% mt_pol_idx_mesh_max is (NxM) by M, mt_pol_idx is N by M
< 0.001 
      1 
 251
mt_pol_idx_mesh_max = mt_pol_idx(:) + (0:1:(it_exostates_cols_n-1))*it_endostates_rows_n; 
 252 

 253 
%% 2. Transition Probabilities from (M by M) to (NxM) by M
 254 
%
 255 
%   mt_trans_prob =
 256 
% 
 257 
%     0.9332    0.0668    0.0000
 258 
%     0.9332    0.0668    0.0000
 259 
%     0.9332    0.0668    0.0000
 260 
%     0.9332    0.0668    0.0000
 261 
%     0.9332    0.0668    0.0000
 262 
%     0.0062    0.9876    0.0062
 263 
%     0.0062    0.9876    0.0062
 264 
%     0.0062    0.9876    0.0062
 265 
%     0.0062    0.9876    0.0062
 266 
%     0.0062    0.9876    0.0062
 267 
%     0.0000    0.0668    0.9332
 268 
%     0.0000    0.0668    0.9332
 269 
%     0.0000    0.0668    0.9332
 270 
%     0.0000    0.0668    0.9332
 271 
%     0.0000    0.0668    0.9332
 272 
%
 273 

< 0.001 
      1 
 274
mt_trans_prob = reshape(repmat(mt_z_trans(:)', [it_endostates_rows_n, 1]), [it_endostates_rows_n*it_exostates_cols_n, it_exostates_cols_n]); 
 275 

 276 
%% 3. Fill mt_pol_idx_mesh_idx to mt_full_trans_mat
 277 
% Try to always use sparse matrix, unless grid sizes very small, keeping
 278 
% non-sparse code here for comparison. Sparse matrix is important for
 279 
% allowing the code to be fast and memory efficient. Otherwise this method
 280 
% is much slower than iterative method.
 281 

< 0.001 
      1 
 282
it_sparse_threshold = 100*7; 
 283 

< 0.001 
      1 
 284
if (it_endostates_rows_n*it_exostates_cols_n > it_sparse_threshold) 
 285 
    
 286 
    %% 3.1 Sparse Matrix Approach
< 0.001 
      1 
 287
    i = mt_pol_idx_mesh_max(:); 
< 0.001 
      1 
 288
    j = repmat((1:1:it_endostates_rows_n*it_exostates_cols_n),[1,it_exostates_cols_n])'; 
< 0.001 
      1 
 289
    v = mt_trans_prob(:); 
< 0.001 
      1 
 290
    m = it_endostates_rows_n*it_exostates_cols_n; 
< 0.001 
      1 
 291
    n = it_endostates_rows_n*it_exostates_cols_n; 
  0.028 
      1 
 292
    mt_full_trans_mat = sparse(i, j, v, m, n); 
 293 
    
 294 
else
 295 
    
 296 
    %% 3.2 Full Matrix Approach
 297 
    %
 298 
    %   ar_lin_idx_start_point =
 299 
    % 
 300 
    %      0    15    30    45    60    75    90   105   120   135   150   165   180   195   210
 301 
    %
 302 
    %   mt_pol_idx_mesh_idx_meshfull =
 303 
    % 
 304 
    %      1     6    11
 305 
    %     17    22    27
 306 
    %     33    38    43
 307 
    %     49    54    59
 308 
    %     65    70    75
 309 
    %     76    81    86
 310 
    %     92    97   102
 311 
    %    108   113   118
 312 
    %    124   129   134
 313 
    %    140   145   150
 314 
    %    151   156   161
 315 
    %    167   172   177
 316 
    %    183   188   193
 317 
    %    199   204   209
 318 
    %    215   220   225
 319 
    %
 320 

 321 
    % Each row's linear index starting point
 322 
    ar_lin_idx_start_point = ((it_endostates_rows_n*it_exostates_cols_n)*(0:1:(it_endostates_rows_n*it_exostates_cols_n-1)));
 323 

 324 
    % mt_pol_idx_mesh_idx_meshfull is (NxM) by M
 325 
    % Full index in (NxM) to (NxM) transition Matrix
 326 
    mt_pol_idx_mesh_idx_meshfull = mt_pol_idx_mesh_max + ar_lin_idx_start_point';
 327 

 328 
    % Fill mt_pol_idx_mesh_idx to mt_full_trans_mat
 329 
    mt_full_trans_mat = zeros([it_endostates_rows_n*it_exostates_cols_n, it_endostates_rows_n*it_exostates_cols_n]);    
 330 
    mt_full_trans_mat(mt_pol_idx_mesh_idx_meshfull(:)) = mt_trans_prob(:);
 331 
    
< 0.001 
      1 
 332
end 
 333 

 334 
%% 4. Stationary Distribution *Method A*, Eigenvector Approach
 335 
% Given that markov chain we have constructured for all state-space
 336 
% elements, we can now find the stationary distribution using standard
 337 
% <https://en.wikipedia.org/wiki/Markov_chain#Stationary_distribution_relation_to_eigenvectors_and_simplices
 338 
% eigenvector> approach.
 339 

< 0.001 
      1 
 340
if (strcmp(st_analytical_stationary_type, 'eigenvector')) 
  0.493 
      1 
 341
    [V, ~] = eigs(mt_full_trans_mat,1,1); 
< 0.001 
      1 
 342
    ar_stationary = V/sum(V); 
< 0.001 
      1 
 343
end 
 344 

 345 
%% 5. Stationary Distribution *Method B*, Projection
 346 
% This uses Projection. 
 347 

< 0.001 
      1 
 348
if (strcmp(st_analytical_stationary_type, 'projection')) 
 349 
    
 350 
    % a. Transition - I
 351 
    % P = P*T
 352 
    % 0 = P*T - P
 353 
    % 0 = P*(T-1)                
 354 
    % Q = trans_prob - np.identity(state_count);
 355 

 356 
    mt_diag = eye(it_endostates_rows_n*it_exostates_cols_n);
 357 
    if (it_endostates_rows_n*it_exostates_cols_n > it_sparse_threshold)
 358 
        % if larger, use sparse matrix
 359 
        mt_diag = sparse(mt_diag);
 360 
    end
 361 
    mt_Q = mt_full_trans_mat' - mt_diag;
 362 

 363 
    % b. add all 1 as final column, (because P*1 = 1) 
 364 
    % one_col = np.ones((state_count,1))
 365 
    % Q = np.column_stack((Q, one_col))
 366 

 367 
    ar_one = ones([it_endostates_rows_n*it_exostates_cols_n,1]);
 368 
    mt_Q = [mt_Q, ar_one];
 369 

 370 
    % c. b is the LHS 
 371 
    % b = [0,0,0,...,1]
 372 
    % b = np.zeros((1, (state_count+1)))
 373 
    % b[0, state_count] = 1
 374 

 375 
    ar_b = zeros([1, it_endostates_rows_n*it_exostates_cols_n+1]);
 376 
    if (it_endostates_rows_n*it_exostates_cols_n > it_sparse_threshold)
 377 
        % if larger, use sparse matrix
 378 
        ar_b = sparse(ar_b);
 379 
    end    
 380 
    ar_b(it_endostates_rows_n*it_exostates_cols_n+1) = 1;
 381 

 382 
    % d. solve
 383 
    % b = P*Q
 384 
    % b*Q^{T} = P*Q*Q^{T}
 385 
    % P*Q*Q^{T} = b*Q^{T}
 386 
    % P = (b*Q^{T})[(Q*Q^{T})^{-1}]
 387 
    % Q_t = np.transpose(Q)
 388 
    % b_QT = np.dot(b, Q_t)
 389 
    % Q_QT = np.dot(Q, Q_t)
 390 

 391 
    % inv_mt_Q_QT = inv(mt_Q*mt_Q');
 392 
    ar_stationary = (ar_b*mt_Q')/(mt_Q*mt_Q');
 393 

 394 
end
 395 

 396 
%% 6. Stationary Distribution *Method C*, Power
 397 
% Takes markov chain to Nth power. This is the slowest.
 398 

< 0.001 
      1 
 399
if (strcmp(st_analytical_stationary_type, 'power')) 
 400 
    
 401 
    mt_stationary_full = (mt_full_trans_mat)^it_trans_power_dist;
 402 
    ar_stationary = mt_stationary_full(:,1);
 403 
end
 404 

 405 
%% 7. Stationary Vector to Stationary Matrix in Original Dimensions
 406 

< 0.001 
      1 
 407
mt_dist_az = reshape(ar_stationary, size(mt_pol_idx)); 
 408 

 409 
%% End Time and Profiler
 410 

 411 
% End Timer
< 0.001 
      1 
 412
if (bl_time) 
< 0.001 
      1 
 413
    toc; 
< 0.001 
      1 
 414
end 
 415 
 
 416 
% End Profile
< 0.001 
      1 
 417
if (bl_profile_dist) 
 418 
    profile off
 419 
    profile viewer
 420 
    st_file_name = [st_profile_prefix st_profile_name_main st_profile_suffix];
 421 
    profsave(profile('info'), strcat(st_profile_path, st_file_name));
 422 
end
 423 

 424 
%% *f(y), f(c), f(a)*: Generate Key Distributional Statistics for Each outcome
 425 
% Having derived f(a,z) the probability mass function of the joint discrete
 426 
% random variables, we now obtain distributional statistics. Note that we
 427 
% know f(a,z), and we also know relevant policy functions a'(a,z), c(a,z),
 428 
% or other policy functions. We can simulate any choices that are a
 429 
% function of the random variables (a,z), using f(a,z). We call function
 430 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solvepost/html/ff_az_ds_post_stats.html
 431 
% ff_az_ds_post_stats> which uses
 432 
% <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_stats.html
 433 
% fft_disc_rand_var_stats> and
 434 
% <https://fanwangecon.github.io/CodeDynaAsset/tools/html/fft_disc_rand_var_mass2outcomes.html
 435 
% fft_disc_rand_var_mass2outcomes> to compute various statistics of
 436 
% interest.
 437 

< 0.001 
      1 
 438
bl_input_override = true; 
  0.344 
      1 
 439
result_map = ff_az_ds_post_stats(support_map, result_map, mt_dist_az, bl_input_override); 
 440 

  0.001 
      1 
 441
end 

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