Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some RNG fixes #757

Merged
merged 9 commits into from
Jul 16, 2020
Merged

Some RNG fixes #757

merged 9 commits into from
Jul 16, 2020

Conversation

mnwhite
Copy link
Contributor

@mnwhite mnwhite commented Jul 11, 2020

One of our DemARKs was malfunctioning because our simulator wasn't replicating the same sequence of random shocks after initializeSim() was called. This PR fixes that problem in all of our models (I think) by implementing extensions to AgentType.resetRNG() that reset the RNG of each discrete distribution used by that type.

Malfunctioning Fagereng DemARK revealed that simulation RNG was not being properly reset by the AgentType.resetRNG() method.  This commit adds an extended resetRNG() method for IndShockConsumerType, which fixes the problem for that class and some of its immediate successors.

Other AgentType subclasses will also need resetRNG() methods like this to make sure their simulation RNG gets reset fully.
Tested with examples file, which I also cleaned very slightly (process_time to time, removed reference to timeFwd).  This will break more tests, of course.
Cleaned example file slightly; it had some references to old distribution format.

Also adjusted how preference shocks are drawn to be more parsimonious with new distribution format.
Also made small fixes to example file to remove references to old distribution format.  And changed how simulation draws work to simplify the code and accelerate (5x improvement).
The Markov versions of ConsAggShock and ConsRepAgent were breaking because their IncomeDstns are Markov-state dependent.  These types now call MarkovConsumerType's resetRNG method rather than IndShockConsumerType's.

Also twiddled the targets for some of these tests because they depend on RNG behavior in IndShockConsumerType, which changed earlier in this branch.
Some autoformatter made this solver nearly unreadable.  Adjusted the position of comments to restore it.
if hasattr(self, 'IncomeDstn'):
T = len(self.IncomeDstn)
for t in range(T):
self.IncomeDstn[t].reset()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible rewrite:

for distribution in self.IncomeDstn:
distribution.reset()

'''
PerfForesightConsumerType.resetRNG(self)

# Reset IncomeDstn if it exists (it might not because resetRNG is called at init)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this could be written in a more general way once rather than having more complexity added via inheritance.

This could be a time to think through how exogenous shocks get stored on the Agent object.

dolo, for example, puts all these into a collection names exogenous

'''
PersistentShockConsumerType.resetRNG(self)

# Reset MedShkDstn if it exists (it might not because resetRNG is called at init)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again: if all the exogenous shock distributions were contained in a single collector, then this method could be written more efficiently by looping over that collection.

@sbenthall
Copy link
Contributor

Great progress.

I have some notes on this which I don't think should block the PR but which I think would, ideally, be addressed or at least marked for improvement:

  1. It looks like some of the changes made in this PR are purely formatting/whitespace issues, like when there are line breaks. I understand that there are often strong aesthetic feelings on this point. I also feel that objectively, these differences are trivial. I also believe that black, the code formatting tool that is now a pre-commit hook, is very opinionated about this, and that @MridulS merged a PR some time ago with the black changes made to the ConsumerSaving classes.

I just want to confirm that the changes in this PR are consistent with black, and not a reversion to a pre-black standard.

  1. The resetRNG is in this PR inherited and modified by each subclass according to the name of its exogenous shocks. It would simplify the code and inheritance structure, as well as bring the software closer in line with Dolo, if the exogenous shocks were stored in some collection, such as a dictionary stored at self.exogenous, instead of added as attributes to the base Agent object. This would enable the method to be written generically like so:
for distribution in self.exogenous:
  self.exogenous[distribution].reset()

I wonder if now is the time to do this kind of refactoring, or if it should be slated for a different issue, given the urgency of this work.

@mnwhite
Copy link
Contributor Author

mnwhite commented Jul 14, 2020 via email

@sbenthall
Copy link
Contributor

Good point about the code snippet not working.
Ideally, I'd like to see IncomeDstn implemented in such a way that it was never a nested list, but always a Distribution, even if it was a complex, multivariate distribution.
I'd see that as another step in this proposed refactoring.

I suppose I'll flag this as something to refactor later, unless you have an objection to this in principle.

As for the whitespace issues, while we have not passed an EEP about it, @MridulS and I at least are in agreement that following black conventions for whitespace is a good ida.
https://github.com/econ-ark/governance/issues/5

Since there is now the pre-commit hook installed ( see #703 ) I think that creates de facto pressure to standardize this way.

Running the black on some of the changed files in this PR, I see that indeed the tool does some reformatting.

I'm not certain but I believe some of these reformattings are ones you may have reverted in this PR.

It would be extremely silly if some of us used a reformatting tool as part of our contributions, and some of us reverted them back to a different format whenever they worked on the code.

@mnwhite
Copy link
Contributor Author

mnwhite commented Jul 14, 2020 via email

@sbenthall
Copy link
Contributor

Hmm. Then maybe using the Dolo idiom of a Process would be better here.

I'm not wedded to it being a Distribution subclass.

But I think it would be better to wrap this construct in an object rather than using a generic data type like a list because there is functionality over it that could be encapsulated by a method (for example, reseting all of them at once)

@sbenthall sbenthall merged commit 12b82a5 into master Jul 16, 2020
@sbenthall
Copy link
Contributor

Early bird catches the worm

@mnwhite mnwhite deleted the MoreRNGfixes branch July 16, 2020 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants