Match Borrowing Choices to Formal Grid

back to Fan's Dynamic Assets Repository Table of Content.

Contents

function [ar_a_grid_ceil_principle, ar_a_grid_ceil_wthr, ...
    ar_a_grid_floor_principle, ar_a_grid_floor_wthr] = ffs_for_br_block_match(varargin)

FFS_FOR_BR_BLOCK_MATCH formal borrowing blocks

Find Value just below or above each element of ar_a from ar_forbrblk. a vector of grid points, find for each element of ar_a the element of ar_forbrblk that is just above or just below.

  1. ar_a: $a'_i$ where $i \in (1,...,N)$
  2. ar_forbrblk: $grid_j$ where $j\in (1,...,M)$

$$ForCEIL_i = argmin_{j}(ForGrid_j - a'_i | grid_j > a'_i)$$

$ForCEIL_i$ is the level of formal borrowing if joint formal + informal borrowing is chosen.

$$ForFLOOR_i = argmax_{j}(ForGrid_j - a'_i | grid_j <= a'_i)$$

$ForFLOOR_i$ is the level of formal borrowing if joint formal borrowing + informal savings is chosen.

@param ar_a boolean N by 1 single formal borrowing levels, could include interest rate or principle only depending on bl_b_is_principle

@param ar_forbrblk 1 by M array array of formal borrowing grid points. This always is just the formal borrowing levels principles only without interest rate.

@param ar_forbrblk_r array interest rates associated with equal-length ar_forbrblk.

@param bl_b_is_principle boolean solving with aggregate savings as savings + debt principles + interests, or just principles no interests. if true, principels only, no interests. Specifically:

@return ar_a_grid_ceil_principle array N by 1 Solution to:

$$min_{j}(ForGrid_j - a'_i | grid_j > a'_i)$$

@return ar_a_grid_ceil_wthr array ar_a_grid_ceil_principle with interest rates specified to each borrowing formal level added

@return ar_a_grid_floor_principle array N by 1 element of the ar_forbrblk vector that are the elements right above each eelemnt of ar_a. Solution to:

$$max_{j}(ForGrid_j - a'_i | grid_j <= a'_i)$$

@return ar_a_grid_floor_principle array ar_a_grid_floor_principle with interest rates specified to each borrowing formal level added

@example

[ar_a_grid_ceil, ar_a_grid_floor] = ...
     ffs_for_br_block_match(ar_a, ar_forbrblk, ar_forbrblk_r, bl_b_is_principle);

@seealso

Default

% array of a choices
% ar_a could be principles + interests, or principles only
ar_a = -sort(rand([10,1])*20);

% use defaults from block gen
[ar_forbrblk, ar_forbrblk_r] = ffs_for_br_block_gen();

% if bl_b_is_principle is true, b is principles only, no interests.
% bl_b_is_principle = false is the case for models like *abz* without
% interpolation over cash-on-hand
bl_b_is_principle = true;

% Display
if (isempty(varargin))
    bl_display_brblockmatch = true;
else
    bl_display_brblockmatch = false;
end

default_params = {ar_a ar_forbrblk ar_forbrblk_r bl_b_is_principle bl_display_brblockmatch};

Parse Parameters

% numvarargs is the number of varagin inputted
[default_params{1:length(varargin)}] = varargin{:};
[ar_a, ar_forbrblk, ar_forbrblk_r, bl_b_is_principle, bl_display_brblockmatch] = default_params{:};

Adjust Inputs t

if bl_b_is_principle, then principle, with the assumption that ar_forbrblk. If bl_b_is_principle is false, that means the ar_a vector is principle and interest rates. Hence, need to convert ar_forbrblk which are principles to interests plus principles to be on the same scale as ar_a.

if (bl_b_is_principle)
    ar_forbrblk_use = ar_forbrblk;
else
    ar_forbrblk_use = ar_forbrblk.*(1+ar_forbrblk_r);
end

Show Details Step by Step

