Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: BARK: Bellman Abstract Representation toolKit. #1186

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
618f282
notebook demonstrating new Bellman stage code
sbenthall Oct 4, 2022
50674bc
computing v_x by taking expectations over shocks
sbenthall Oct 10, 2022
f90ca9e
progress on Bellman Stages
sbenthall Oct 11, 2022
d302703
cleaner Bellman stage implementation
sbenthall Oct 21, 2022
655e5f0
putting stage code in the right places to prep PR
sbenthall Nov 8, 2022
055e05f
changes for Python 3.8 compatibility: collections.abd -> typing
sbenthall Nov 9, 2022
80dedbe
adding action upper and lower bounds
sbenthall Nov 15, 2022
469760f
Can now pass optimizer arguments through solve() and when initializin…
sbenthall Nov 15, 2022
5ad039b
BellmanStages example update -- still WIP but shows different optimiz…
sbenthall Nov 15, 2022
a819962
Allow a Stage to take a value transform (for decurved interpolation) …
sbenthall Nov 18, 2022
23a83f0
working implementation of pi* points given to a Stage; improved notebook
sbenthall Nov 22, 2022
031f403
fixes to tests
sbenthall Nov 22, 2022
bcb0e2a
fixing Callable[float,float] to Callable[[float],float] for 3.8
sbenthall Nov 22, 2022
4f7591f
tuple[...] to Tuple[...] for type annotation in 3.8
sbenthall Nov 22, 2022
d99e0ec
adding forward simulation on a Stage,
sbenthall Nov 23, 2022
ff61eb3
allow None to be passed in to pi_star_points
sbenthall Nov 28, 2022
c7c015b
stages now take 'solution_points' which can determine both pi* and/or…
sbenthall Nov 29, 2022
d662ae5
Updating Notebook. Using solution_points. Risky Growth and Income Gro…
sbenthall Nov 29, 2022
d002763
Edits to BellmanStages notebook
sbenthall Dec 5, 2022
9e3b7b8
using marginal output value function and FOC to compute optimal policy
sbenthall Dec 7, 2022
566462f
optimal_polixy_foc; abstracting out solve to solve_v_x and helper met…
sbenthall Dec 13, 2022
53d7a76
finalized marginal value update; some example and analysis in the not…
sbenthall Dec 13, 2022
4cb53dd
endogeneous grid point compuation of optimal policy
sbenthall Dec 14, 2022
9a1015d
improving exposition of policy optimization vs. value updating, and n…
sbenthall Dec 15, 2022
a4d1a92
reworking stage.py; optimal_policy_foc now returns y_data; new solvin…
sbenthall Dec 20, 2022
11c21d5
more work on optimal_policy_egm
sbenthall Dec 21, 2022
40cbe3a
pi* solution points now added to optimal policy in optimal_policy_egm
sbenthall Dec 28, 2022
cca3241
notebook has previous commit added -- egm optimal policy has solution…
sbenthall Dec 28, 2022
6eead18
analytic_pi_star_y; transition_der can be constant; generalizes egm m…
sbenthall Dec 28, 2022
839f589
analytic marginal value
sbenthall Jan 5, 2023
27346c5
portfolio consumption stages to standalone file; working marginal val…
sbenthall Jan 5, 2023
47f2e2c
stage simulationd demo notebook
sbenthall Jan 5, 2023
ff2d66d
notebook with math for using Envelope Theorem to derive abstract stag…
sbenthall Jan 5, 2023
de38da4
solve_egm and backwards_induction takes a solver method
sbenthall Jan 12, 2023
966494c
consindshock with stages example
sbenthall Jan 12, 2023
3c57a6e
Adapting SolvingMicroDSOPs notebook update
sbenthall Jan 12, 2023
bab0185
allow transforms on v_der; some additional notes in the notebooks
sbenthall Feb 7, 2023
6cdb7da
additional materials documentating BARK
sbenthall May 8, 2023
896d612
Merge branch 'master' into stages
sbenthall May 15, 2023
9b996e3
HARK BARK Lifecycle test start
sbenthall May 15, 2023
129aab1
updates to keep up with HARK changes
sbenthall May 17, 2023
0b19562
notebook updates: notes on BellmanStages document; composition API sp…
sbenthall May 17, 2023
5872010
improvements ot HARK/BARK test; pass v_der_transform to terminal and …
sbenthall May 23, 2023
fd996d2
fix tests
sbenthall May 24, 2023
8fd0909
using inverse marginal utility for marginal value transform on all st…
sbenthall May 24, 2023
33aa13e
updates the HARK/BARK notebook test
sbenthall May 24, 2023
816c020
clean up BellmanStages notebooks
sbenthall May 24, 2023
5aa1d97
HARK / BARK update/fixes
sbenthall May 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,238 changes: 1,238 additions & 0 deletions HARK/stage.py

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions HARK/tests/test_stage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
"""
This file implements unit tests for abstract Bellman stage code.
"""

from typing import Any, Mapping
import HARK.distribution as distribution
from HARK.rewards import CRRAutility
from HARK.stage import Stage, simulate_stage
import unittest

CRRA = 5

R = 1.01
G = 1.02

sigma_psi = 1.05
sigma_theta = 1.15
sigma_eta = 1.1
p_live = 0.98

# Replace this when CRRAutility can handle 0 as an input.
CRRAutility_hack = lambda u, gam: float('-inf') if u == 0.0 else CRRAutility(u, gam)

