%% Borrowing Choice Set Discretization in a Deterministic Two Period Model
% *<https://fanwangecon.github.io/ThaiForInfLuuRobFan/ Go back to LuuRobFan 
% Project Main Page>*
%% Borrowing Constraint
% In a standard incomplete market savings/borrowing model, households are able 
% to borrow and save, with risk-free asset $b$ and given interest rate $r$. $b<0$ 
% is borrowing, and $b>0$ is saving.
% 
% * Savings is limited by the cash-on-hand available to households today.
% * Borrowing is limited by households' minimum Wealth in future periods.
% 
% To model financial constraints, an exogenous or endogenous bound*, *$\bar{b} 
% \le 0$ with $\bar{b} \le b$, is often imposed on borrowing that could be tighter 
% than the (non-binding) naturally borrowing limit.
% 
% Financial deepening might come in the form of relaxing/decreasing $\bar{b}$ 
% so that households can borrow to finance investments and consumption when they 
% are low on cash today relative to the future. 
%% Increasing the Borrowing Choice Set
% $b \ge \bar{b}$ assumes that lenders impose a quantity bound, and a development 
% banker's policy could shift $\bar{b}$ to the left or the right.
% 
% In reality, lenders can also choose what borrowing quantities/levels are 
% available to households, and couple these with variations in borrowing rates 
% $r_b$:
% 
% _Borrow Choice Set_:$\left\{ \left\{ \mathcal{b}_1, r_1 \right\},..., \left\{\mathcal{b}_N,r_N\right\} 
% \right\}$
% 
% Improving borrowing condition--financial deepening--might not involve allowing 
% for larger maximum borrowing quantity, but by increasing the number of borrowing 
% options within the existing maximum bound.
%% Why Would Lenders Offer Only a Borrowing Choice Set
% Why not allow households to choose their optimal borrowing level?  
% 
% Empirically, some, perhaps many, development banks and microfinance lenders 
% offer loans in discretized borrowing sets.
% 
% Even if more continuous borrowing ranges are allowed, it is common for 
% development lenders to at least set the smallest level of borrowing. This is 
% the simplest form of discretization. It happens in the opposite direction as 
% the standard borrowing limit. 
% 
% Perhaps from the perspective of operating a large-scale national development-oriented 
% bank that has branches in rural areas, it is sometimes just administratively 
% easier to deal with standardized loan sizes that are at least larger than a 
% particular size.
% 
% Perhaps in places with credit-rating is more readily available, it is easier 
% for banks to come up with a formula to determine the exact upper bound for borrowing. 
% When credit cards are obtained in the US for example, any borrowing up to the 
% credit-limit is allowed.
%% *Two Period Model and Choice Set*
% Given the simplest two period borrowing problem, what is the optimal choice, 
% and what is the choice when the choice set is B-discrete-constrained:
% 
% * Exogenous endowments in both periods: $z_1, z_2$
% * One choice: $b$, borrow or save
% * Assume for now all interest rates are the same
% 
% $$max_{b \in \mathcal{B}} \log \left( z_1 - b \right) + \beta \cdot \log\left( 
% z_2 + (1+r) \cdot b \right)$$
% 
% where: $\mathcal{B} \in \left\{ \left\{ \mathcal{b^{\text{br}}_1}, \mathcal{b^{\text{br}}_2}, 
% ..., \mathcal{b^{\text{br}}_N} \right\} \cup \left\{ b^{\text{save}} \mid b 
% \ge 0 \right\} \right\}$
%% Unconstrained Problem
% In the following numerical example, the endowment is higher in the second 
% period, giving households an incentive to borrow. To simplify things, the interest 
% rate is the same for all levels of borrowing. First, I draw the budget line, 
% indifference curve, endowment point, and the optimal unconstrained borrowing 
% choice.
%%
% Numbers
z1 = 0.2;
z2 = 2;
beta = 1;
r = 0;

