Skip to content

Add unit-checking math functions #955

Closed

Description

@mdboom

I don't yet know if this is a good idea, or I'm inadvertently writing a belated April Fools' joke, but...

It might be handy to have a set of math functions that do unit checking and take and return Quantities (or Angles -- but those are soon be more-or-less the same thing).

For example:

    >>> q = 90 * u.degree
    >>> astropy.units.math.sin(q)
    1.0
    >>> astropy.units.math.arcsin(1.0)
    <Quantity 1.57079632679 rad>
    >>> _.degree
    90.0

I think that these should be strict about requiring quantities and not raw unadorned Numpy arrays, otherwise users will just try to bypass the type-checking by putting .value everywhere and we'll have gained nothing. These functions already exist without unit checking in Numpy, so if that's what the user wants, they should use those.

Activity

  1. mdboom commented on Apr 8, 2013

    @mdboom
    ContributorAuthor

    While the obvious application of this is angles with trig functions, are there any other use cases?

  2. eteq commented on Apr 8, 2013

    @eteq
    Member

    Exponentials and logs in principal should only work with unitless numbers. For logarithms, there's a tradition in astronomy of taking the logs of united things (implicitly meaning the log of the value divided by its unit), though.

    #929 might do this for "free" (or at least cheap), though. If we make Quantity into an ndarray, I think we can re-define the relevant ufuncs to check units. I think that's possible, anyway.

  3. mhvk commented on Apr 9, 2013

    @mhvk
    Contributor

    If one could deal with the unitless numbers the same way, that would be fantastic. Would this resolve #669? Might also go at least some way (@eteq: all way?) towards #862, i.e., being able to do 1+v/c and get out a unitless quantity.

  4. embray commented on Apr 10, 2013

    @embray
    Member

    Somewhere in my future I see a big patch to Numpy being worked on.... :/

  5. eteq commented on Apr 10, 2013

    @eteq
    Member

    I don't think it fully addresses #862 - the problem there is that sometimes a user wants scaled but dimensionless units. E.g., log10(1 * u.km / u.m) - does the user want 0, or 3 ? So instead of guessing, we could just fail and force the user to be explicit - that is, only dimensionless and unscaled values count.

  6. eteq commented on Apr 10, 2013

    @eteq
    Member

    (It definitely does help with some of the concerns of #669, though!)

  7. mhvk commented on Apr 11, 2013

    @mhvk
    Contributor

    @eteq: I am not sure I agree the example undermines the case for doing the right thing with dimensionless quantiteis. On the specific example of doing log10(1*u.km/u.m), it seems really odd to think the user would ever want anything else than 3; It feels so wrong physically!
    But of course there are cases where dimensions are odd in astronomy, with perhaps the most famous example being the Hubble constant. But even there, I failed to come up with an example where one would like to keep the odd unit. E.g., suppose one defined h=70 u.km/u.s/u.Mpc, and had a galaxy with an apparent magnitude m and some recession velocity v, I'd think that it would be nice to calculate the absolute magnitude simply with M=m-5*log10(v/h/(10*u.pc)), without worrying whether v is in m/s or in km/s, or about the scaling between Mpc and pc. I give this example in part since in the cases where I used quantity so far, what I really like is that I do not have to know what the exact units and scales are -- this all gets taken care of!
    I realise that there are astronomical cases where the log is taken of a quantity with units; the one I've done most myself is surface gravity g. For that case, though, I find it hard to believe anybody would want to write log10(g) and just count on it being in cgs already. Instead, I'd guess one could write something like log10(g.cgs.value), or, more safely (since it does a unit check), log10(g/(u.cm/u.s**2)).
    In the end, I think the analogy with angles remains instructive; writing an example equivalent to yours, I think one would want to automatically convert to radians when encountering, e.g., sin(1 * u.arcsec/u.century * 10 u.yr). And probably raise an exception for sin(1*u.km). It seems then logical to do the same for log, etc. (and I'd argue also throw an exception rather than a warning if the quantity has units, however annoying this will be in plotting... Though maybe @mdboom can make matplotlib Quantity-aware...).

  8. wkerzendorf commented on Apr 11, 2013

    @wkerzendorf
    Member

    I've just been pointed to this by @mhvk. I think that is actually a very good idea to re-implement some of these functions sin, log, .... as astropy versions as we can also teach it to deal with uncertainties (as has been done in the uncertainties python package. 👍 to this idea.

  9. eteq commented on Apr 15, 2013

    @eteq
    Member

    @mhvk - You may be right - it's true that for the trig functions it seems perfectly natural, and it's hard to give a clear reason for why log/log10 is any different. I'm mainly just inclined to make users use decompose as an "insurance policy" requiring that the user stop and think about what they're actually meaning to do. To apply this to one of your examples, I would not could on users to do log10(g/(u.cm/u.s**2)) on their own without first trying log10(g) and encountering an exception - that's the sort of insurance against assumptions that I'm thinking about here. But maybe I'm just being overly-paranoid for the users...

    On an earlier topic, the more I think about it, the more I'm a bit worried about astropy.units.math.sin. I already see a lot of people (both new and experienced pythonistas) making mistakes and incorrect assumptions about math.sin vs. numpy.sin. Adding a third one seems potentially dangerous. So I think I would instead advocate for trying to override the behavior of the relevant ufuncs in numpy for Quantity objects (if this is possible). Then we can continue to tell everyone to just do np.sin(q).

  10. mhvk commented on Aug 9, 2013

    @mhvk
    Contributor

    @mdboom - now that #929 is in, I think this can be closed, right?

  11. embray commented on Nov 12, 2013

    @embray
    Member

    I like how this started out as a possible April Fools' joke...

  12. astrofrog commented on Nov 12, 2013

    @astrofrog
    Member

    Well, the whole concept of Quantity started after a drink or two (or three)!

  13. mhvk commented on Nov 12, 2013

    @mhvk
    Contributor

    Yes, it truly is amazing. To see what 1 nanoarcsecond really meant (we're trying to reach such precision by using the interstellar medium as a telescope -- with pulsar scintellation), I just happened to do:

    In [9]: (2.54*u.cm/np.tan(1*u.narcsec)).to(u.au)
    Out[9]: <Quantity 35.021394717460026 AU>
    

    i.e, resolving a quarter (almost) on Pluto... So trivial to do now...

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions