Skip to content

units: operations on dimensionless units #862

Closed

Description

@mhvk

Hi,

in further playing with units, I tried something simple:

def doppler(v): return 1.+v/si.c
doppler(10. * u.km/u.s)

But this gives
TypeError: unsupported operand type(s) for +: 'int' and 'Quantity'

Of course, this can be resolved with

def doppler(v): return 1+(v/si.c).to(u.dimensionless_unscaled).value
doppler(10. * u.km/u.s)

Which gives
1.0000333564095198

But this seems needlessly inelegant. My suggestion would that if a Quantity can be made dimensionless, no complaint is made for addition, raising to non-half powers, etc. Similarly, for conversion to a numpy array, I would again suggest that if it is possible to convert to dimensionless units, this is done silently, reserving the warning for the case it is well-deserved (actually, if it were up to me, I'd raise an exception, as I think it is better to force the user to make an explicit choice). A specific advantage might be for, say, model atmosphere fitting. Currently:

g = (si.G*u.solMass/u.solRad**2)
np.log10((g/(u.cm/u.s**2)))

gives
WARNING: Converting Quantity object in units 'm3 solMass / (cm kg solRad2)' to a Numpy array [astropy.units.quantity] -10.175624209420819

Instead it would be nice if it would do the same as:

np.log10((g/(u.cm/u.s**2)).to(u.dimensionless_unscaled))

4.4384281484130499

(I realise np.log10(g.cgs) also gives the right answer, even if with the warning)

Thanks!

Marten

Activity

  1. embray commented on Mar 11, 2013

    @embray
    Member

    This issue was already discussed at great length in #669. In short, the current behavior is a tradeoff between convenience and clarity. What you're proposing here would involve too much "magic" in that it would hide actual errors and make them almost impossible to detect or catch early.

    In your doppler example a simpler way of doing it might be:

    def doppler(v):
        return 1 + (v / c).decompose().value
    

    In this case the decompose() returns a quantity in Unit(dimensionless). IF the unit is already in dimensionless AND the scale is 1.0 then maybe it would be okay to allow addition? I'm not sure though.

  2. mhvk commented on Mar 11, 2013

    @mhvk
    ContributorAuthor

    Thanks for pointing me to #669 -- quite a thread! However, as it explicitly concluded this was to be revisited for 0.3, perhaps I can make a start... I discussed off-line with @wkerzendorf and he certainly convinced me rules should be strict before anything else, i.e., force users to be explicit.

    As a reason for strictness, your example in #669 #669 (comment)) is interesting:

    from astropy.units import Quantity as Q
    v = Q((1, 2, 3), 'm/s')
    v / np.linalg.norm(v)
    

    which currently gives

    WARNING: Converting Quantity object in units 'm / (s)' to a Numpy array [astropy.units.quantity]
    <Quantity [ 0.26726124  0.53452248  0.80178373] m / (s)>
    

    This is wrong physically, of course (answer should be dimensionless), and it seems unclear whether any convenience is worth getting out something wrong in a way that might easily propagate and cause problems much further down.

    Back to my example, in some sense your suggestion is an example of why perhaps one might wish to treat the dimensionless differently:

    from astropy import constants
    from astropy.units import Quantity as Q
    def doppler(v):
        return 1 + (v / constants.c).decompose().value
    doppler(Q(1,'Mm'))
    

    which yields 1.0033356409519816 without any warning, ie., one has lost a nice benefit of using quantities, that it catches dimensional mistakes.

    After reading the thread, it is clear this is a complicated issue; I think I'd still tend to argue for Germanic strictness, though perhaps a slight Dutch touch in "doing the right thing" for quantities that can be made dimensionless.

  3. mhvk commented on Jul 25, 2013

    @mhvk
    ContributorAuthor

    solved by #929 - thanks @astrofrog!

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