% Symbols
syms b

% Utility
Utility = log(z1-b) + beta*log(z2+b*(1+r));

% Optimal Choice
b_opti = double(solve(diff(Utility, b)==0, b, 'Real', true));
c1_opti = z1 - b_opti;
c2_opti = z2 + b_opti*(1+r);

% Value (Utility at Optimal Choices)
U_at_b_opti = double(subs(Utility, {b}, {b_opti}));

% Results In Table
unconstrained_table=table(b_opti, c1_opti, c2_opti, U_at_b_opti)

% Define Budget Line and Indifference Curve
syms c1
% The Budget Line
f_budget = z1*(1+r) + z2 - c1*(1+r);
% Indifference at V*
f_indiff = exp((U_at_b_opti-log(c1))/(beta));

% Graph
figure();
hold on;
% Main Lines
fplot(f_budget, [0, (z1 + z2/(1+r))*1.25]);
fplot(f_indiff, [0, (z1 + z2/(1+r))*1.25]);

% Endowment Point
scatter(c1_opti, c2_opti, 100, 'k', 'filled', 'd');
plot(linspace(0,c1_opti,10),ones(10,1) * c2_opti, 'k--', 'HandleVisibility','off');
plot(ones(10,1) * c1_opti, linspace(0,c2_opti,10), 'k--', 'HandleVisibility','off');

% Optimal Choices Point
scatter(z1, z2, 100, 'k', 's');
plot(linspace(0,z1,10),ones(10,1) * z2, 'k--', 'HandleVisibility','off');
plot(ones(10,1) * z1, linspace(0,z2,10), 'k--', 'HandleVisibility','off');

% Labeling
ylim([0, (z1 + z2/(1+r))*1.25])
title({['Optimal Choices Given Complete Budget'],...
       ['Borrowing only Bounded by Endowment Next Period'],...
       ['beta = ' num2str(beta) ', z1 = ' num2str(z1)...
        ', z2 = ' num2str(z2) ', r = ' num2str(r) ' ']})
xlabel('consumption today');
ylabel('consumption tomorrow');
legend({'Budget', 'Utility at Optimal Choices', 'Optimal Choice', 'Endowment Point'})
grid on;
%% *Optimal Choices with Grid-Constrained Borrowing Choice Set*
% Now we solve for the grid-constrained problem. We don't have to worry about 
% savings here because endowment is higher in the second period, so households 
% naturally want to borrow.
% 
% * The borrowing grid is equi-distance and starts at $0$
% * Different households will be impacted by the same borrow grid differently 
% depending on how much they need to borrow
% * If the borrow grid points happen to be close to the unconstrained optimal 
% choice, discretization has low costs
%%
% There is a grid of b choices
b_grid_gap = 0.6;
% This is the max natural borrowing constraint
b_max_borrow = z2/(1+r); 
% The is the choice Grid
b_grid = (-1)*(0:b_grid_gap:b_max_borrow);
% r_grid = zeros(size(b_grid)) + r;
r_slope = 0;
r_grid = zeros(size(b_grid)) + r;
% r_grid = r + 0:(r_slope):((length(b_grid)-1)*(r_slope));
% b_grid = [0 b_opti/2 b_opti*1.5];
c1_b_grid = z1 - b_grid;
c2_b_grid = z2 + b_grid.*(1+r_grid);

% Utility Along Choice Grid
Utility_Grid = log(z1-b_grid) + beta*log(z2+b_grid.*(1+r_grid));

% Optimal Choice
[val_og, max_idx] = max(Utility_Grid);
b_opti_grid_constrained = b_grid(max_idx);
r_og = r_grid(max_idx);
c1_opti_grid = z1 - b_opti_grid_constrained;
c2_opti_grid = z2 + b_opti_grid_constrained*(1+r);

