Skip to content

WIP: Improve modeling docs how to create user-defined models and fitters#1878

Closed
cdeil wants to merge 8 commits into
astropy:masterfrom
cdeil:modeling_new_model_fitter_docs
Closed

WIP: Improve modeling docs how to create user-defined models and fitters#1878
cdeil wants to merge 8 commits into
astropy:masterfrom
cdeil:modeling_new_model_fitter_docs

Conversation

@cdeil

@cdeil cdeil commented Dec 9, 2013

Copy link
Copy Markdown
Member

This pull request tries to improve the sections of the modeling docs that explain how to implement user-defined models and fitters.

  • Split it in two pages: user-defined models; user-defined fitters
  • Extract examples into Python files so that they can be easily tested (the current user-defined fitter example is completely broken) and the user has a working example to copy & paste and get started.
  • Change to old-school documentation format: full example first, then short high-level description, then detailed line-by-line explanations.

@nden @embray @astrofrog Please review.

TODO:

  • Replace TODO markers with actual line numbers after review.
  • Rewrite new_model.rst in the same style I rewrote new_fitter.rst.

Comment thread docs/modeling/new_fitter.py Outdated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@nden @embray I have no idea ... what constraints are really supported here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since this uses scipy.optimize.fmin_slsqp then in principle all of these constraint types should be supported. Though at first glance it doesn't look like the current implementation of this fitter is actually supporting them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SLSQPFitter supports all these constraints. However, for clarity of the example, and because "ineqcons" and "eqcons" are specific to SLSQP and have not been tested much, I think we can exclude them.

Also it may be good to add a comment that the call to _model_to_fit_params() is needed in order to deal with "fixed" and "tied" constraints. It also handles "bounds" for optimization algorithms which (unlike SLSQP) don't internally handle it. Because "fmin_slsqp" works internally with bounds, they must be passed to it in the correct form (see comment below).

@cdeil

cdeil commented Dec 9, 2013

Copy link
Copy Markdown
Member Author

Do we want the Gaussian1DModel and LineModel example or is one enough?
Should we remove the LineModel as in reality there is never (or very rarely) the need to define a custom PolynomialModel?

@nden

nden commented Dec 9, 2013

Copy link
Copy Markdown
Contributor

I agree these need more attention. 👍 on splitting the examples for models and fitters and 👍 on extracting the examples into python files.

For the content, I think for models we need an example of using custom1d (is anyone interested in writing custom2d?) and two examples of creating a model by subclassing a base class (one of a parametric model and one of a non-fittable model). The reason for this is that there is a subtle difference in handling parameters with the current parameter implementation (or at least this is my understanding, see e.g. Pix2Sky_AZP.) I am not sure LineModel is a good example of a parametric model, may be a 2D example would be better. Also any suggestions for a good example of directly subclassing Model?

We've talked before about separating optimization algorithms and fit statistic in fitters and I think we should aim to get this included in 0.4. I will make a separate issue about this but I think for 0.3.1 we should just correct the existing example and write a more complete example for 0.4 showing how to combine statistic and optimization methods to create a fitter. I like how you started Chi2Fitter, it's just that how this is implemented in fitting.py may change when we split those two and so the example will change.

So to summarize how I see this:

for 0.3.1:

  • keep the gaussian example
  • either keep Line1D or create a more useful example (need suggestions ?)
  • create an example of subclassing Model (suggestions ?)
  • clean and correct the existing new_fitter example

for 0.4

  • separate optimization from statistic (code changes)
  • write examples of new fitters (I think the above code changes will simplify the examples)

Comments about this plan?

@cdeil I'll try to review this PR today.

@cdeil

cdeil commented Dec 9, 2013

Copy link
Copy Markdown
Member Author

How can I avoid this error (i.e. make this optional if scipy and matplotlib are available)?
https://travis-ci.org/astropy/astropy/jobs/15167254#L1551

@cdeil

cdeil commented Dec 9, 2013

Copy link
Copy Markdown
Member Author

@nden Agree with everything you say. So this PR would be the modeling docs fixes for 0.3.1 and we'll discuss the 0.4 changes elsewhere. I'll wait for your review and then try to make all changes at once.

Can't resist ... some comments on 0.4:

  • +1 to splitting fit statistic and minimiser.
  • +1 to not worry at all about backwards compatibility when discussing the 0.4 API.
  • Can we make the interfaces more generic? (I currently work with 3D data and models ... I'll try to make an example soon.)

@embray

embray commented Dec 9, 2013

Copy link
Copy Markdown
Member

As for custom2d I still have in mind to write an n-dimensional custom_model that would replace the custom1d and obviate the need for a separate custom2d.

Comment thread docs/modeling/new_fitter.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As mentioned above SLSQP handles internally bounds and they must be passed to the minimizer in the correct form:

pars = [getattr(model_copy, name) for name in model_copy.param_names]
bounds = [par.bounds for par in pars if par.fixed != True and par.tied == False]
bounds = np.asarray(bounds)
for i in bounds:
    if i[0] is None:
        i[0] = DEFAULT_MIN_BOUND
    if i[1] is None:
        i[1] = DEFAULT_MAX_BOUND

@nden

nden commented Dec 9, 2013

Copy link
Copy Markdown
Contributor

@cdeil The models examples look good to me. Does adding __doctest_requires__ to new_fitter.py help with the Travis error? I haven't used it before but from the testing guidelines, it sounds like this might work:

__doctest_requires__ = {('Chi2Fitter.*): ['scipy']}

@cdeil

cdeil commented Feb 22, 2014

Copy link
Copy Markdown
Member Author

Puh, it's hard to come back to old pull requests after a few months ... sorry for dropping the ball on this PR.
I'll hold off finishing this up until #1914 is merged.
Or maybe I'll start from scratch trying to improve the modeling docs after the main structural changes are done.

@cdeil

cdeil commented Feb 22, 2014

Copy link
Copy Markdown
Member Author

@nden @embray The astropy.modeling docs are a bit of a mess at the moment (Parameters and Returns sections for many methods outdated or missing). I'm not sure opening more pull requests is helpful at the moment ... anyways, here's some fixes:
cdeil@c851559

@astrofrog astrofrog added this to the v0.4.0 milestone May 9, 2014
@astrofrog

Copy link
Copy Markdown
Member

What is the status of this?

@embray

embray commented May 9, 2014

Copy link
Copy Markdown
Member

Well, @cdeil would have to rebase this before going anywhere with it. But it's probably not worth it at the moment.

@cdeil

cdeil commented May 27, 2014

Copy link
Copy Markdown
Member Author

@embray I'm closing this ... by now it would probably be better to re-start from master if something like this is considered useful.

@cdeil cdeil closed this May 27, 2014
@embray

embray commented May 27, 2014

Copy link
Copy Markdown
Member

I would like to leave it open for now merely so that I don't forget about it, as there are some good examples in it that I might like to use later. I will forget this exists otherwise.

I'll assign it to myself so you don't have to worry about it.

@embray embray reopened this May 27, 2014
@embray embray self-assigned this May 27, 2014
@astrofrog

Copy link
Copy Markdown
Member

Removing the milestone since it isn't intended for merging.

@astrofrog astrofrog removed this from the v1.0.0 milestone Jan 15, 2015
@astrofrog astrofrog assigned embray and unassigned embray Mar 21, 2015
@cdeil

cdeil commented Jan 25, 2016

Copy link
Copy Markdown
Member Author

It's been another two years.
I highly doubt this is a useful starting point for further work on astropy.modeling.
Closing this now.

@cdeil cdeil closed this Jan 25, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants