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

Model parameter getters and setters modeled on NetworkX methods #679

Closed
sbenthall opened this issue May 7, 2020 · 5 comments
Closed

Model parameter getters and setters modeled on NetworkX methods #679

sbenthall opened this issue May 7, 2020 · 5 comments
Assignees
Milestone

Comments

@sbenthall
Copy link
Contributor

Currently, HARK users are encouraged to dynamically reset model parameters on the model class like so:

    def test_another_solution(self):
        self.agent_alt.DiscFac = 0.90
        self.agent_alt.solve()
        self.assertAlmostEqual(
            self.agent_alt.solution[0].cFunc(10).tolist(),
            3.9750093524820787)

Here DiscFac is being reset by the user after initialization.

This use of a public attribute is in fact Pythonic. (I was incorrect earlier about using getters and setters in Python). But there are ways to set up hooks when the value is set using the @property decorator:

https://www.python-course.eu/python3_properties.php

This might be useful for testing conditions (for example, that Rboro > Rsave) when the model is being modified.

It may also be useful for storing the values in a way that is easier to programmatically access later. Ideally, there would be a way to export or display all the currently set model parameters as a dictionary (or some other format) and this is currently impossible. See #446

@sbenthall sbenthall added this to the 1.0.0 milestone May 7, 2020
@sbenthall
Copy link
Contributor Author

This requirement is, on its surface, at odds with the idea of namespacing parameters #660
It would be possible in principle to redundantly store model properties in a namespace.
But the implementation implied by the python @property decorator stores the property value as an object attribute.

At this time when this issue was written, this user interface was considered important.

What is troublesome from a software design perspective about this is that there are currently multiple ways to reset a parameter. There is this way: setting it via an attribute setter.

There is also the way the HARKobject class is given a __call__() method mapped to assignParameters()

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

This violates the Zen of Python: o"There should be one-- and preferably only one --obvious way to do it." (see Zen of Python)

We need to give up one of these ways of doing things. Which will it be?

We can either:

  1. Allow parameters to be assigned to attributes/properties of a Model class. This will require hard-coding the parameters of a Model as properties.
  2. Allow parameters to be provided in a more flexible way, but in a dedicated data structure. This is the direction other parts of the library have been moving in, as this matches the more general architecture of Dolo.

Because assignParameters works with any dictionary, there's no way to keep track of those parameters without storing the dictionary itself. This is what is being done in solutions to issues like #612 see #903

@sbenthall
Copy link
Contributor Author

This is related to #640 . The use case is when the user wants to change the standard deviation of the income distribution and rerun the model.

Currently, changing this parameter will not reconstruct the internally used discretized distribution object.

@sbenthall
Copy link
Contributor Author

The question underlying this issue is whether and how to commit HARK models to an underlying data structure.

This documentation about the data structure of Graphs in NetworkX is informative and a nice example of a clearlyly defined data structure for a scientific library.

https://networkx.org/documentation/stable/reference/introduction.html#data-structure

As we move towards more configurable model definition and flexible modeling architecture, our models cease being code and become a kind of data. That implies the need to define our data structure.

That suggests that we should not be supporting the setting of model properties through attribute getters and setters. If we follow the pattern of NetworkX (a library I like very much, personally), we would have methods like set_model_property(name, value) (or something shorter) to manage the interaction with the model. If a user wants to use Python syntax directly, they could modify e.g. model.paramaters['CRRA'] = 0.95 and that probably would also still work, though we would want to test and document it if we intended that to be how it was used.

I'm feeling confident about this and so will change the name and purpose of this ticket to making a model parameter setting method. If there's pushback on this, I'll keep trying to argue the point.

@sbenthall sbenthall changed the title @property for dynamic resetting of model parameters UI? Model parameter getters and setters modeled on NetworkX methods Feb 8, 2021
@sbenthall
Copy link
Contributor Author

Ah. This is close to what assignParameters does.
It can be modified to do this exactly.

@sbenthall
Copy link
Contributor Author

maybe it doesn't need to be parameters in the method name. it could maybe be set or assign.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant