Skip to content

Commit 041ed76

Browse files
committed
Simplify setting constructors at initialization
As is, setting a non-default constructor at instantiation is a little obnoxious, because the user has to deepcopy the constructor dictionary, change some entries, and then put the altered copy into their parameter dictionary. This commit makes it much easier to set non-default constructor functions at initialization. The user *only* needs to put entries into params["constructors"] for the constructors they want to change; the others will use their default. If the user wants to turn off a constructor with a default, they can set that entry to None.
1 parent a98e751 commit 041ed76

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

HARK/ConsumptionSaving/ConsWealthPortfolioModel.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ class ChiFromOmegaFunction:
3838
A class for representing a function that takes in values of omega = EndOfPrdvP / aNrm
3939
and returns the corresponding optimal chi = cNrm / aNrm. The only parameters
4040
that matter for this transformation are the coefficient of relative risk
41-
aversion rho and the share of wealth in the Cobb-Douglas aggregator delta.
41+
aversion (rho) and the share of wealth in the Cobb-Douglas aggregator (delta).
4242
4343
Parameters
4444
----------
45-
rho : float
45+
CRRA : float
4646
Coefficient of relative risk aversion.
47-
delta : float
47+
WealthShare : float
4848
Share for wealth in the Cobb-Douglas aggregator in CRRA utility function.
4949
N : int, optional
5050
Number of interpolating gridpoints to use (default 501).
@@ -65,10 +65,9 @@ def f(self, x):
6565
"""
6666
Define the relationship between chi and omega, and evaluate on the vector
6767
"""
68-
return x ** (1 - self.WealthShare) * (
69-
(1 - self.WealthShare) * x ** (-self.WealthShare)
70-
- self.WealthShare * x ** (1 - self.WealthShare)
71-
) ** (-1 / self.CRRA)
68+
r = self.CRRA
69+
d = self.WealthShare
70+
return x ** (1 - d) * ((1 - d) * x ** (-d) - d * x ** (1 - d)) ** (-1 / r)
7271

7372
def update(self):
7473
"""

HARK/core.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,12 @@ class AgentType(Model):
817817
Indicator for whether this instance's construct() method should be run
818818
when initialized (default True). When False, an instance of the class
819819
can be created even if not all of its attributes can be constructed.
820+
use_defaults : bool
821+
Indicator for whether this instance should use the values in the class'
822+
default_ dictionary to fill in parameters and constructors for those not
823+
provided by the user (default True). Setting this to False is useful for
824+
situations where the user wants to be absolutely sure that they know what
825+
is being passed to the class initializer, without resorting to defaults.
820826
821827
Attributes
822828
----------
@@ -844,11 +850,23 @@ def __init__(
844850
quiet=False,
845851
seed=0,
846852
construct=True,
853+
use_defaults=True,
847854
**kwds,
848855
):
849856
super().__init__()
850-
params = deepcopy(self.default_["params"])
857+
params = deepcopy(self.default_["params"]) if use_defaults else {}
851858
params.update(kwds)
859+
860+
# Correctly handle constructors that have been passed in kwds
861+
if "constructors" in self.default_["params"].keys() and use_defaults:
862+
constructors = deepcopy(self.default_["params"]["constructors"])
863+
else:
864+
constructors = {}
865+
if "constructors" in kwds.keys():
866+
constructors.update(kwds["constructors"])
867+
params["constructors"] = constructors
868+
869+
# Set model file name if possible
852870
try:
853871
self.model_file = copy(self.default_["model"])
854872
except (KeyError, TypeError):

tests/ConsumptionSaving/test_ConsMarkovModel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def setUp(self):
6464
init_serial_unemployment["Rfree"] = [np.array([1.03, 1.03, 1.03, 1.03])]
6565
init_serial_unemployment["LivPrb"] = [np.array([0.98, 0.98, 0.98, 0.98])]
6666
init_serial_unemployment["PermGroFac"] = [np.array([1.01, 1.01, 1.01, 1.01])]
67-
init_serial_unemployment["constructors"].pop("MrkvArray")
67+
init_serial_unemployment["constructors"]["MrkvArray"] = None
6868

6969
self.model = MarkovConsumerType(**init_serial_unemployment)
7070
self.model.cycles = 0

0 commit comments

Comments
 (0)