% Results In Table
unconstrained_table
constrained_table = table(b_opti_grid_constrained, c1_opti_grid, c2_opti_grid, val_og)
%% Expenditure Minimization to Calculate Wealth Loss due to Discretization
% Given the optimal b-grid-constrained choice, we evaluate utility at the optimal 
% point and can solve for the expenditure minimization problem given this b-grid-constrained 
% optimal value.
% 
% The expenditure minimization problem search for the budget that is required 
% if choices were unconstrained that would achieve the same level of optimal utility 
% as the b-grid-constrained problem.
% 
% Comparing the actual budget and the budget from expenditure minimization, 
% we can calculate the Wealth loss due to discretization.
%%
% Solve a Expenditure Minimization Problem
% Under what budget would the value at constrained optimal bundle 
% be value for unconstrained problem?
syms c1 c2 lambda
lagrangian = (c2 + (1+r_og)*c1 - lambda*( log(c1) + beta*log(c2) - val_og));
solu_min = solve(diff(lagrangian, c1)==0,...
                 diff(lagrangian, c2)==0,...
                 diff(lagrangian, lambda)==0,...
                 c1, c2, lambda, 'Real', true);
solu_min_c1 = double(solu_min.c1);
solu_min_c2 = double(solu_min.c2);
Wealth_grid = solu_min_c1*(1+r_og) + solu_min_c2;
Wealth_loss = 1- (Wealth_grid/(z1*(1+r_og) + z2));
Wealth_loss_percent = round(Wealth_loss*10000)/100;

% Show Table Results
unconstrained_table
constrained_table
exp_min_table = table(solu_min_c1, solu_min_c2, Wealth_loss, Wealth_loss_percent)
%% Graphical Results 
% Show results graphically. The Graph below will show these:
% 
% * *Endowment Point:* where $z_1$ and $z_2$ are 
% * *Unconstrained (complete budget) problem Budget*: Budget given interest 
% rate, frontier when any borrowing and savings are allowed
% * *Unconstrained (complete budget) problem Value*: Indifference curve for 
% utility given the optimal unconstrained choice
% * *B-Grid Choice Set*: Borrow Grid Constrained Choice Set
% * *B-Grid Expenditure Minimizing Budget*: Given B-Grid optimal value, what 
% is the budget from the expenditure minimization problem
% * *B-Grid Optimal Value*: Given B-Grid optimal choice, what is the utility.
% * *B-Grid Optimal Choice*: Optimal B-Constrained Choice
%%
% For Graphing
syms c1
% The grid constrained value's unconstrained optimal budget line
f_budget_grid_constrained = solu_min_c1*(1+r_og) + solu_min_c2 - c1*(1+r_og);
% Indifference for grid constrained value
f_indiff_grid_constrained = exp((val_og-log(c1))/(beta));

% Graphing
figure();
hold on;

% Endowment Point
scatter(z1, z2, 250, 'k', 's');
plot(linspace(0,z1,10),ones(10,1) * z2, 'k--', 'HandleVisibility','off');
plot(ones(10,1) * z1, linspace(0,z2,10), 'k--', 'HandleVisibility','off');

% Unconstrained Lines now Dashed
fplot(f_budget, [0, (z1 + z2/(1+r))*1.25], 'b--');
fplot(f_indiff, [0, (z1 + z2/(1+r))*1.25], 'r--');

% Unconstrained Optimal Point
scatter(c1_opti, c2_opti, 250, 'k', 'd');
plot(linspace(0,c1_opti,10),ones(10,1) * c2_opti, 'k--', 'HandleVisibility','off');
plot(ones(10,1) * c1_opti, linspace(0,c2_opti,10), 'k--', 'HandleVisibility','off');

% Constrained Lines
scatter(c1_b_grid, c2_b_grid, 100, 'k', 'filled', 'c');
fplot(f_budget_grid_constrained, [0, (z1 + z2/(1+r))*1.25], 'b-');
fplot(f_indiff_grid_constrained, [0, (z1 + z2/(1+r))*1.25], 'r-');

