econ-ark / HARK

Heterogenous Agents Resources & toolKit
Apache License 2.0
329 stars 198 forks source link

`make_shock_history` and `read_shocks` ignore draws of initial state vector #1097

Closed Mv77 closed 2 years ago

Mv77 commented 2 years ago

I believe make_shock_history and agent.read_shocks = True are meant to be used when one wants to limit the randomness of simulations for reproducibility or when estimating a model and wanting a well defined objective function.

(Are these the use cases you had in mind? Are there others?)

It currently works great for shocks, but it leaves another source of randomness uncontrolled: the initial state of newborns (e.g. pLvl and aNrm of newborns in the case of ConsIndShock). You can see that regardless of whether read_shocks == True or not, get_mortality() calls sim_births() and draws states for newborns: https://github.com/econ-ark/HARK/blob/1d379083cdba3ff9bbca494fb8664eb9ae4f29da/HARK/core.py#L631-L635

It would be useful (at least for me at the moment) to have a way to also fix these initial conditions, as we do for shocks.

Mv77 commented 2 years ago

I'll be working on this.

alanlujan91 commented 2 years ago

Might be related to @sbenthall's issue #1084.

llorracc commented 2 years ago

I'm guessing that this has not come up in the use of these before because the models being simulated started with everyone having identical initial circumstances (and maybe no death).

mnwhite commented 2 years ago

This was actually meant as a speedup mechanism. The code should already be structured so that the same sequence of random shocks is drawn for each agent on each simulation pass; that's why the resetRNG() or reset() methods exist (I forget what they're called now) as part of initialize_sim(). Everything about the simulation should be reset to the same computational state even without read_shocks=True. Objective functions based on simulations should be stable no matter what.

What read_shocks=True allows is avoiding the work of re-drawing the exact same sequences of shocks (tens of) thousands of times. If the same shocks would be drawn every time, why not just draw them once, write them down, and then look them up later. The shock-drawing process can be a non-trivial part of the computation in models with "nested states", or shock distributions that depend on (e.g.) a discrete Markov state or another exogenously evolving state variable.

On Sat, Jan 8, 2022 at 3:13 PM Christopher Llorracc Carroll < @.***> wrote:

I'm guessing that this has not come up in the use of these before because the models being simulated started with everyone having identical initial circumstances (and maybe no death).

— Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/1097#issuecomment-1008132642, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFOXCNIRBXDCSYZX23TUVCLEZANCNFSM5LQ6W7BA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

Mv77 commented 2 years ago

@mnwhite thanks, I am glad that is the case.

The one case I think might break this is the following.

Suppose that I have two models: A and B. And suppose B nests A in the sense that B has the same shocks and state variables as A but an additional state variable to be initialized.

If I wanted to run a simulation of agents of type A and B whose common states are initialized in the same (random) values and are hit by exactly the same shocks, I would do something like

agent_B = type_B()
agent_B.make_shock_history()
agent_B.read_shocks = True

agent_A = type_A()
agent_A.shock_history = copy(agent_B.shock_history)
agent_A.read_shocks = True

agent_B.solve()
agent_B.simulate()

agent_A.solve()
agent_A.simulate()

But this will not force the states that are common to A and B to be initialized to the same values when agents are born (I believe). Because, since B will draw extra states from the RNG, the RNG states between simulations A and B will be out of phase when drawing their common states. Does this sound right?

As I write this, I realize the use-case might be quite specific. Nevertheless, might there be value (beyond my issue) in allowing users to pre-specify draws for initial states of newborns just as they can pre-specify shock draws?

mnwhite commented 2 years ago

Yes, absolutely. This oversight should be fixed, and newborn / sim_birth() draws should use the same or similar functionality.

On Sat, Jan 8, 2022 at 3:44 PM Mateo Velásquez-Giraldo < @.***> wrote:

@mnwhite https://github.com/mnwhite thanks, I am glad that is the case.

The one case I think might break this is the following.

Suppose that I have two models: A and B. And suppose B nests A in the sense that B has the same shocks and state variables as A but an additional state variable to be initialized.

If I wanted to run a simulation of agents of type A and B whose common states are initialized in the same (random) values and are hit by exactly the same shocks, I would do something like

agent_B = type_B() agent_B.make_shock_history() agent_B.read_shocks = True

agent_A = type_A() agent_A.shock_history = copy(agent_B.shock_history) agent_A.read_shocks = True

agent_B.solve() agent_B.simulate()

agent_A.solve() agent_A.simulate()

But this will not force the states that are common to A and B to be initialized to the same values when agents are born (I believe). Because, since B will draw extra states from the RNG, the RNG states between simulations A and B will be out of phase when drawing their common states. Does this sound right?

As I write this, I realize the use-case might be quite specific. Nevertheless, might there be value (beyond my issue) in allowing users to pre-specify draws for initial states of newborns just as they can pre-specify shock draws?

— Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/1097#issuecomment-1008147963, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFKBZOOA36FRU4FJ42TUVCO4HANCNFSM5LQ6W7BA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

Mv77 commented 2 years ago

Great, I'm on it.