econ-ark / HARK

Heterogenous Agents Resources & toolKit
Apache License 2.0
336 stars 199 forks source link

solveOnePeriod is not a method, but sure looks like one #658

Closed sbenthall closed 4 years ago

sbenthall commented 4 years ago

There is a strange coding pattern in the Model classes. I am tempted to try to turn it into something more standard, but want to check if there is a hidden purpose to it.

Typically, a ConsumerType will have an attribute, solveOnePeriod, that is set upon initialization to some stand-alone function in the module. E.g.:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L1658

This stand alone method then typically initalizes a Solver object, runs solve() on it, then returns the result (a solution). E.g.:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L590-L625

These methods are for the most part, except for the choice of Solver class, identical across the library.

This is not ideal because it makes it difficult to read the code: to follow the solution logic, you have to jump out of one class into the global scope, then into another.

It seems to me that either:

The only motivation I can think of for the current implementation is that it's suggested by this code block that the idea was to make it possible to have time-varying solution functions:

https://github.com/econ-ark/HARK/blob/78d1981233a6cda398d4e3007be03f558a7bc910/HARK/core.py#L807-L810

However, this flexibility does not seem to be used anywhere in the HARK repository (I checked), nor does it have any tests associated with it. If this was still a desirable feature, it would be possible to build 'solveOnePeriod', as a standardized method, to optionally take a list of class names that could be indexed by time periods.