% Constrained Optimal Choice
scatter(c1_opti_grid, c2_opti_grid, 250, 'r', 'd');

% Labeling
ylim([0, (z1 + z2/(1+r))*1.25])
title({[num2str(Wealth_loss_percent) '% Wealth Loss Due to Discretization'],...
       ['B Grid Gap = ' num2str(b_grid_gap)...
        ', beta = ' num2str(beta)...
        ', r = ' num2str(r)],...            
       ['z1 = ' num2str(z1),...
        ', z2 = ' num2str(z2)],...
       ['Unconstrained: C1*= ' num2str(c1_opti)...
        ', C2*=' num2str(c2_opti)...
        ', B*=' num2str(b_opti)],...
       ['Constrained: C1*= ' num2str(c1_opti_grid)...
        ', C2*=' num2str(c2_opti_grid),...
        ', B*=' num2str(b_opti_grid_constrained)]});     
xlabel('consumption today');
ylabel('consumption tomorrow');
legend({'Endowment',...
        'Complete Budget',...
        'Complete Optimal Value',...
        'Complete Optimal Choice',...
        'B-Grid Choice Set',...
        'B-Grid Exp. Min. Budget',...
        'B-Grid Optimal Value',...
        'B-Grid Optimal Choice'...
        })
grid on;
%% Grid Constrained Borrowing Choice Set at Four Wealth Levels
% In these two period models, wealth is $z_1\cdot (1+r) + z_2$. Generally, holding 
% the ratio of $z_1$ and $z_2$ fixed, with the same borrowing grid-gap, higher 
% wealth households will lose less Wealth due to discretization.
% 
% Intuitively, if the borrowing grid allows for borrowing 1, 2 and 3 units. 
% Poorer households whose optimal borrowing quantity is 0.25 unit will suffer 
% greater Wealth loss due to discretization than a household whose optimal borrowing 
% quantity is 2.5. But the relationship is not monotonic, depending on wealth, 
% it could be that your borrowing need at some point is exactly on the grid. (See 
% chart below)
% 
% Using the same structure as above, now we do the exercise many times and 
% graph results for four different wealth levels and compare Wealth losses due 
% to discretization.
% 
% * Now I set $\beta = 0.95$, and also $r=0.05$
% * Borrow grid gap is still: $0.6$
% * Shift Overall Wealth level: $z_1\cdot (1+r) + z_2$, from equal to the borrow 
% grid gap to six times the borrow grid gap.
%%
% There is a grid of b choices
b_grid_gap = 0.6;
beta = 0.95;
r = 0.05;
z1_share = 0.15;
z2_share = 1 - z1_share;

% Wealth Grid
wealth_grid_min = b_grid_gap;
wealth_grid_max = b_grid_gap*6;
wealth_grid_n = 500;
wealth_grid = linspace(wealth_grid_min, wealth_grid_max, wealth_grid_n);
wealth_grid_graph = [1 round(wealth_grid_n/3) round((wealth_grid_n)*2/3) wealth_grid_n];

% Store Wealth Loss Along Grid
Wealth_loss_percent_grid = zeros(size(wealth_grid));
% Store Wealth Loss Along Grid
opti_borrow_exct = zeros(size(wealth_grid));
opti_borrow_grid = zeros(size(wealth_grid));

