This is a static copy of a profile report

Home

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

Home

ff_az_vf_vecsv (Calls: 1, Time: 1.381 s)
Generated 22-Jul-2019 16:35:06 using performance time.
function in file C:\Users\fan\CodeDynaAsset\m_az\solve\ff_az_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
272
[ar_opti_val1_z, ar_opti_idx_z...
15900.533 s38.6%
266
mt_utility = mt_utility.*(~mt_...
15900.257 s18.6%
238
mt_utility = f_util_crra(mt_c)...
150.189 s13.7%
260
mt_utility = cl_u_c_store{it_z...
15900.176 s12.7%
243
mt_utility(mt_it_c_valid_idx) ...
150.064 s4.6%
All other lines  0.162 s11.7%
Totals  1.381 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
...c)(((c).^(1-fl_crra)-1)./(1-fl_crra))anonymous function150.182 s13.2%
...s>@(z,b,bprime)(f_coh(z,b)-bprime)anonymous function150.017 s1.2%
Self time (built-ins, overhead, etc.)  1.182 s85.6%
Totals  1.381 s100% 
Code Analyzer results
Line numberMessage
146The value assigned here to 'f_util_log' appears to be unused. Consider replacing it by ~.
Coverage results
Show coverage for parent directory
Total lines in function375
Non-code lines (comments, blank lines)235
Code lines (lines that can run)140
Code lines that did run51
Code lines that did not run89
Coverage (did run/can run)36.43 %
Function listing
time 
Calls 
 line
   7 
function result_map = ff_az_vf_vecsv(varargin)
   8 
%% FF_AZ_VF_VECSV solve infinite horizon exo shock + endo asset problem
   9 
% This program solves the infinite horizon dynamic single asset and single
  10 
% shock problem with vectorized codes.
  11 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf.html
  12 
% ff_az_vf> shows looped codes.
  13 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vec.html
  14 
% ff_az_vf_vec> shows vectorized codes. This file shows vectorized codes
  15 
% that is faster but is more memory intensive.
  16 
%
  17 
% See
  18 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vec.html
  19 
% ff_az_vf_vec> how vectorization works within this structure.
  20 
%
  21 
% This _optimized-vectorized_ solution method provides very large speed
  22 
% improvements for this infinite horizon problem because the u(c(z,a,a'))
  23 
% calculation within each iteration is identical. Generally the idea is to
  24 
% identify inside iteration whether the model is infinite horizon or
  25 
% life-cycle based where repeat calculations are taking place. If such
  26 
% calculations can be identified, then potentially they could be stored and
  27 
% retrieved during future iterations/periods rather than recomputed every
  28 
% time. This saves time.
  29 
%
  30 
% @param param_map container parameter container
  31 
%
  32 
% @param support_map container support container
  33 
%
  34 
% @param armt_map container container with states, choices and shocks
  35 
% grids that are inputs for grid based solution algorithm
  36 
%
  37 
% @param func_map container container with function handles for
  38 
% consumption cash-on-hand etc.
  39 
%
  40 
% @return result_map container contains policy function matrix, value
  41 
% function matrix, iteration results, and policy function, value function
  42 
% and iteration results tables.
  43 
%
  44 
% keys included in result_map:
  45 
%
  46 
% * mt_val matrix states_n by shock_n matrix of converged value function grid
  47 
% * mt_pol_a matrix states_n by shock_n matrix of converged policy function grid
  48 
% * ar_val_diff_norm array if bl_post = true it_iter_last by 1 val function
  49 
% difference between iteration
  50 
% * ar_pol_diff_norm array if bl_post = true it_iter_last by 1 policy
  51 
% function difference between iterations
  52 
% * mt_pol_perc_change matrix if bl_post = true it_iter_last by shock_n the
  53 
% proportion of grid points at which policy function changed between
  54 
% current and last iteration for each element of shock
  55 
%
  56 
% @example
  57 
%
  58 
%    % Get Default Parameters
  59 
%    it_param_set = 2;
  60 
%    [param_map, support_map] = ffs_abz_set_default_param(it_param_set);
  61 
%    % Change Keys in param_map
  62 
%    param_map('it_a_n') = 500;
  63 
%    param_map('it_z_n') = 11;
  64 
%    param_map('fl_a_max') = 100;
  65 
%    param_map('fl_w') = 1.3;
  66 
%    % Change Keys support_map
  67 
%    support_map('bl_display') = false;
  68 
%    support_map('bl_post') = true;
  69 
%    support_map('bl_display_final') = false;
  70 
%    % Call Program with external parameters that override defaults.
  71 
%    ff_az_vf_vecsv(param_map, support_map);
  72 
%
  73 
% @include
  74 
%
  75 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/paramfunc/html/ffs_az_set_default_param.html ffs_az_set_default_param>
  76 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/paramfunc/html/ffs_az_get_funcgrid.html ffs_az_get_funcgrid>
  77 
% * <https://fanwangecon.github.io/CodeDynaAsset/m_az/solvepost/html/ff_az_vf_post.html ff_az_vf_post>
  78 
%
  79 
% @seealso
  80 
%
  81 
% * save loop: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf.html ff_az_vf>
  82 
% * save vectorized: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vec.html ff_az_vf_vec>
  83 
% * save optimized-vectorized: <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_az_vf_vecsv.html ff_az_vf_vecsv>
  84 
% * save + borr loop: <https://fanwangecon.github.io/CodeDynaAsset/m_abz/solve/html/ff_abz_vf.html ff_abz_vf>
  85 
% * save + borr vectorized: <https://fanwangecon.github.io/CodeDynaAsset/m_abz/solve/html/ff_abz_vf_vec.html ff_abz_vf_vec>
  86 
% * save + borr optimized-vectorized: <https://fanwangecon.github.io/CodeDynaAsset/m_abz/solve/html/ff_abz_vf_vecsv.html ff_abz_vf_vecsv>
  87 
%
  88 

  89 

  90 
%% Default
  91 
%
  92 
% * it_param_set = 1: quick test
  93 
% * it_param_set = 2: benchmark run
  94 
% * it_param_set = 3: benchmark profile
  95 
% * it_param_set = 4: press publish button
  96 
%
  97 
% go to
  98 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/paramfunc/html/ffs_az_set_default_param.html
  99 
% ffs_az_set_default_param> to change parameters in param_map container.
 100 
% The parameters can also be updated here directly after obtaining them
 101 
% from ffs_az_set_default_param as we possibly change it_a_n and it_z_n
 102 
% here.
 103 

 104 
it_param_set = 3;
 105 
bl_input_override = true;
 106 
[param_map, support_map] = ffs_az_set_default_param(it_param_set);
 107 

 108 
% Note: param_map and support_map can be adjusted here or outside to override defaults
 109 
% param_map('it_a_n') = 750;
 110 
% param_map('it_z_n') = 15;
 111 
    
 112 
[armt_map, func_map] = ffs_az_get_funcgrid(param_map, support_map, bl_input_override); % 1 for override
 113 
default_params = {param_map support_map armt_map func_map};
 114 

 115 
%% Parse Parameters 1
 116 

 117 
% if varargin only has param_map and support_map,
 118 
params_len = length(varargin);
 119 
[default_params{1:params_len}] = varargin{:};
 120 
param_map = [param_map; default_params{1}];
 121 
support_map = [support_map; default_params{2}];
 122 
if params_len >= 1 && params_len <= 2
 123 
    % If override param_map, re-generate armt and func if they are not
 124 
    % provided
 125 
    bl_input_override = true;
 126 
    [armt_map, func_map] = ffs_az_get_funcgrid(param_map, support_map, bl_input_override);
 127 
else
 128 
    % Override all
 129 
    armt_map = [armt_map; default_params{3}];
 130 
    func_map = [func_map; default_params{4}];
 131 
end
 132 

 133 
% append function name
 134 
st_func_name = 'ff_az_vf_vecsv';
 135 
support_map('st_profile_name_main') = [st_func_name support_map('st_profile_name_main')];
 136 
support_map('st_mat_name_main') = [st_func_name support_map('st_mat_name_main')];
 137 
support_map('st_img_name_main') = [st_func_name support_map('st_img_name_main')];
 138 

 139 
%% Parse Parameters 2
 140 

 141 
% armt_map
 142 
params_group = values(armt_map, {'ar_a', 'mt_z_trans', 'ar_z'});
 143 
[ar_a, mt_z_trans, ar_z] = params_group{:};
 144 
% func_map
 145 
params_group = values(func_map, {'f_util_log', 'f_util_crra', 'f_cons', 'f_coh'});
 146 
[f_util_log, f_util_crra, f_cons, f_coh] = params_group{:};
 147 
% param_map
 148 
params_group = values(param_map, {'it_a_n', 'it_z_n', 'fl_crra', 'fl_beta', 'fl_nan_replace'});
 149 
[it_a_n, it_z_n, fl_crra, fl_beta, fl_nan_replace] = params_group{:};
 150 
params_group = values(param_map, {'it_maxiter_val', 'fl_tol_val', 'fl_tol_pol', 'it_tol_pol_nochange'});
 151 
[it_maxiter_val, fl_tol_val, fl_tol_pol, it_tol_pol_nochange] = params_group{:};
 152 

 153 
% support_map
 154 
params_group = values(support_map, {'bl_profile', 'st_profile_path', ...
 155 
    'st_profile_prefix', 'st_profile_name_main', 'st_profile_suffix',...
 156 
    'bl_time', 'bl_display_defparam', 'bl_display', 'it_display_every', 'bl_post'});
 157 
[bl_profile, st_profile_path, ...
 158 
    st_profile_prefix, st_profile_name_main, st_profile_suffix, ...
 159 
    bl_time, bl_display_defparam, bl_display, it_display_every, bl_post] = params_group{:};
 160 
params_group = values(support_map, {'it_display_summmat_rowmax', 'it_display_summmat_colmax'});
 161 
[it_display_summmat_rowmax, it_display_summmat_colmax] = params_group{:};
 162 

 163 
%% Initialize Output Matrixes
 164 
% include mt_pol_idx which we did not have in looped code
 165 

 166 
mt_val_cur = zeros(length(ar_a),length(ar_z));
 167 
mt_val = mt_val_cur - 1;
 168 
mt_pol_a = zeros(length(ar_a),length(ar_z));
 169 
mt_pol_a_cur = mt_pol_a - 1;
 170 
mt_pol_idx = zeros(length(ar_a),length(ar_z));
 171 

 172 
% We did not need these in ff_az_vf or ff_az_vf_vec
 173 
% see
 174 
% <https://fanwangecon.github.io/M4Econ/support/speed/partupdate/fs_u_c_partrepeat_main.html
 175 
% fs_u_c_partrepeat_main> for why store using cells.
 176 
cl_u_c_store = cell([it_z_n, 1]);
 177 
cl_c_valid_idx = cell([it_z_n, 1]);
 178 

 179 
%% Initialize Convergence Conditions
 180 

 181 
bl_vfi_continue = true;
 182 
it_iter = 0;
 183 
ar_val_diff_norm = zeros([it_maxiter_val, 1]);
 184 
ar_pol_diff_norm = zeros([it_maxiter_val, 1]);
 185 
mt_pol_perc_change = zeros([it_maxiter_val, it_z_n]);
 186 

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

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

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

 208 
% Value Function Iteration
< 0.001 
      1 
 209
while bl_vfi_continue 
< 0.001 
    106 
 210
    it_iter = it_iter + 1; 
 211 

 212 
    %% Solve Optimization Problem Current Iteration
 213 
    % Only this segment of code differs between ff_az_vf and ff_az_vf_vec
 214 
    % Store in cells results and retrieve, this is more memory intensive
 215 
    % than ff_az_vf_vec.
 216 

 217 
    % loop 1: over exogenous states
< 0.001 
    106 
 218
    for it_z_i = 1:length(ar_z) 
 219 

 220 
        % Current Shock
< 0.001 
   1590 
 221
        fl_z = ar_z(it_z_i); 
 222 

 223 
        % Consumption and u(c) only need to be evaluated once
  0.001 
   1590 
 224
        if (it_iter == 1) 
 225 

 226 
            % Consumption: fl_z = 1 by 1, ar_a = 1 by N, ar_a' = N by 1
 227 
            % mt_c is N by N: matrix broadcasting, expand to matrix from arrays
  0.024 
     15 
 228
            mt_c = f_cons(fl_z, ar_a, ar_a'); 
 229 

 230 
            % EVAL current utility: N by N, f_util defined earlier
 231 
            % slightly faster to explicitly write function
< 0.001 
     15 
 232
            if (fl_crra == 1) 
 233 
                mt_utility = log(mt_c);
< 0.001 
     15 
 234
            else 
 235 
                % slightly faster if write function here directly, but
 236 
                % speed gain is very small, more important to have single
 237 
                % location control of functions.
  0.189 
     15 
 238
                mt_utility = f_util_crra(mt_c); 
< 0.001 
     15 
 239
            end 
 240 

 241 
            % Eliminate Complex Numbers
  0.005 
     15 
 242
            mt_it_c_valid_idx = (mt_c <= 0); 
  0.064 
     15 
 243
            mt_utility(mt_it_c_valid_idx) = fl_nan_replace; 
 244 

 245 
            % Store in cells
< 0.001 
     15 
 246
            cl_u_c_store{it_z_i} = mt_utility; 
< 0.001 
     15 
 247
            cl_c_valid_idx{it_z_i} = mt_it_c_valid_idx; 
 248 

< 0.001 
     15 
 249
        end 
 250 

 251 
        % f(z'|z)
  0.001 
   1590 
 252
        ar_z_trans_condi = mt_z_trans(it_z_i,:); 
 253 

 254 
        % EVAL EV((A',K'),Z'|Z) = V((A',K'),Z') x p(z'|z)', (N by Z) x (Z by 1) = N by 1
 255 
        % Note: transpose ar_z_trans_condi from 1 by Z to Z by 1
 256 
        % Note: matrix multiply not dot multiply
  0.008 
   1590 
 257
        mt_evzp_condi_z = mt_val_cur * ar_z_trans_condi'; 
 258 

 259 
        % EVAL add on future utility, N by N + N by 1
  0.176 
   1590 
 260
        mt_utility = cl_u_c_store{it_z_i} + fl_beta*mt_evzp_condi_z; 
 261 

 262 
        % Index update
 263 
        % using the method below is much faster than index replace
 264 
        % see <https://fanwangecon.github.io/M4Econ/support/speed/index/fs_subscript.html fs_subscript>
  0.001 
   1590 
 265
        mt_it_c_valid_idx = cl_c_valid_idx{it_z_i}; 
  0.257 
   1590 
 266
        mt_utility = mt_utility.*(~mt_it_c_valid_idx) + fl_nan_replace*(mt_it_c_valid_idx); 
 267 

 268 
        % Optimization: remember matlab is column major, rows must be
 269 
        % choices, columns must be states
 270 
        % <https://en.wikipedia.org/wiki/Row-_and_column-major_order COLUMN-MAJOR>
 271 
        % mt_utility is N by N, rows are choices, cols are states.
  0.533 
   1590 
 272
        [ar_opti_val1_z, ar_opti_idx_z] = max(mt_utility); 
  0.011 
   1590 
 273
        mt_val(:,it_z_i) = ar_opti_val1_z; 
  0.014 
   1590 
 274
        mt_pol_a(:,it_z_i) = ar_a(ar_opti_idx_z); 
< 0.001 
   1590 
 275
        if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
     15 
 276
            mt_pol_idx(:,it_z_i) = ar_opti_idx_z; 
< 0.001 
     15 
 277
        end 
  0.001 
   1590 
 278
    end 
 279 

 280 
    %% Check Tolerance and Continuation
 281 

 282 
    % Difference across iterations
  0.042 
    106 
 283
    ar_val_diff_norm(it_iter) = norm(mt_val - mt_val_cur); 
  0.032 
    106 
 284
    ar_pol_diff_norm(it_iter) = norm(mt_pol_a - mt_pol_a_cur); 
  0.008 
    106 
 285
    mt_pol_perc_change(it_iter, :) = sum((mt_pol_a ~= mt_pol_a_cur))/(it_a_n); 
 286 

 287 
    % Update
  0.003 
    106 
 288
    mt_val_cur = mt_val; 
  0.002 
    106 
 289
    mt_pol_a_cur = mt_pol_a; 
 290 

 291 
    % Print Iteration Results
< 0.001 
    106 
 292
    if (bl_display && (rem(it_iter, it_display_every)==0)) 
 293 
        fprintf('VAL it_iter:%d, fl_diff:%d, fl_diff_pol:%d\n', ...
 294 
            it_iter, ar_val_diff_norm(it_iter), ar_pol_diff_norm(it_iter));
 295 
        tb_valpol_iter = array2table([mean(mt_val_cur,1); mean(mt_pol_a_cur,1); ...
 296 
            mt_val_cur(it_a_n,:); mt_pol_a_cur(it_a_n,:)]);
 297 
        tb_valpol_iter.Properties.VariableNames = strcat('z', string((1:size(mt_val_cur,2))));
 298 
        tb_valpol_iter.Properties.RowNames = {'mval', 'map', 'Hval', 'Hap'};
 299 
        disp('mval = mean(mt_val_cur,1), average value over a')
 300 
        disp('map  = mean(mt_pol_a_cur,1), average choice over a')
 301 
        disp('Hval = mt_val_cur(it_a_n,:), highest a state val')
 302 
        disp('Hap = mt_pol_a_cur(it_a_n,:), highest a state choice')
 303 
        disp(tb_valpol_iter);
 304 
    end
 305 

 306 
    % Continuation Conditions:
 307 
    % 1. if value function convergence criteria reached
 308 
    % 2. if policy function variation over iterations is less than
 309 
    % threshold
< 0.001 
    106 
 310
    if (it_iter == (it_maxiter_val + 1)) 
< 0.001 
      1 
 311
        bl_vfi_continue = false; 
  0.002 
    105 
 312
    elseif ((it_iter == it_maxiter_val) || ... 
    105 
 313
            (ar_val_diff_norm(it_iter) < fl_tol_val) || ... 
    105 
 314
            (sum(ar_pol_diff_norm(max(1, it_iter-it_tol_pol_nochange):it_iter)) < fl_tol_pol)) 
 315 
        % Fix to max, run again to save results if needed
< 0.001 
      1 
 316
        it_iter_last = it_iter; 
< 0.001 
      1 
 317
        it_iter = it_maxiter_val; 
< 0.001 
      1 
 318
    end 
 319 

< 0.001 
    106 
 320
end 
 321 

 322 
% End Timer
< 0.001 
      1 
 323
if (bl_time) 
< 0.001 
      1 
 324
    toc; 
< 0.001 
      1 
 325
end 
 326 

 327 
% End Profile
< 0.001 
      1 
 328
if (bl_profile) 
  0.001 
      1 
 329
    profile off 
 330 
    profile viewer
 331 
    st_file_name = [st_profile_prefix st_profile_name_main st_profile_suffix];
 332 
    profsave(profile('info'), strcat(st_profile_path, st_file_name));
 333 
end
 334 

 335 
%% Process Optimal Choices
 336 
% for choices outcomes, store as cell with two elements, first element is
 337 
% the y(a,z), outcome given states, the second element will be solved found
 338 
% in
 339 
% <https://fanwangecon.github.io/CodeDynaAsset/m_az/solve/html/ff_ds_vf.html
 340 
% ff_ds_vf> and other distributions files. It stores what are the
 341 
% probability mass function of y, along with sorted unique values of y.
 342 

 343 
result_map = containers.Map('KeyType','char', 'ValueType','any');
 344 
result_map('mt_val') = mt_val;
 345 
result_map('mt_pol_idx') = mt_pol_idx;
 346 

 347 
result_map('cl_mt_coh') = {f_coh(ar_z, ar_a'), zeros(1)};
 348 
result_map('cl_mt_pol_a') = {mt_pol_a, zeros(1)};
 349 
result_map('cl_mt_pol_c') = {f_cons(ar_z, ar_a', mt_pol_a), zeros(1)};
 350 
result_map('ar_st_pol_names') = ["cl_mt_pol_a", "cl_mt_coh", "cl_mt_pol_c"];
 351 

 352 
if (bl_post)
 353 
    bl_input_override = true;
 354 
    result_map('ar_val_diff_norm') = ar_val_diff_norm(1:it_iter_last);
 355 
    result_map('ar_pol_diff_norm') = ar_pol_diff_norm(1:it_iter_last);
 356 
    result_map('mt_pol_perc_change') = mt_pol_perc_change(1:it_iter_last, :);
 357 
    result_map = ff_az_vf_post(param_map, support_map, armt_map, func_map, result_map, bl_input_override);
 358 
end
 359 

 360 
%% Display Various Containers
 361 

 362 
if (bl_display_defparam)
 363 

 364 
    %% Display 1 support_map
 365 
    fft_container_map_display(support_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 366 

 367 
    %% Display 2 armt_map
 368 
    fft_container_map_display(armt_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 369 

 370 
    %% Display 3 param_map
 371 
    fft_container_map_display(param_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 372 

 373 
    %% Display 4 func_map
 374 
    fft_container_map_display(func_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 375 

 376 
    %% Display 5 result_map
 377 
    fft_container_map_display(result_map, it_display_summmat_rowmax, it_display_summmat_colmax);
 378 

 379 
end
 380 

 381 
end

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