if (bl_display_brblockmatch)

    % show borrowing array
    disp('ar_a')
    disp(ar_a)

    % show borrowing formal blocks/grids
    disp('ar_forbrblk_use and ar_forbrblk');
    disp([ar_forbrblk_use;ar_forbrblk]');

    % all combination division
    disp('mt_a_dvd_grid = (ar_a./ar_forbrblk_use)');
    mt_a_dvd_grid = (ar_a./ar_forbrblk_use);

    % ceiling for each
    disp('(mt_a_dvd_grid >= 1)');
    (mt_a_dvd_grid >= 1)

    % If ceiling exists and cloest ceiling index
    % min_{j}( ar_forbrblk[j] - ar_a[i] | ar_forbrblk[j] > ar_a[i])
    disp('[~, ar_max_a_on_grid_idx] = max((mt_a_dvd_grid >= 1),[], 2)');
    [~, ar_max_a_on_grid_idx] = max((mt_a_dvd_grid >= 1),[], 2)

    % ar_forbrblk[argmin_{j}( ar_forbrblk[j] - ar_a[i] | ar_forbrblk[j] > ar_a[i])]
    disp('ar_a_grid_ceil = ar_forbrblk_use(ar_max_a_on_grid_idx)');
    ar_a_grid_ceil = ar_forbrblk_use(ar_max_a_on_grid_idx)
    % ar_a_grid_ceil(ar_max_a_on_grid_idx == 1) = ar_forbrblk(0)

    % now floor, just one index less
    disp('ar_a_grid_floor = ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1))');
    ar_a_grid_floor = ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1))
    % ar_a_grid_floor(ar_max_a_on_grid_idx == 1) =

    % Dispaly
    tab_matched_grid = table(ar_a, ar_a_grid_floor', ar_a_grid_ceil');
    tab_matched_grid.Properties.VariableNames = {'ar_a','ar_a_grid_floor','ar_a_grid_ceil'};
    disp('ar_a_grid_floor: for borrow + for save');
    disp('ar_a_grid_ceil: for + inf borrow');
    disp(tab_matched_grid);
end
ar_a
   -0.1193
   -0.4659
   -0.7142
   -3.3894
   -5.3466
  -12.3617
  -12.4052
  -17.8726
  -18.2702
  -19.3514

ar_forbrblk_use and ar_forbrblk
  -19.0000  -19.0000
  -18.5000  -18.5000
  -18.0000  -18.0000
  -17.5000  -17.5000
  -17.0000  -17.0000
  -16.5000  -16.5000
  -16.0000  -16.0000
  -15.5000  -15.5000
  -15.0000  -15.0000
  -14.5000  -14.5000
  -14.0000  -14.0000
  -13.5000  -13.5000
  -13.0000  -13.0000
  -12.5000  -12.5000
  -12.0000  -12.0000
  -11.5000  -11.5000
  -11.0000  -11.0000
  -10.5000  -10.5000
  -10.0000  -10.0000
   -9.5000   -9.5000
   -9.0000   -9.0000
   -8.5000   -8.5000
   -8.0000   -8.0000
   -7.5000   -7.5000
   -7.0000   -7.0000
   -6.5000   -6.5000
   -6.0000   -6.0000
   -5.5000   -5.5000
   -5.0000   -5.0000
   -4.5000   -4.5000
   -4.0000   -4.0000
   -3.5000   -3.5000
   -3.0000   -3.0000
   -2.5000   -2.5000
   -2.0000   -2.0000
   -1.5000   -1.5000
   -1.0000   -1.0000
         0         0

mt_a_dvd_grid = (ar_a./ar_forbrblk_use)
(mt_a_dvd_grid >= 1)

ans =

  10×38 logical array

  Columns 1 through 19

   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   1   1   1   1
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   1   1   1   1
   0   0   0   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   0   0   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  Columns 20 through 38

   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1
   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1
   0   0   0   0   0   0   0   0   0   0   0   0   0   1   1   1   1   1   1
   0   0   0   0   0   0   0   0   0   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

[~, ar_max_a_on_grid_idx] = max((mt_a_dvd_grid >= 1),[], 2)

ar_max_a_on_grid_idx =

    38
    38
    38
    33
    29
    15
    15
     4
     3
     1

