astropy/astropy — pull request #1243 by nden (2013-07-10 20:03:04+00:00)
Title: Refactor constraints

This is a somewhat larger PR as it touches almost every module but the goal is to simplify and improve handling of constraints. The added tests hopefully will make it easier to further refactor the code or provide alternate implementations.

The biggest change is that the `Constraints` class was eliminated. As before constraints are properties of parameters. Fitters have a copy / list of different types of constraints (``bounds``, ``fixed``, ...). These lists are created once but used in fitting iterations. Before starting a fit, fitters update their lists of constraints to pick up any changes made to the model. Models have a convenience getter property for each type of constraint which returns the current constraints on a model. For example:

```
g1=models.Gaussian1DModel(10, 2, 1, fixed={'amplitude': True})
g1.fixed
Out[6]: {'amplitude': True, 'mean': False, 'stddev': False}

gfit= fitting.NonLinearLSQFitter(g1)
gfit.fixed
Out[4]: [True, False, False]

gfit.bounds
Out[5]:
[(-1000000000000.0, 1000000000000.0),
(-1000000000000.0, 1000000000000.0),
(-1000000000000.0, 1000000000000.0)]

```

This required a change to the `Parameter` class which doesn't inherit from `list` any more. A new attribute `Parameter.value` was added and is mostly transparent to end users.
This change fixed the problem with losing the constraints after a fit. In the previous implementation, when a fitter updated the parameters, it did not update the previously set constraints and they were lost. Now a fitter updates the ``value`` attribute only and all other attributes are kept.

This PR addresses problems raised in issues #1064 , #1218. #1078

I also have a few questions on how to proceed

- What value is it best to use to reset bounds? Internally the default values for bounds are (-10**12, 10**12) and they populate the `min` and `max` attributes of a parameter. Suppose a model was initialized with some bounds. What is the best way to reset them. For example, using `gauss.mean.max = 10**12` to reset the value seems not very intuitive. Is `gauss.mean.max = None` acceptable?

- What is a good way to include a standard docstring about constraints in all models?
The constraints docstrings are currently included in `ParametricModel` and are not visible as individual models's docstrings. If I separate them as a standalone string, is there a way to attach them to a class docstring (all my attempts to append them to __doc__ failed)?