Skip to content

Commit

Permalink
Merge branch 'master' into i1105
Browse files Browse the repository at this point in the history
  • Loading branch information
sbenthall authored Sep 21, 2022
2 parents fad1a26 + b6a3907 commit 3371efd
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 90 deletions.
1 change: 1 addition & 0 deletions Documentation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Release Date: TBD
* Adds `HARK.distribution.expected` alias for `DiscreteDistribution.expected`. [#1156](https://github.com/econ-ark/HARK/pull/1156)
* Renames attributes in `DiscreteDistribution`: `X` to `atoms` and `pmf` to `pmv`. [#1164](https://github.com/econ-ark/HARK/pull/1164), [#1051](https://github.com/econ-ark/HARK/pull/1151), [#1159](https://github.com/econ-ark/HARK/pull/1159).
* Remove or replace automated tests that depend on brittle simulation results. [#1148](https://github.com/econ-ark/HARK/pull/1148)
* Updates asset grid constructor from `ConsIndShockModel.py` to allow for linearly-spaced grids when `aXtraNestFac == -1`. [#1172](https://github.com/econ-ark/HARK/pull/1172)

### 0.12.0

Expand Down
67 changes: 2 additions & 65 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
from HARK.datasets.SCF.WealthIncomeDist.SCFDistTools import income_wealth_dists_from_scf
from HARK.distribution import (
DiscreteDistribution,
expected,
IndexDistribution,
Lognormal,
MeanOneLogNormal,
Uniform,
add_discrete_outcome_constant_mean,
combine_indep_dstns,
expected,
)
from HARK.interpolation import CubicHermiteInterp as CubicInterp
from HARK.interpolation import (
Expand All @@ -57,7 +57,7 @@
CRRAutilityP_inv,
CRRAutilityP_invP,
CRRAutilityPP,
make_grid_exp_mult,
construct_assets_grid,
)
from scipy.optimize import newton

Expand Down Expand Up @@ -3178,69 +3178,6 @@ def apply_flat_income_tax(
return IncShkDstn_new


# =======================================================
# ================ Other useful functions ===============
# =======================================================


def construct_assets_grid(parameters):
"""
Constructs the base grid of post-decision states, representing end-of-period
assets above the absolute minimum.
All parameters are passed as attributes of the single input parameters. The
input can be an instance of a ConsumerType, or a custom Parameters class.
Parameters
----------
aXtraMin: float
Minimum value for the a-grid
aXtraMax: float
Maximum value for the a-grid
aXtraCount: int
Size of the a-grid
aXtraExtra: [float]
Extra values for the a-grid.
exp_nest: int
Level of nesting for the exponentially spaced grid
Returns
-------
aXtraGrid: np.ndarray
Base array of values for the post-decision-state grid.
"""
# Unpack the parameters
aXtraMin = parameters.aXtraMin
aXtraMax = parameters.aXtraMax
aXtraCount = parameters.aXtraCount
aXtraExtra = parameters.aXtraExtra
grid_type = "exp_mult"
exp_nest = parameters.aXtraNestFac

# Set up post decision state grid:
aXtraGrid = None
if grid_type == "linear":
aXtraGrid = np.linspace(aXtraMin, aXtraMax, aXtraCount)
elif grid_type == "exp_mult":
aXtraGrid = make_grid_exp_mult(
ming=aXtraMin, maxg=aXtraMax, ng=aXtraCount, timestonest=exp_nest
)
else:
raise Exception(
"grid_type not recognized in __init__."
+ "Please ensure grid_type is 'linear' or 'exp_mult'"
)

# Add in additional points for the grid:
for a in aXtraExtra:
if a is not None:
if a not in aXtraGrid:
j = aXtraGrid.searchsorted(a)
aXtraGrid = np.insert(aXtraGrid, j, a)

return aXtraGrid


# Make a dictionary to specify a lifecycle consumer with a finite horizon

# Main calibration characteristics
Expand Down
24 changes: 22 additions & 2 deletions HARK/tests/test_HARKutilities.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""
This file implements unit tests to check HARK/utilities.py
"""
import HARK.utilities

# Bring in modules we need
import unittest
from types import SimpleNamespace

import HARK.utilities
import numpy as np


Expand Down Expand Up @@ -64,3 +65,22 @@ def test_CRRAutilityPPPP(self):
self.derivative_func_comparison(
HARK.utilities.CRRAutilityPPPP, HARK.utilities.CRRAutilityPPP
)

def test_asset_grid(self):
# test linear asset grid

params = {
"aXtraMin": 0.0,
"aXtraMax": 1.0,
"aXtraCount": 5,
"aXtraExtra": [None],
"aXtraNestFac": -1,
}

params = SimpleNamespace(**params)

aXtraGrid = HARK.utilities.construct_assets_grid(params)

test = np.unique(np.diff(aXtraGrid).round(decimals=3))

self.assertEqual(test.size, 1)
108 changes: 85 additions & 23 deletions HARK/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import cProfile
import functools
import pstats
import warnings

import numpy as np # Python's numeric library, abbreviated "np"

Expand All @@ -16,17 +17,16 @@
# exception_type, value, traceback = sys.exc_info()
# raise ImportError('HARK must be used in a graphical environment.', exception_type, value, traceback)
from scipy.interpolate import interp1d
import warnings


def memoize(obj):
"""
A decorator to (potentially) make functions more efficient.
A decorator to (potentially) make functions more efficient.
With this decorator, functions will "remember" if they have been evaluated with given inputs
before. If they have, they will "remember" the outputs that have already been calculated
for those inputs, rather than calculating them again.
"""
With this decorator, functions will "remember" if they have been evaluated with given inputs
before. If they have, they will "remember" the outputs that have already been calculated
for those inputs, rather than calculating them again.
"""
cache = obj._cache = {}

@functools.wraps(obj)
Expand Down Expand Up @@ -143,8 +143,8 @@ def CRRAutility(c, gam):

def uFunc_CRRA_stone_geary(c, CRRA, stone_geary):
"""
Evaluates Stone-Geary version of a constant relative risk aversion (CRRA)
utility of consumption c wiht given risk aversion parameter CRRA and
Evaluates Stone-Geary version of a constant relative risk aversion (CRRA)
utility of consumption c wiht given risk aversion parameter CRRA and
Stone-Geary intercept parameter stone_geary
Parameters
Expand All @@ -154,7 +154,7 @@ def uFunc_CRRA_stone_geary(c, CRRA, stone_geary):
CRRA : float
Relative risk aversion
stone_geary : float
Intercept in Stone-Geary utility
Intercept in Stone-Geary utility
Returns
-------
(unnamed) : float
Expand All @@ -163,7 +163,7 @@ def uFunc_CRRA_stone_geary(c, CRRA, stone_geary):
Tests
-----
Test a value which should pass:
>>> c, CRRA, stone_geary = 1.0, 2.0, 0.0
>>> c, CRRA, stone_geary = 1.0, 2.0, 0.0
>>> utility(c=c, CRRA=CRRA, stone_geary=stone_geary )
-1.0
"""
Expand All @@ -175,8 +175,8 @@ def uFunc_CRRA_stone_geary(c, CRRA, stone_geary):

def uPFunc_CRRA_stone_geary(c, CRRA, stone_geary):
"""
Marginal utility of Stone-Geary version of a constant relative risk aversion (CRRA)
utility of consumption c wiht given risk aversion parameter CRRA and
Marginal utility of Stone-Geary version of a constant relative risk aversion (CRRA)
utility of consumption c wiht given risk aversion parameter CRRA and
Stone-Geary intercept parameter stone_geary
Parameters
Expand All @@ -186,7 +186,7 @@ def uPFunc_CRRA_stone_geary(c, CRRA, stone_geary):
CRRA : float
Relative risk aversion
stone_geary : float
Intercept in Stone-Geary utility
Intercept in Stone-Geary utility
Returns
-------
(unnamed) : float
Expand All @@ -198,7 +198,7 @@ def uPFunc_CRRA_stone_geary(c, CRRA, stone_geary):

def uPPFunc_CRRA_stone_geary(c, CRRA, stone_geary):
"""
Marginal marginal utility of Stone-Geary version of a CRRA utilty function
Marginal marginal utility of Stone-Geary version of a CRRA utilty function
with risk aversion parameter CRRA and Stone-Geary intercept parameter stone_geary
Parameters
Expand All @@ -208,7 +208,7 @@ def uPPFunc_CRRA_stone_geary(c, CRRA, stone_geary):
CRRA : float
Relative risk aversion
stone_geary : float
Intercept in Stone-Geary utility
Intercept in Stone-Geary utility
Returns
-------
(unnamed) : float
Expand Down Expand Up @@ -239,7 +239,7 @@ def CRRAutilityP(c, gam):
if gam == 1:
return 1 / c

return c ** -gam
return c**-gam


def CRRAutilityPP(c, gam):
Expand Down Expand Up @@ -468,7 +468,7 @@ def CARAutilityPPP(c, alpha):
(unnamed): float
Marginal marginal marginal utility
"""
return alpha ** 2.0 * np.exp(-alpha * c)
return alpha**2.0 * np.exp(-alpha * c)


def CARAutility_inv(u, alpha):
Expand Down Expand Up @@ -531,6 +531,67 @@ def CARAutility_invP(u, alpha):
return 1.0 / (alpha * (1.0 - u))


# =======================================================
# ================ Other useful functions ===============
# =======================================================


def construct_assets_grid(parameters):
"""
Constructs the base grid of post-decision states, representing end-of-period
assets above the absolute minimum.
All parameters are passed as attributes of the single input parameters. The
input can be an instance of a ConsumerType, or a custom Parameters class.
Parameters
----------
aXtraMin: float
Minimum value for the a-grid
aXtraMax: float
Maximum value for the a-grid
aXtraCount: int
Size of the a-grid
aXtraExtra: [float]
Extra values for the a-grid.
exp_nest: int
Level of nesting for the exponentially spaced grid.
If -1, the grid is linearly spaced.
Returns
-------
aXtraGrid: np.ndarray
Base array of values for the post-decision-state grid.
"""
# Unpack the parameters
aXtraMin = parameters.aXtraMin
aXtraMax = parameters.aXtraMax
aXtraCount = parameters.aXtraCount
aXtraExtra = parameters.aXtraExtra
exp_nest = parameters.aXtraNestFac

# Set up post decision state grid:
if exp_nest == -1:
aXtraGrid = np.linspace(aXtraMin, aXtraMax, aXtraCount)
elif exp_nest >= 0:
aXtraGrid = make_grid_exp_mult(
ming=aXtraMin, maxg=aXtraMax, ng=aXtraCount, timestonest=exp_nest
)
else:
raise ValueError(
"aXtraNestFac not recognized in __init__."
+ "Please ensure aXtraNestFac is either -1 or a positive integer."
)

# Add in additional points for the grid:
for a in aXtraExtra:
if a is not None and a not in aXtraGrid:
j = aXtraGrid.searchsorted(a)
aXtraGrid = np.insert(aXtraGrid, j, a)

return aXtraGrid


# ==============================================================================
# ============== Functions for generating state space grids ===================
# ==============================================================================
Expand Down Expand Up @@ -916,7 +977,7 @@ def plot_funcs_der(functions, bottom, top, N=1000, legend_kwds=None):


def determine_platform():
""" Untility function to return the platform currenlty in use.
"""Untility function to return the platform currenlty in use.
Returns
---------
Expand All @@ -942,7 +1003,7 @@ def determine_platform():


def test_latex_installation(pf):
""" Test to check if latex is installed on the machine.
"""Test to check if latex is installed on the machine.
Parameters
-----------
Expand Down Expand Up @@ -988,7 +1049,7 @@ def test_latex_installation(pf):


def in_ipynb():
""" If the ipython process contains 'terminal' assume not in a notebook.
"""If the ipython process contains 'terminal' assume not in a notebook.
Returns
--------
Expand All @@ -1005,7 +1066,7 @@ def in_ipynb():


def setup_latex_env_notebook(pf, latexExists):
""" This is needed for use of the latex_envs notebook extension
"""This is needed for use of the latex_envs notebook extension
which allows the use of environments in Markdown.
Parameters
Expand All @@ -1014,6 +1075,7 @@ def setup_latex_env_notebook(pf, latexExists):
output of determine_platform()
"""
import os

import matplotlib.pyplot as plt

plt.rc("font", family="serif")
Expand Down Expand Up @@ -1047,7 +1109,7 @@ def setup_latex_env_notebook(pf, latexExists):


def make_figs(figure_name, saveFigs, drawFigs, target_dir="Figures"):
""" Utility function to save figure in multiple formats and display the image.
"""Utility function to save figure in multiple formats and display the image.
Parameters
----------
Expand Down Expand Up @@ -1091,7 +1153,7 @@ def make_figs(figure_name, saveFigs, drawFigs, target_dir="Figures"):


def find_gui():
""" Quick fix to check if matplotlib is running in a GUI environment.
"""Quick fix to check if matplotlib is running in a GUI environment.
Returns
-------
Expand Down

0 comments on commit 3371efd

Please sign in to comment.