ar_a_grid_ceil = ar_forbrblk_use(ar_max_a_on_grid_idx)

ar_a_grid_ceil =

  Columns 1 through 7

         0         0         0   -3.0000   -5.0000  -12.0000  -12.0000

  Columns 8 through 10

  -17.5000  -18.0000  -19.0000

ar_a_grid_floor = ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1))

ar_a_grid_floor =

  Columns 1 through 7

   -1.0000   -1.0000   -1.0000   -3.5000   -5.5000  -12.5000  -12.5000

  Columns 8 through 10

  -18.0000  -18.5000  -19.0000

ar_a_grid_floor: for borrow + for save
ar_a_grid_ceil: for + inf borrow
      ar_a      ar_a_grid_floor    ar_a_grid_ceil
    ________    _______________    ______________

    -0.11933            -1                 0     
    -0.46588            -1                 0     
    -0.71421            -1                 0     
     -3.3894          -3.5                -3     
     -5.3466          -5.5                -5     
     -12.362         -12.5               -12     
     -12.405         -12.5               -12     
     -17.873           -18             -17.5     
      -18.27         -18.5               -18     
     -19.351           -19               -19     

Standard Quicker Solve

% Get Index
[~, ar_max_a_on_grid_idx] = max(((ar_a./ar_forbrblk_use) >= 1),[], 2);

% Get Values
if (bl_b_is_principle)

    % Borrowing borrowing points, following formal grids, but add interests
    ar_a_grid_ceil_wthr = ...
        (ar_forbrblk_use(ar_max_a_on_grid_idx).*(1+ar_forbrblk_r(ar_max_a_on_grid_idx)))';
    ar_a_grid_floor_wthr = ...
        (ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1)).*(1+ar_forbrblk_r(max(ar_max_a_on_grid_idx - 1, 1))))';

    % Principles only, note ar_forbrblk_use = ar_forbrblk
    ar_a_grid_ceil_principle = ar_forbrblk_use(ar_max_a_on_grid_idx)';
    ar_a_grid_floor_principle = ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1))';

else

    % Borrowing borrowing points, following formal grids, but add interests
    ar_a_grid_ceil_wthr = ar_forbrblk_use(ar_max_a_on_grid_idx)';
    ar_a_grid_floor_wthr = ar_forbrblk_use(max(ar_max_a_on_grid_idx - 1, 1))';

    % Principles only
    ar_a_grid_ceil_principle = ar_forbrblk(ar_max_a_on_grid_idx)';
    ar_a_grid_floor_principle = ar_forbrblk(max(ar_max_a_on_grid_idx - 1, 1))';

end

Display

if (bl_display_brblockmatch)

    disp('ar_a_grid_ceil_principle');
    disp(ar_a_grid_ceil_principle);

    disp('ar_a_grid_ceil_wthr');
    disp(ar_a_grid_ceil_wthr);

    disp('ar_a_grid_floor_principle');
    disp(ar_a_grid_floor_principle);

    disp('ar_a_grid_floor_wthr');
    disp(ar_a_grid_floor_wthr);

end
ar_a_grid_ceil_principle
         0
         0
         0
   -3.0000
   -5.0000
  -12.0000
  -12.0000
  -17.5000
  -18.0000
  -19.0000

ar_a_grid_ceil_wthr
         0
         0
         0
   -3.1350
   -5.2250
  -12.5400
  -12.5400
  -18.2875
  -18.8100
  -19.8550

ar_a_grid_floor_principle
   -1.0000
   -1.0000
   -1.0000
   -3.5000
   -5.5000
  -12.5000
  -12.5000
  -18.0000
  -18.5000
  -19.0000

ar_a_grid_floor_wthr
   -1.0450
   -1.0450
   -1.0450
   -3.6575
   -5.7475
  -13.0625
  -13.0625
  -18.8100
  -19.3325
  -19.8550

end
ans =

         0
         0
         0
   -3.0000
   -5.0000
  -12.0000
  -12.0000
  -17.5000
  -18.0000
  -19.0000