Skip to content

Commit

Permalink
Add vFunc capability to simplified portfolio solver
Browse files Browse the repository at this point in the history
Have not tested fixed share functionality, but I expect it works.
  • Loading branch information
mnwhite committed Mar 8, 2024
1 parent 747eeab commit 45d645c
Showing 1 changed file with 86 additions and 2 deletions.
88 changes: 86 additions & 2 deletions HARK/ConsumptionSaving/ConsPortfolioModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,92 @@ def EndOfPrddvds_dist(S, a, z):

# Add the value function if requested TODO
if vFuncBool:

Check warning on line 681 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L681

Added line #L681 was not covered by tests
vFuncAdj_now = NullFunc()
vFuncFxd_now = NullFunc()
# Create the value functions for this period, defined over market resources
# mNrm when agent can adjust his portfolio, and over market resources and
# fixed share when agent can not adjust his portfolio.

def calc_v_intermed(S, b, z):

Check warning on line 686 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L686

Added line #L686 was not covered by tests
'''
Calculate "intermediate" value from next period's bank balances, the
income shocks S, and the risky asset share.
'''
mNrm_next = calc_mNrm_next(S, b)

Check warning on line 691 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L691

Added line #L691 was not covered by tests

vAdj_next = vFuncAdj_next(mNrm_next)
if AdjustPrb < 1.0:
vFxd_next = vFuncFxd_next(mNrm_next, z)

Check warning on line 695 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L693-L695

Added lines #L693 - L695 were not covered by tests
# Combine by adjustment probability
v_next = AdjustPrb * vAdj_next + (1.0 - AdjustPrb) * vFxd_next

Check warning on line 697 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L697

Added line #L697 was not covered by tests
else: # Don't bother evaluating if there's no chance that portfolio share is fixed
v_next = vAdj_next

Check warning on line 699 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L699

Added line #L699 was not covered by tests

v_intermed = (S["PermShk"] * PermGroFac) ** (1.0 - CRRA) * v_next
return v_intermed

Check warning on line 702 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L701-L702

Added lines #L701 - L702 were not covered by tests

# Calculate intermediate value by taking expectations over income shocks
v_intermed = expected(calc_v_intermed, IncShkDstn, args=(bNrmNext, ShareNext))

Check warning on line 705 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L705

Added line #L705 was not covered by tests

# Construct the "intermediate value function" for this period
vNvrs_intermed = uFunc.inv(v_intermed)
vNvrsFunc_intermed = BilinearInterp(vNvrs_intermed, bNrmGrid, ShareGrid)
vFunc_intermed = ValueFuncCRRA(vNvrsFunc_intermed, CRRA)

Check warning on line 710 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L708-L710

Added lines #L708 - L710 were not covered by tests

def calc_EndOfPrd_v(S, a, z):

Check warning on line 712 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L712

Added line #L712 was not covered by tests
# Calculate future realizations of bank balances bNrm
Rxs = S - Rfree
Rport = Rfree + z * Rxs
bNrm_next = Rport * a

Check warning on line 716 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L714-L716

Added lines #L714 - L716 were not covered by tests

# Make an extended share_next of the same dimension as b_nrm so
# that the function can be vectorized
z_rep = z + np.zeros_like(bNrm_next)

Check warning on line 720 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L720

Added line #L720 was not covered by tests

EndOfPrd_v = vFunc_intermed(bNrm_next, z_rep)
return EndOfPrd_v

Check warning on line 723 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L722-L723

Added lines #L722 - L723 were not covered by tests

# Calculate end-of-period value by taking expectations
EndOfPrd_v = DiscFacEff * expected(calc_EndOfPrd_v, RiskyDstn, args=(aNrmNow, ShareNext))
EndOfPrd_vNvrs = uFunc.inv(EndOfPrd_v)

Check warning on line 727 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L726-L727

Added lines #L726 - L727 were not covered by tests

# Now make an end-of-period value function over aNrm and Share
EndOfPrd_vNvrsFunc = BilinearInterp(EndOfPrd_vNvrs, aNrmGrid, ShareGrid)
EndOfPrd_vFunc = ValueFuncCRRA(EndOfPrd_vNvrsFunc, CRRA)

Check warning on line 731 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L730-L731

Added lines #L730 - L731 were not covered by tests

# Construct the value function when the agent can adjust his portfolio
mNrm_temp = aXtraGrid # Just use aXtraGrid as our grid of mNrm values
cNrm_temp = cFuncAdj_now(mNrm_temp)
aNrm_temp = mNrm_temp - cNrm_temp
Share_temp = ShareFuncAdj_now(mNrm_temp)
v_temp = uFunc(cNrm_temp) + EndOfPrd_vFunc(aNrm_temp, Share_temp)
vNvrs_temp = uFunc.inv(v_temp)
vNvrsP_temp = uFunc.der(cNrm_temp) * uFunc.inverse(v_temp, order=(0, 1))
vNvrsFuncAdj = CubicInterp(

Check warning on line 741 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L734-L741

Added lines #L734 - L741 were not covered by tests
np.insert(mNrm_temp, 0, 0.0), # x_list
np.insert(vNvrs_temp, 0, 0.0), # f_list
np.insert(vNvrsP_temp, 0, vNvrsP_temp[0]), # dfdx_list
)
# Re-curve the pseudo-inverse value function
vFuncAdj_now = ValueFuncCRRA(vNvrsFuncAdj, CRRA)

Check warning on line 747 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L747

Added line #L747 was not covered by tests

# Construct the value function when the agent *can't* adjust his portfolio
mNrm_temp, Share_temp = np.meshgrid(aXtraGrid, ShareGrid)
cNrm_temp = cFuncFxd_now(mNrm_temp, Share_temp)
aNrm_temp = mNrm_temp - cNrm_temp
v_temp = uFunc(cNrm_temp) + EndOfPrd_vFunc(aNrm_temp, Share_temp)
vNvrs_temp = uFunc.inv(v_temp)
vNvrsP_temp = uFunc.der(cNrm_temp) * uFunc.inverse(v_temp, order=(0, 1))
vNvrsFuncFxd_by_Share = []
for j in range(ShareCount):
vNvrsFuncFxd_by_Share.append(

Check warning on line 758 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L750-L758

Added lines #L750 - L758 were not covered by tests
CubicInterp(
np.insert(mNrm_temp[:, 0], 0, 0.0), # x_list
np.insert(vNvrs_temp[:, j], 0, 0.0), # f_list
np.insert(vNvrsP_temp[:, j], 0, vNvrsP_temp[j, 0]), # dfdx_list
)
)
vNvrsFuncFxd = LinearInterpOnInterp1D(vNvrsFuncFxd_by_Share, ShareGrid)
vFuncFxd_now = ValueFuncCRRA(vNvrsFuncFxd, CRRA)

Check warning on line 766 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L765-L766

Added lines #L765 - L766 were not covered by tests

else: # If vFuncBool is False, fill in dummy values
vFuncAdj_now = NullFunc()
vFuncFxd_now = NullFunc()

Check warning on line 770 in HARK/ConsumptionSaving/ConsPortfolioModel.py

View check run for this annotation

Codecov / codecov/patch

HARK/ConsumptionSaving/ConsPortfolioModel.py#L769-L770

Added lines #L769 - L770 were not covered by tests
Expand Down

0 comments on commit 45d645c

Please sign in to comment.