-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Quantity Support in Modeling [continued] #4615
Conversation
# TODO: numerical test of results | ||
|
||
# A more complex test with an equivalency that depends on x values | ||
g_init.output_equivalencies = u.brightness_temperature, (3e-5 * u.sr, 'x') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the comma here is intentional and required, i.e. g_init.output_equivalencies = u.brightness_temperature(3e-5 * u.sr, 'x')
will not work because x
needs to be interpreted by the fitter? This is a bit subtle and easy-to-miss. Maybe output_equivalencies
should be required to be a dict of {'equivalencies': ..., 'kwargs': ...}
or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed this is needed because 'x' is not known until the model is evaluated. I described this a little more in test_output_units_equivalencies_with_parameters
. There may indeed be better ways to specify this syntax-wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope the implementation doesn't put any knowledge of quantities into the actual fitters (or at the very least simple wrappers around them).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@perrygreenfield - indeed, the idea in the fitters will be to get rid of units as soon as possible and add them back later
@astrofrog - Thanks! I skimmed the tests and this looks intuitive and nice. What about parameter errors? I think |
@cdeil, @astrofrog - for covariance matrices with different units for each element, there is an issue about this: #3777. As is, one can "cheat" and construct an |
Thanks everyone for the feedback so far! Here are my own thoughts on this API, triggered by your comments. The current system (including the unit spec, etc.) proposed here may be unnecessarily complicated in terms of setting up models that will be used to fit data with units. The main issue is that this API currently requires the model units to be fully spec-ed out before one can fit a model to data with units. In other words, m_init = Polynomial(degree=5)
m = fit(m_init, x * u.s, y * u.m) would not work (at least the way I've written the fitting tests at the moment). However, I think it's pretty clear that this should work and furthermore that One crucial piece of the puzzle to get this to work would be a way to transform a unitless model into a unitful model given the units of the data alone. In other words, if I have: p = Polynomial1D(degree=5) I should be able to do (with a better method name): pu = p.with_units_from_data(u.s, u.m) a m_init = Polynomial1D(degree=5)
m = fit(m_init, x * u.s, y * u.m) In this case, internally, the fitting method can drop the data units, do the fitting the normal way, then at the end call The other thing this allows is for users to specify initial values in a unitful way:
The question here is, can the units of the parameters always be determined from the units of the data the model is fit to? There are cases where the units of the model could be arbitrary and not related to the final data units (e.g. angle) but in those cases we can just pick arbitrarily. Are there cases where this logic wouldn't work? In terms of models alone (forgetting about fitting) we could allow parameters to be set to quantities and quantities to be passed as input to models in the same way as any other function, but without having any constraints hard-coded in the model (I think this is what @hamogu and @mhvk are suggesting) - the quantity arithmetic in Note that this and the previous suggestion about adding units to models then simplifies things a lot in some cases - for instance, if you're dealing with a Gaussian, you no longer need to worry about having to spec out that the mean and sigma need the same units. If you're just evaluating the model, this is taken care of by the arithmetic in There are a couple more things one can consider:
@hamogu @mhvk @perrygreenfield @cdeil @hcferguson @Cadair @keflavich - what do you think about these suggestions? |
# Instantiate with a different, but compatible unit | ||
m = TestModel(2.0 * u.pc) | ||
assert m.a.unit == u.pc | ||
assert m.a.value == 2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it doesn't convert to the default units in this case?
Is this possible / does this make sense? What would be the unit of the |
@cdeil - for a power law of the form
Does this make sense? There may be cases I'm not thinking of where this is not possible though? |
So just to clarify, if you are fitting data in units of rates (units: s^-1) then the amplitude would be a rate. |
@astrofrog - Yes, that makes sense. Thanks for explaining. As to whether this is a good idea to infer units from data automatically --- I don't know. >>> import this
...
Explicit is better than implicit.
... |
@cdeil - in the case of a 5th order polynomial, you probably wouldn't want to have to set the units of all the coefficients manually though. Do you mean that the following should return a model without units unless explicitly requested with an optional argument in
|
I agree that manually setting units for parameters of a polynomial model could be painful. |
Not necessarily - imagine you have a model with two gaussians and one polynomial background - in the current API described in this PR, you'd have to set the units on each of them before you try and fit the data, which is a fair number of parameters (yes the units would be simpler, but there's still a few...) |
@astrofrog You seem pretty sure that inferring the parameter units is a good idea. I'm just a sceptical guy and especially grumpy today. So please ignore me and go ahead! |
…et__), and make sure that setting Parameter.value takes a unitless value not a quantity.
… a model with parameters that have equivalencies attached to them.
…quire information about input values, and include an example of fitting a spectrum in Jy to data in K and in erg/cm^2/s/micron.
13453ea
to
1693687
Compare
I moved over the 1.2 milestone from #3852, feel free to change it as appropriate. |
See #4855 for a simplified version of this PR |
Implementation of units in models [simplified version of #4615]
This was superseded by #4855, which has now been merged |
Read me first!
This is a rebased continuation of @embray's #3852, and is still a work in progress, but I'll be pushing from time to time to make sure the CI doesn't break.
At this stage please only review the tests, which show a proposed API - do not comment on implementation (which is incomplete)
To-dos (some to-do list items are taken from @embray's list) - not all have to be done for this PR
input_units
/output_units
per instanceParameter
? (see WIP: Prototype for Quantity support in Models #3852)