% Graphing
for wealth_i=1:1:length(wealth_grid)
    
    % Numbers
    z1 = z1_share * wealth_grid(wealth_i);
    z2 = z2_share * wealth_grid(wealth_i);
    
    % Symbols
    syms b
    
    % Utility
    Utility = log(z1-b) + beta*log(z2+b*(1+r));
    
    % Optimal Choice
    b_opti = double(solve(diff(Utility, b)==0, b, 'Real', true));
    c1_opti = z1 - b_opti;
    c2_opti = z2 + b_opti*(1+r);
    
    % Value (Utility at Optimal Choices)
    U_at_b_opti = subs(Utility, {b}, {b_opti});    
        
    % This is the max natural borrowing constraint
    b_max_borrow = z2/(1+r); 
    % The is the choice Grid
    b_grid = (-1)*(0:b_grid_gap:b_max_borrow);
    % r_grid = zeros(size(b_grid)) + r;
    r_grid = zeros(size(b_grid)) + r;
    c1_b_grid = z1 - b_grid;
    c2_b_grid = z2 + b_grid.*(1+r_grid);
    
    % Utility Along Choice Grid
    Utility_Grid = log(z1-b_grid) + beta*log(z2+b_grid.*(1+r_grid));
    
    % Optimal Choice
    [val_og, max_idx] = max(Utility_Grid);
    b_opti_grid_constrained = b_grid(max_idx);
    r_og = r_grid(max_idx);
    c1_opti_grid = z1 - b_opti_grid_constrained;
    c2_opti_grid = z2 + b_opti_grid_constrained*(1+r);
    
    % Solve a Expenditure Minimization Problem
    % Under what budget would the value at constrained optimal bundle 
    % be value for unconstrained problem?
    syms c1 c2 lambda
    lagrangian = (c2 + (1+r_og)*c1 - lambda*( log(c1) + beta*log(c2) - val_og));
    solu_min = solve(diff(lagrangian, c1)==0,...
                     diff(lagrangian, c2)==0,...
                     diff(lagrangian, lambda)==0,...
                     c1, c2, lambda, 'Real', true);
    solu_min_c1 = double(solu_min.c1);
    solu_min_c2 = double(solu_min.c2);
    Wealth_grid = solu_min_c1*(1+r_og) + solu_min_c2;
    Wealth_loss = 1- (Wealth_grid/(z1*(1+r_og) + z2));
    Wealth_loss_percent = round(Wealth_loss*10000)/100;
    
    % Store Results
    Wealth_loss_percent_grid(wealth_i) = Wealth_loss_percent;
    opti_borrow_exct(wealth_i) = b_opti;
    opti_borrow_grid(wealth_i) = b_opti_grid_constrained;
    
    % Graph Budget and Indiff for a Subset
    if (ismember(wealth_i, wealth_grid_graph))
        
        % Subplotting