[Separately, and maybe to be addressed in a different issue: I'm skeptical about the performance of this method of firing up a new Solver object, complete with a lot of initialization, at every step of the backwards inductions. It seems to me there may be a lot of redundant code calls. I'll revisit this once I've got a profiler set up, but I wanted to mention it now to start circulating the thought.]

mnwhite commented 4 years ago

Yes, I coded it this way to allow for time-varying solveOnePeriod functions. This was intentional.

Not all of our solution functions create a solver class. Some of them are just coded as a single function, which is a lot easier to read and write.

I don't particularly like our "object oriented solvers". The idea was to not rewrite code across solvers, but they made the code an absolute maze to navigate. Moreover, we never actually had a meeting to plan out what the scope of models that HARK should be able to handle (but not for lack of trying), so the "forward looking" structure of the solvers wasn't particularly forward looking.

As for redundant working being done by instantiating and then destroying solver objects: yes, 100%, and there's an old issue that I wrote years ago about this. I think you can find it if you search for "persistent solvers". The idea is to have a better partition between objects that can be re-used across periods of the model and those that need to be created every time.

On Fri, Apr 24, 2020, 7:17 PM Sebastian Benthall notifications@github.com wrote:

There is a strange coding pattern in the Model classes. I am tempted to try to turn it into something more standard, but want to check if there is a hidden purpose to it.

Typically, a ConsumerType will have an attribute, solveOnePeriod, that is set upon initialization to some stand-alone function in the module. E.g.:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L1658

This stand alone method then typically initalizes a Solver object, runs solve() on it, then returns the result (a solution). E.g.:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L590-L625

These methods are for the most part, except for the choice of Solver class, identical across the library.

This is not ideal because it makes it difficult to read the code: to follow the solution logic, you have to jump out of one class into the global scope, then into another.

It seems to me that either:

  • (A) solveOnePeriod could be a method, which would just look like exactly the function that is currently assigned to it, or
  • (B) solveOnePeriod could be a standardized method, which points to a particular Solver class, which is then parameterized in the model code.

The only motivation I can think of for the current implementation is that it's suggested by this code block that the idea was to make it possible to have time-varying solution functions:

https://github.com/econ-ark/HARK/blob/78d1981233a6cda398d4e3007be03f558a7bc910/HARK/core.py#L807-L810

However, this flexibility does not seem to be used anywhere in the HARK repository (I checked), nor does it have any tests associated with it. If this was still a desirable feature, it would be possible to build 'solveOnePeriod', as a standardized method, to optionally take a list of class names that could be indexed by time periods.

[Separately, and maybe to be addressed in a different issue: I'm skeptical about the performance of this method of firing up a new Solver object, complete with a lot of initialization, at every step of the backwards inductions. It seems to me there may be a lot of redundant code calls. I'll revisit this once I've got a profiler set up, but I wanted to mention it now to start circulating the thought.]

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPJRRIYWVBVYTJMUU3ROIMWZANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

Issue #97 is the "persistent solver" issue.

Thanks for acknowledging the maze--I'm glad it isn't just me.

It sounds like you are open to my doing some work on this. I'd be glad to.

Is the time-varying solver functionality something that must be preserved?

mnwhite commented 4 years ago

Must is a strong word. No, but it should exist.

On Fri, Apr 24, 2020, 9:39 PM Sebastian Benthall notifications@github.com wrote:

Issue #97 https://github.com/econ-ark/HARK/issues/97 is the "persistent solver" issue.

Thanks for acknowledging the maze--I'm glad it isn't just me.

It sounds like you are open to my doing some work on this. I'd be glad to.

Is the time-varying solver functionality something that must be preserved?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-619299790, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPWL5OELIJSEMNQNCTROI5MDANCNFSM4MQPH6XQ .

mnwhite commented 4 years ago

Honestly, I think the "some work" on this is to largely start over, in a similar vein to what you described in the other thread about integrating HARK with dolo.

On Fri, Apr 24, 2020, 10:14 PM Matthew White mnwhite@gmail.com wrote:

Must is a strong word. No, but it should exist.

On Fri, Apr 24, 2020, 9:39 PM Sebastian Benthall notifications@github.com wrote:

Issue #97 https://github.com/econ-ark/HARK/issues/97 is the "persistent solver" issue.

Thanks for acknowledging the maze--I'm glad it isn't just me.

It sounds like you are open to my doing some work on this. I'd be glad to.

Is the time-varying solver functionality something that must be preserved?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-619299790, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPWL5OELIJSEMNQNCTROI5MDANCNFSM4MQPH6XQ .

llorracc commented 4 years ago

I agree with Matt. This is probably something for HARK 2.0.

sbenthall commented 4 years ago

I'm confused by your reaction here. The scope of this issue (#658) is quite narrow.

It also seems like in with one of the desiderata for HARK 1.0, which is correcting the class/method architecture to remove the use of standalone functions where they seem to have been left out in the open originally and never tucked in.

https://github.com/econ-ark/HARK/wiki/Towards-2.0#hark-10-refactoringfeature-targets

I could see how fixing #97 is a bigger lift. Maybe you meant that that should be a 2.0 target.

mnwhite commented 4 years ago

I don't think this issue should be solved. One use case for doing it this way is for teaching purposes when showing multiple methods for solving the same problem.

In my graduate numeric methods class, I walk the students through three different methods for solving a basic consumption-saving model (explicit maximization, first-order-condition solving, and endogenous grid method; I assign them to further vectorize the latter as an assignment). I write one (very simple) AgentType subclass and three solveOnePeriod functions. To demonstrate each one, I can create several instances of the type and substitute a different function into solveOnePeriod for each one.

That would take three different classes under your revision, if I understand you correctly.

On Mon, Apr 27, 2020 at 3:39 PM Sebastian Benthall notifications@github.com wrote:

I'm confused by your reaction here. The scope of this issue (#658 https://github.com/econ-ark/HARK/issues/658) is quite narrow.

It also seems like in with one of the desiderata for HARK 1.0, which is correcting the class/method architecture to remove the use of standalone functions where they seem to have been left out in the open originally and never tucked in.

https://github.com/econ-ark/HARK/wiki/Towards-2.0#hark-10-refactoringfeature-targets

I could see how fixing #97 https://github.com/econ-ark/HARK/issues/97 is a bigger lift. Maybe you meant that that should be a 2.0 target.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620192235, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFJF2DKXX2IJCVJJFHDROXNQNANCNFSM4MQPH6XQ .

llorracc commented 4 years ago

Generically we should work on a syntax to direct an agent to solve their problem with a particular method: Value Function Iteration, FOC's, endogenous grid, polynomial methods, etc. At present, for most of our models, we have only one solution method that is hard-coded in. If we had a generic syntax, we could still make the "default" method be the one that is now hard-coded in, and if the user asks for any other solution method that is not available, they are told that their requested method is not yet available.

sbenthall commented 4 years ago

I like @llorracc 's point here a lot.

@mnwhite I think I see what you're saying about needing to swap in different solvers.

Are the other solveOnePeriod methods you use also in HARK?

The way Dolo works, the solver (say, Value Iteration), takes the model as an argument, and returns the solution (a decision rule). I like that design. https://github.com/EconForge/dolo/blob/master/dolo/algos/value_iteration.py#L17

What if as a workflow:

The solver could know that it only accepts certain classes of AgentType as inputs if it is not generic.

llorracc commented 4 years ago

I don't like the idea of the solver "knowing that it only accepts certain classes of AgentType as inputs." Solvers should be specified as generically as possible, without reference to the AgentType that they are solving. It is the AgentType that should know which kinds of solvers work for it. This is because there is a potentially unlimited number of AgentTypes and it would be messy for each solver to have to be updated to keep track of the status of every kind of AgentType.

mnwhite commented 4 years ago

If you want to make solveByBlah a function rather than have a solve method, go ahead.

On Mon, Apr 27, 2020 at 4:26 PM Sebastian Benthall notifications@github.com wrote:

I like @llorracc https://github.com/llorracc 's point here a lot.

@mnwhite https://github.com/mnwhite I think I see what you're saying about needing to swap in different solvers.

Are the other solveOnePeriod methods you use also in HARK?

The way Dolo works, the solver (say, Value Iteration), takes the model as an argument, and returns the solution (a decision rule). I like that design.

https://github.com/EconForge/dolo/blob/master/dolo/algos/value_iteration.py#L17

What if as a workflow:

  • you define an AgentType
  • You instantiate a Solver (or 3)
  • You pass the AgentType to the Solver?

The solver could know that it only accepts certain classes of AgentType as inputs if it is not generic.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620214898, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPIXZHQSPAI4VAWX43ROXS7DANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

Ok. I will put some thought into this and see if there's anything that can be done in the short term to make things a little cleaner.

mnwhite commented 4 years ago

I don't think there's any "small work" here, at least any that's meaningful. Changing the syntax from ThisType.solve() to solveByTheOnlyMethodWeProgrammed(ThisType) seems like a big structural change that doesn't actually do anything. We can do it, but it feels like something we should do when starting over from scratch. We can call that HARK 1.0 or HARK 2.0, but I don't think this is a place for incremental change.

On Mon, Apr 27, 2020 at 4:34 PM Sebastian Benthall notifications@github.com wrote:

Ok. I will put some thought into this and see if there's anything that can be done in the short term to make things a little cleaner.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620219372, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFLSAS7VKQWGZAFAL63ROXT7BANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

I thought you just said, "go ahead". Maybe you were being sarcastic.

I wonder if you've ever given much thought to what the term "refactor" means. https://refactoring.com/

My understanding is that a major deliverable of the grant I am working on is to refactor HARK towards a 1.0 version.

Refactoring normally means making structural changes to code that does not change the functionality in order to make it easier to read and extend.

My sense is that there are two good standards available for what HARK should be refactored towards:

There's also the usual considerations: performance, and making things a bit more concise when there are unnecessary lines of code.

One reason why it's a good idea to make these changes is that it makes it more likely that somebody else who comes along and reads the code isn't bewildered by it. You seem to be a bit ambivalent about the readability of the code here--sometimes you joke about it being hard to read, or call it "a maze". So I gather you do think that there are changes to make.

I'm not sure when the "rewrite" is planned, but I'm not sure it's wise to do that, to be honest. You already have many test cases built out and, I gather, a kind of commitment to preserving the old research code.

You might have the time or wherewithal to do the refactoring; I wouldn't expect you to as a professor of economics. But as I've been a software engineer, among other things, at various times in my career, I see this sort of thing as just par for the course. I think things would move more quickly if you let me do my job.

sbenthall commented 4 years ago

Sorry; I meant might not have the time or wherewithal to do the refactoring.

sbenthall commented 4 years ago

So, hmmm: there is already a function that takes an agent and solves it? core.solveAgent

https://github.com/econ-ark/HARK/blob/master/HARK/core.py#L681

But, once again, this is a little misleading. It's defined at the global module level, but really it's intended to be called like a method within AgentType:

https://github.com/econ-ark/HARK/blob/master/HARK/core.py#L314

I guess this has been like this for years and you are used to it.

But, and I'm sorry to have to say this, to me it reads like a mistake. It has strong "the person who wrote this didn't know what they were doing" energy. I gather that you understand that this is a bad design structure, because you've said as much in an analogous case here:

https://github.com/econ-ark/HARK/issues/538#issuecomment-589850515

So all I'm trying to do here is clean up these structural issues so that when HARK does a 1.0 release it doesn't have obviously bad structure to it. I think you think this is so heinously difficult to correct it's not worth doing it. It's on that point I disagree. I think it's wiser to do the refactoring with the existing functionality, robustly tested for as long as possible. It will get you to where you want to go faster. Trust me.

llorracc commented 4 years ago

I think partly Matt's judgment of how difficult something would be to do is colored by the fact that until recently he was pretty much the only do-er. Now that you and Mridul are working with us, our capacity for do-ing is much greater than it was -- and Matt's role can be much smaller than his central nervous system feels it will be when he sees a proposal to do something. Basically, just heading off big mistakes.

sbenthall commented 4 years ago

whoops hit the wrong button. i guess that was my subconscious reacting with a 'case closed'

sbenthall commented 4 years ago

Wikipedia on Refactoring is actually quite good : https://en.wikipedia.org/wiki/Code_refactoring

mnwhite commented 4 years ago

I wasn't being sarcastic. I really did mean this is a change you can make. My subsequent comment was a reaction to your saying "in the short term", because this seems like if it's done and it has teeth, it is a big, big structural change.

To my understanding, you proposed having AgentType instances be passed as an argument to a solver function, where we might have multiple different solver functions, rather than invoking the solve() method. Ex ante, if we were just beginning (or starting over), this would be a fine choice, but it's not clear what's being gained in the short run by doing this. We don't/won't have multiple solver functions to use with it... and it's not clear to me that we ever will have a generic solveByVFI or solveByEGM function. So it feels like just a change in syntax that has a cost (adjusting downstream code) without an apparent upside.

Yes, the child functions of solve are not great, and are downright embarrassing in some cases. All of that can and should be simplified and moved into a single method of AgentType (or maybe two methods). This won't break anything because nothing interacts with the internal stuff in AgentType.

On Mon, Apr 27, 2020 at 8:25 PM Sebastian Benthall notifications@github.com wrote:

whoops hit the wrong button. i guess that was my subconscious reacting with a 'case closed'

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620305117, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPPE3Y2PWNSDCSLSR3ROYO6ZANCNFSM4MQPH6XQ .

mnwhite commented 4 years ago

Whoops, left off a sentence to explain the "change in syntax" bit. Without one of those "generic solvers", ultimately the new solve function will just end up calling our existing model-by-model code.

On Mon, Apr 27, 2020 at 8:53 PM Matthew White mnwhite@gmail.com wrote:

I wasn't being sarcastic. I really did mean this is a change you can make. My subsequent comment was a reaction to your saying "in the short term", because this seems like if it's done and it has teeth, it is a big, big structural change.

To my understanding, you proposed having AgentType instances be passed as an argument to a solver function, where we might have multiple different solver functions, rather than invoking the solve() method. Ex ante, if we were just beginning (or starting over), this would be a fine choice, but it's not clear what's being gained in the short run by doing this. We don't/won't have multiple solver functions to use with it... and it's not clear to me that we ever will have a generic solveByVFI or solveByEGM function. So it feels like just a change in syntax that has a cost (adjusting downstream code) without an apparent upside.

Yes, the child functions of solve are not great, and are downright embarrassing in some cases. All of that can and should be simplified and moved into a single method of AgentType (or maybe two methods). This won't break anything because nothing interacts with the internal stuff in AgentType.

On Mon, Apr 27, 2020 at 8:25 PM Sebastian Benthall < notifications@github.com> wrote:

whoops hit the wrong button. i guess that was my subconscious reacting with a 'case closed'

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620305117, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFPPE3Y2PWNSDCSLSR3ROYO6ZANCNFSM4MQPH6XQ .

llorracc commented 4 years ago

"A journey of a thousand miles begins with a single step"

I think @sbenthall has shown good judgment about ways to move forward without breaking things more than is absolutely necessary.

Either the project will fail, or it will succeed. It definitely will not succeed if we are not ambitious. My sense is that @sbenthall has done a good job of identifying changes we need to make for it to be a good platform for the long haul, and charting a judicious path to getting there.

sbenthall commented 4 years ago

I want to flag this non-OO solver function as an example of a different coding pattern around 1-period solvers.

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsPortfolioModel.py#L228-L234

I see now it's a bit more complicated than I thought, because there's more than one pattern for 'one period solvers' around.

But I think that the OO-solver functions can be consolidated into a single function. Most of these have a redundant structure. E.g:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L623-L625

is similar, except for choice of Solver object, to this:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L623-L625

which has some additional logic for the interpolater choice, that could be smoothed over, but which is otherwise almost identical to this:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsPrefShockModel.py#L486-L491

And so on.

mnwhite commented 4 years ago

I would like ConsIndShockSolverSetup, ConsIndShockSolverBasic, and ConsIndShockSolver to be collapsed into one class. I lost that fight 4.5 years ago.

On Tue, Apr 28, 2020 at 9:17 AM Sebastian Benthall notifications@github.com wrote:

I want to flag this non-OO solver function as an example of a different coding pattern around 1-period solvers.

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsPortfolioModel.py#L228-L234

I see now it's a bit more complicated than I thought, because there's more than one pattern for 'one period solvers' around.

But I think that the OO-solver functions can be consolidated into a single function. Most of these have a redundant structure. E.g:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L623-L625

is similar, except for choice of Solver object, to this:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsIndShockModel.py#L623-L625

which has some additional logic for the interpolater choice, that could be smoothed over, but which is otherwise almost identical to this:

https://github.com/econ-ark/HARK/blob/master/HARK/ConsumptionSaving/ConsPrefShockModel.py#L486-L491

And so on.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620600607, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFIHQGGC4SKIPYR23RTRO3JOBANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

@mnwhite Thanks for the clarification! I think we see eye to eye on a lot of design issues and I understand that part of what I've been seeing in the code is the result of uneasy truces.

Just FYI: even if a method is defined in a class, you can still override it with your own function in Python. I believe Python is mechanically indifferent to whether or not the value of a field is defined in the class/method syntax, or the value-assignment syntax.

So, the following will print "11"

from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType

example = IndShockConsumerType()
example.cycles = 0
example.solve()

example.update = lambda x : x + 1

print(example.update(10))

So if, as suggested originally in this issue, the solveOnePeriod functions were written in the class/method syntax, you could still do what you've been doing while teaching.

It would be a bit clearer from the code, in that case, that you were doing something you "shouldn't" be doing. Which may or may not bother you.

mnwhite commented 4 years ago

I thought that very specifically didn't work-- that once a particular name had been used as a method, it would expect the first argument to be self even if a function were assigned to that name later. I remember having difficulty with this.

On Tue, Apr 28, 2020 at 9:33 AM Sebastian Benthall notifications@github.com wrote:

@mnwhite https://github.com/mnwhite Thanks for the clarification! I think we see eye to eye on a lot of design issues and I understand that part of what I've been seeing in the code is the result of uneasy truces.

Just FYI: even if a method is defined in a class, you can still override it with your own function in Python. I believe Python is mechanically indifferent to whether or not the value of a field is defined in the class/method syntax, or the value-assignment syntax.

So, the following will print "11"

`` from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType

example = IndShockConsumerType() example.cycles = 0 example.solve()

example.update = lambda x : x + 1

print(example.update(10)) ``

So if, as suggested originally in this issue, the solveOnePeriod functions were written in the class/method syntax, you could still do what you've been doing while teaching.

It would be a bit clearer from the code, in that case, that you were doing something you "shouldn't" be doing. Which may or may not bother you.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620610760, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFOBPE7T7GECY7YXA4TRO3LKTANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

Hmm. Curious. I've tested the code in my last comment.

I think I have a good enough understanding of the terrain of concerns here to productively put energy into a PR.

I won't know the specific way that will look until I've done the work of the PR--this is a case where I'll really need to "think in code"--but certainly I'll ask you to review the work @mnwhite. You can tell me then if I've missed the mark.

mnwhite commented 4 years ago

Ok. To be clear, my ideal is for each of our solveOnePeriod functions to be just one function. The OO solvers were a decent idea, but their methods and submethods are incredibly tangled. Our efforts to "not duplicate code" resulted in fewer lines of code that are harder to read, and about 5x more docstrings.

On Tue, Apr 28, 2020 at 10:03 AM Sebastian Benthall < notifications@github.com> wrote:

Hmm. Curious. I've tested the code in my last comment.

I think I have a good enough understanding of the terrain of concerns here to productively put energy into a PR.

I won't know the specific way that will look until I've done the work of the PR--this is a case where I'll really need to "think in code"--but certainly I'll ask you to review the work @mnwhite https://github.com/mnwhite. You can tell me then if I've missed the mark.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/econ-ark/HARK/issues/658#issuecomment-620628078, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKRAFOFXZ2AVT7NJ2V6IO3RO3O4VANCNFSM4MQPH6XQ .

sbenthall commented 4 years ago

Some progress on this, I hope. This proposed commit creates a generic onePeriodOOSolver factory* and tests it out in the PerfectForesight case.

https://github.com/econ-ark/HARK/pull/665/commits/c5a2bc05efb245e79d3e92bae399720be18ff8a7

In a different commit on this PR, I show how that can be reused for the IndShockConsumerType case.

This implementation maintains solveOnePeriod's being set as a field, as opposed to as a method.

But rather than a different function defined for each OO solver, the function is created with the OO solver as an input. This requires a few modifications to the Solver objects, which don't seem sacred in their design based on our converation: they would take the Agent as an argument rather than having so many named parameters.

This is, again, an attempt at a minor refactoring. But the idea is to centralize more of the solution logic so it's a little easier to follow, and to see where there might be other extensions, improvements, or simplifications.

It may be a bit to digest so I won't work on it any more until we've had a chance to discuss it on our Thursday call.