astropy/astropy — pull request #2381 by embray (2014-04-28 17:47:24+00:00)
Title: Model formulae

This is a proof of concept for an idea that's been kicking around in the back of my head.

Many of the basic "functional" models in the modeling package have some formula for that model displayed a LaTeX in the model's docstring. This PR does three main things with this:

1. It adds a `_formula_` attribute to all `Model` subclasses. The attribute should be a string *template*
for the model's LaTeX formula that replaces each parameter's symbol with a template variable with the same name as the parameter attribute.
2. It adds a `latex` attribute to all model `Parameter` attributes, specifying a LaTeX symbol that represents that parameter in the formula.
3. It removes the formula itself from the model's docstring, and instead treats the docstring as a string formatting template, currently with one template variable `{formula}`. On creation of the class the `_formula_` attribute is updated by interpolating it with the actual parameter LaTeX symbols. Then the full docstring is updated by interpolating any template variables (i.e. `{formula}`)

The end result is that `MyModel._formula_` ends up containing the same formula that previously appeared in the docstring, and the docstring itself appears the same as before. Doing things this way has possible advantages, however. One of those advantages is demonstrated by adding `_repr_html_` output for IPython notebook for both `Model` classes themselves, and instances of models (where in the latter case a table of all parameter values for all parameter sets is displayed). This could likely use more work but it's a start:

![modeling_formulae](https://cloud.githubusercontent.com/assets/676149/2820609/1bbe6fa6-cefc-11e3-8511-5becb767e5f6.png)

Abstracting out the parameter symbols has some advantages as well, such as being able to change the symbol used for a parameter in one place.It can also be useful in other contexts, such as in the table displayed above.

A few further ideas and issues that need addressing:

1. Some of the models have more complicated formulas for sets of formula (see the `Gaussian2D` class for example). It's probably not worth worrying about these corner cases, though one could see potential for a `_formulas_` list of multiple formulas. They could be accessed within the docstring as `{formulas[0]}`, `{formulas[1]}`, etc. The `_repr_html_` could be improved too so that individual models can have more control over which formulas are displayed depending on context.
2. In addition to the `latex` symbol, one could also make a case for allowing specification of a plain-text symbol to use for each parameter, perhaps either unicode or ASCII. Perhaps this could be used in a conjunction with an optional dependency on SymPy for generating plain-text formula graphics. These might be useful in other contexts as well.
3. Since the `Model` docstrings are now format strings, any curly braces now need to be doubled up like `{{` and `}}` since they are otherwise interpreted as part of the template format. This does *not* affect doctests, but it's still a bit awkward. Perhaps an alternate template format could be used for the docstrings to avoid this.

So far I have only converted the `Gaussian1D` class to use this format. I didn't want to go whole hog with it until I got a sense that other people think this is a good idea in general.