Skip to content

Commit

Permalink
Merge pull request #59 from Princeton-CDH/revise-hawkdove-distributions
Browse files Browse the repository at this point in the history
fine-tune variant distributions
  • Loading branch information
rlskoeser authored Jan 16, 2024
2 parents 9609219 + e7b8c5b commit 907c290
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
20 changes: 14 additions & 6 deletions simulatingrisk/hawkdovemulti/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,33 +224,41 @@ def get_risk_attitude_generator(self):
while True:
yield self.random.randint(self.min_risk_level, self.max_risk_level)
if self.risk_distribution == "normal":
# return values from a normal distribution centered around 4
# return values from a normal distribution centered around 4.5
while True:
yield int(self.random.gauss(4, 1.5))
yield round(self.random.gauss(4.5, 1.5))
elif self.risk_distribution == "skewed left":
# return values from a triangler distribution centered around 0
while True:
yield round(
self.random.triangular(self.min_risk_level, self.max_risk_level, 0)
)
elif self.risk_distribution == "skewed right":
# return values from a triangler distribution centered around 8
# return values from a triangular distribution centered around 9
while True:
yield round(
self.random.triangular(self.min_risk_level, self.max_risk_level, 8)
self.random.triangular(self.min_risk_level, self.max_risk_level, 9)
)
elif self.risk_distribution == "bimodal":
# to generate a bimodal distribution, alternately generate
# values from two different normal distributions centered
# around the beginning and end of our risk attitude range
while True:
yield int(self.random.gauss(1, 0.75))
yield int(self.random.gauss(7, 0.75))
yield round(self.random.gauss(0, 1.5))
yield round(self.random.gauss(9, 1.5))
# NOTE: on smaller grids, using 0/9 makes it extremely
# unlikely to get mid-range risk values (4/5)

def get_risk_attitude(self):
"""return the next value from risk attitude generator, based on
configured distribution."""
val = next(self.risk_attitude_generator)

# for bimodal distribution, clamp values to range
if self.risk_distribution == "bimodal":
return max(self.min_risk_level, min(self.max_risk_level, val))

# for all other distributions:
# occasionally generators will return values that are out of range.
# rather than capping to the min/max and messing up the distribution,
# just get the next value
Expand Down
8 changes: 4 additions & 4 deletions tests/test_hawkdovemulti.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def test_get_risk_attitude_generator():
model.risk_distribution = "normal"
model.random.gauss.return_value = 3.3 # value to convert to int
next(model.get_risk_attitude_generator())
model.random.gauss.assert_called_with(4, 1.5)
model.random.gauss.assert_called_with(4.5, 1.5)

model.risk_distribution = "skewed left"
model.random.triangular.return_value = 2.1 # value to round
Expand All @@ -339,7 +339,7 @@ def test_get_risk_attitude_generator():
model.random.triangular.return_value = 7.6 # value to round
next(model.get_risk_attitude_generator())
model.random.triangular.assert_called_with(
model.min_risk_level, model.max_risk_level, 8
model.min_risk_level, model.max_risk_level, 9
)

# bimodal returns values from from two different distributions; call twice
Expand All @@ -348,8 +348,8 @@ def test_get_risk_attitude_generator():
risk_gen = model.get_risk_attitude_generator()
next(risk_gen)
next(risk_gen)
model.random.gauss.assert_any_call(1, 0.75)
model.random.gauss.assert_any_call(7, 0.75)
model.random.gauss.assert_any_call(0, 1.5)
model.random.gauss.assert_any_call(9, 1.5)


def test_get_risk_attitude():
Expand Down

0 comments on commit 907c290

Please sign in to comment.