%         subplot(2,2,find(graph_grid==wealth_i));
        figure();
        hold on;        
        
        % Define Budget Line and Indifference Curve
        syms c1
        % The Budget Line
        f_budget = z1*(1+r) + z2 - c1*(1+r);
        % Indifference at V*
        f_indiff = exp((U_at_b_opti-log(c1))/(beta));
        
        % The grid constrained value's unconstrained optimal budget line
        f_budget_grid_constrained = solu_min_c1*(1+r_og) + solu_min_c2 - c1*(1+r_og);
        % Indifference for grid constrained value
        f_indiff_grid_constrained = exp((val_og-log(c1))/(beta));
            
        % Endowment Point
        scatter(z1, z2, 250, 'k', 's');
        plot(linspace(0,z1,10),ones(10,1) * z2, 'k--', 'HandleVisibility','off');
        plot(ones(10,1) * z1, linspace(0,z2,10), 'k--', 'HandleVisibility','off');
        
        % Unconstrained Lines now Dashed
        fplot(f_budget, [0, (z1 + z2/(1+r))*1.25], 'b--');
        fplot(f_indiff, [0, (z1 + z2/(1+r))*1.25], 'r--');
        
        % Unconstrained Optimal Point
        scatter(c1_opti, c2_opti, 250, 'k', 'd');
        plot(linspace(0,c1_opti,10),ones(10,1) * c2_opti, 'k--', 'HandleVisibility','off');
        plot(ones(10,1) * c1_opti, linspace(0,c2_opti,10), 'k--', 'HandleVisibility','off');
        
        % Constrained Lines
        scatter(c1_b_grid, c2_b_grid, 100, 'k', 'filled', 'c');
        fplot(f_budget_grid_constrained, [0, (z1 + z2/(1+r))*1.25], 'b-');
        fplot(f_indiff_grid_constrained, [0, (z1 + z2/(1+r))*1.25], 'r-');
        
        % Constrained Optimal Choice
        scatter(c1_opti_grid, c2_opti_grid, 250, 'r', 'd');
        
        % Y and X lim
        ylim([0, (z1 + z2/(1+r))*1.25])
        
        % Labeling
        title({[num2str(Wealth_loss_percent) '% Wealth Loss Due to Discretization'],...
               ['B Grid Gap = ' num2str(b_grid_gap)...
                ', beta = ' num2str(beta)...
                ', r = ' num2str(r)],...            
               ['W = ' num2str(wealth_grid(wealth_i))...
                ', z1 = ' num2str(z1),...
                ', z2 = ' num2str(z2)],...
               ['Unconstrained: C1*= ' num2str(c1_opti)...
                ', C2*=' num2str(c2_opti)...
                ', B*=' num2str(b_opti)],...
               ['Constrained: C1*= ' num2str(c1_opti_grid)...
                ', C2*=' num2str(c2_opti_grid),...
                ', B*=' num2str(b_opti_grid_constrained)]});     
        xlabel('consumption today');
        ylabel('consumption tomorrow');
        legend({'Endowment',...
                'Complete Budget',...
                'Complete Optimal Value',...
                'Complete Optimal Choice',...
                'B-Grid Choice Set',...
                'B-Grid Exp. Min. Budget',...
                'B-Grid Optimal Value',...
                'B-Grid Optimal Choice'...
                });
        xlabel('c today');
        ylabel('c t+1');
        grid on;
    end
end
%% Shifting Wealth and Wealth Loss Due to Discretization
% Plot also based on stored results, given the parameters here, variations in 
% Wealth loss along the total 2 period wealth grid. Now I set $\beta = 0.95$, 
% and also $r=0.05$. It is important to note that the standard borrowing constraint 
% does not pick up the welfare/Wealth loss due to discretization. If in reality, 
% the formal borrowing choice set is limited, or at least have a minimum borrowing 
% requirement, this leads potentially to very significant welfare/Wealth loss 
% to households with low levels of optimal borrowing needs. 
%%
figure();
hold on;

% Left Axis Wealth Loss
yyaxis left
line(wealth_grid, Wealth_loss_percent_grid);
plot(wealth_grid, ones(size(wealth_grid)) * 0, 'k--');
ylim([-(max(Wealth_loss_percent_grid))/8 max(Wealth_loss_percent_grid)*9/8]);
xlim([wealth_grid_min wealth_grid_max]);

title({['% Wealth Loss to Borrowing Grid Discretization'],...
       ['B Grid Gap = ' num2str(b_grid_gap) ...
        ', beta = ' num2str(beta) ', r = ' num2str(r) ' '],...
       ['z1 Wealth share = ' num2str(z1_share) ...
        ', z2 Wealth share = ' num2str(z2_share)]})
xlabel('wealth = z1*(1+r) + z2 ');
ylabel({['Wealth Loss Percentage'],...
        ['Computed From Expenditure Minimization'],...
        ['Given Value at Optimal Constrained-Discrete Choice'],...
        ['Compare to Value at Optimal Un-Constrained Choice']});
grid on;
grid minor;

% Right Axis Optimal Choices
yyaxis right
line(wealth_grid, (-1)*opti_borrow_grid);
ylim([-(-1*min(opti_borrow_grid))/8 (-1*(min(opti_borrow_grid)+min(opti_borrow_grid)/8))]);
xlim([wealth_grid_min wealth_grid_max]);
ylabel({['Optimal Discrete Grid Borrowing Choices * (-1)']});
%% 
%