Skip to content

Commit

Permalink
consumer.yaml config file; yaml loader in HARK.parser; smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
sbenthall committed Jul 2, 2024
1 parent 7e93ece commit b4b2bd9
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
41 changes: 41 additions & 0 deletions HARK/parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
from HARK.distribution import Bernoulli, Lognormal, MeanOneLogNormal
from sympy.utilities.lambdify import lambdify
from sympy.parsing.sympy_parser import parse_expr
import yaml


class ControlToken:
"""
Represents a parsed Control variable.
"""

def __init__(self, args):
pass


class Expression:
Expand All @@ -17,10 +28,40 @@ def func(self):
return lambdify(list(self.expr.free_symbols), self.expr, "numpy")


def tuple_constructor_from_class(cls):
def constructor(loader, node):
value = loader.construct_mapping(node)
return (cls, value)

return constructor


def math_text_to_lambda(text):
"""
Returns a function represented by the given mathematical text.
"""
expr = parse_expr(text)
func = lambdify(list(expr.free_symbols), expr, "numpy")
return func


def harklang_loader():
"""Add constructors to PyYAML loader."""
loader = yaml.SafeLoader
yaml.SafeLoader.add_constructor(
"!Bernoulli", tuple_constructor_from_class(Bernoulli)
)
yaml.SafeLoader.add_constructor(
"!MeanOneLogNormal", tuple_constructor_from_class(MeanOneLogNormal)
)
yaml.SafeLoader.add_constructor(
"!Lognormal", tuple_constructor_from_class(Lognormal)
)
yaml.SafeLoader.add_constructor(
"!Control", tuple_constructor_from_class(ControlToken)
)

return loader


########################################################################
51 changes: 51 additions & 0 deletions HARK/tests/test_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os
import unittest


import HARK.parser as parser
import yaml


class test_consumption_parsing(unittest.TestCase):
def setUp(self):
this_file_path = os.path.dirname(__file__)
consumer_yaml_path = os.path.join(this_file_path, "../models/consumer.yaml")

self.consumer_yaml_file = open(consumer_yaml_path, "r")

def test_parse(self):
self.consumer_yaml_file

config = yaml.load(self.consumer_yaml_file, Loader=parser.harklang_loader())
pass

"""
try:
config = yaml.load(open('perfect_foresight_full_experimental.yaml', 'r'), Loader= get_loader())
# data is copied
assert config['model']['blocks']['consumption'] == config['model']['strategies'][1]['block']
# data is maintained once in memory and referenced in both places
assert config['model']['blocks']['consumption'] is config['model']['strategies'][1]['block']
# object created by parser
c1 = config['model']['blocks']['consumption']['dynamics']['c']
c2 = config['model']['strategies'][1]['block']['dynamics']['c']
# objects are equal
assert c1 == c2
# objects are identical in memory; the reference is shared.
assert c1 is c2
a_str = config['model']['blocks']['consumption']['dynamics']['a']
a_expr = parse_expr(a_str)
a_func = lambdify(list(a_expr.free_symbols), a_expr, "numpy")
m = np.random.random(100)
c = np.random.random(100)
#import pdb; pdb.set_trace()
except yaml.YAMLError as exc:
print("Error in configuration file:", exc)
"""
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ networkx>=3
numba<0.60.0
numpy>=1.23
pandas>=1.5
pyyaml>=6.0
quantecon
scipy>=1.10
seaborn>=0.12
Expand Down

0 comments on commit b4b2bd9

Please sign in to comment.