class testPortfolioConsumptionStages(unittest.TestCase):
def setUp(self):

self.consumption_stage = Stage(
transition = lambda x, k, a : {'a' : x['m'] - a['c']},
reward = lambda x, k, a : CRRAutility_hack(a['c'], CRRA),
inputs = ['m'],
actions = ['c'],
outputs = ['a'],
action_upper_bound = lambda x, k: (x['m'],) ,
action_lower_bound = lambda x, k: (0,) ,
discount = .96, # lambda x, k, a : .96 * k['psi']^(1 - CRRA) < ---
optimizer_args = {
'method' : 'Nelder-Mead',
'options' : {
'maxiter': 75000,
}
},
)

self.allocation_stage = Stage(
transition = lambda x, k, a : {'a' : x['a'], 'alpha' : a['alpha']},
inputs = ['a'],
actions = ['alpha'],
outputs = ['a', 'alpha'],
constraints = [
lambda x, k, a: 1 - a['alpha'],
lambda x, k, a: a['alpha']
]
)

def growth_transition(x, k, a):
return {'m' : ((x['alpha'] * k['eta'] + (1 - x['alpha']) * R)
* x['a'] + k['theta'])
/ (k['psi'] * G)}

self.growth_stage = Stage(
transition = growth_transition,
inputs = ['a', 'alpha'],
discount = lambda x, k, a: p_live * k['psi'] ** (1 - CRRA),
shocks = {
'psi' : distribution.Lognormal(0, sigma_psi),
'theta' : distribution.Lognormal(0, sigma_theta),
'eta' : distribution.Lognormal(0, sigma_eta),
# 'live' : distribution.Bernoulli(p_live) ## Not implemented for now
},
outputs = ['m'],
)

def test_consumption_stage(self):

def consumption_v_y(y : Mapping[str,Any]):
return CRRAutility_hack(y['a'], CRRA) - 1

pi_star, q = self.consumption_stage.optimal_policy(
{'m' : [1, 3, 6, 12, 20, 26]},
v_y = consumption_v_y
)

# q function has proper coords
assert q.coords['m'][4].data.tolist() == 20

# Consume over half the resources
assert (pi_star[5]).data.tolist() > 13

assert self.consumption_stage.T({'m' : 100}, {}, {'c' : 50})['a'] == 50

assert self.consumption_stage.T({'m' : 100}, {}, {'c' : 101})['a'] == -1

assert self.consumption_stage.reward({'m' : 100}, {}, {'c' : 50}) < 0.00001

assert self.consumption_stage.q({'m' : 100}, {}, {'c' : 50}, v_y = consumption_v_y) < 0.000001

c_sol = self.consumption_stage.solve(
{'m' : [0, 50, 100, 1000]},
{},
{},
consumption_v_y
)

# simulate forward
simulate_stage(self.consumption_stage, {'m' : 5}, c_sol.pi_star)

def test_allocation_stage(self):

def allocation_v_y(y : Mapping[str,Any]):
return CRRAutility(y['alpha'] * y['a'] + 1,CRRA) \
+ CRRAutility((1 - y['alpha']) * y['a'] + 1, CRRA * 0.9)

assert self.allocation_stage.T({'a': 100}, {}, {'alpha' : 0.5})['a'] == 100

assert self.allocation_stage.reward({'a': 100}, {}, {'alpha' : 0.5}) == 0

# smoke tests
pi_star, q = self.allocation_stage.optimal_policy(
{'a' : [9, 11, 20, 300, 4000, 5500]},
v_y = allocation_v_y
)

a_sol = self.allocation_stage.solve(
{'a' : [0, 50, 100, 1000]},
{},
{},
allocation_v_y
)

def test_growth_stage(self):

assert self.growth_stage.T(
{'a': 100, 'alpha' : 0.5},
{'psi' : 1.00, 'theta' : 1.10, 'eta' : 1.05, 'live' : 1},
{}
)['m'] == 102.05882352941175

def growth_v_y(y : Mapping[str,Any]):
return CRRAutility(y['m'], CRRA)

pi_star, q = self.growth_stage.optimal_policy(
{'a' : [300, 600],
'alpha' : [0, 1.0]
},
{'psi' : [1., 1.1],
'theta' : [1., 1.1],
'eta' : [1., 1.1],
# 'live' : [0, 1]
},
v_y = growth_v_y)

q

g_sol = self.growth_stage.solve(
{'a' : [0, 500, 1000], 'alpha' : [0, 0.5, 1.0]},
{},
{
'psi' : 4,
'theta' : 4,
'eta' : 4,
# 'live' : [0, 1]
}, growth_v_y)

# simulate forward
simulate_stage(
self.growth_stage,
{'a' : 5, 'alpha' : 0.5},
lambda x, k : None
)
59 changes: 59 additions & 0 deletions examples/BellmanStages/BARK Composition API.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5348411a",
"metadata": {},
"source": [
"Beyond individual blocks,\n",
"\n",
"blocks can be composed into problems.\n",
"\n",
"The Chomskyian grammar and discussion of ticks, etc. go here."
]
},
{
"cell_type": "markdown",
"id": "6ced94e2",
"metadata": {},
"source": [
"\n",
"**Scoping parameters**\n",
"\n",
"You can share parameters within a tick,\n",
"but not across ticks.\n",
"\n",
"Parameters may be shared between stages."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c283c342",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "hark-env",
"language": "python",
"name": "hark-env"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading