Skip to content

np.abs(DeltaTime(dts)) returns object np.array not DeltaTime(abs(dts)) #10653

Open

Description

@taldcroft

Description

Using np.abs() on a DeltaTime object does not return the expected result.

Expected behavior

In [4]: dt = TimeDelta([-1, 1]*u.day)                                                                                                                         

In [5]: np.abs(dt)                                                                                                                                            
Out[5]: 
<TimeDelta object: scale='None' format='jd' value=[1. 1.]>

Actual behavior

In [4]: dt = TimeDelta([-1, 1]*u.day)                                                                                                                         

In [5]: np.abs(dt)                                                                                                                                            
Out[5]: 
array([<TimeDelta object: scale='None' format='jd' value=1.0>,
       <TimeDelta object: scale='None' format='jd' value=1.0>],
      dtype=object)

Steps to Reproduce

See above.

System Details

Darwin-19.5.0-x86_64-i386-64bit
Python 3.7.7 (default, Mar 26 2020, 10:32:53) 
[Clang 4.0.1 (tags/RELEASE_401/final)]
Numpy 1.18.1
astropy 4.2.dev518+g5dfce215b.d20200813
Scipy 1.4.1
Matplotlib 3.1.3

Activity

  1. mhvk commented on Aug 13, 2020

    @mhvk
    Contributor

    Arrgghh. To get this to work we need to implement __array_ufunc__ - not super-hard.

    Note that abs does work (since that just uses the method):

    In [6]: abs(dt)                                                                                        
    Out[6]: <TimeDelta object: scale='None' format='jd' value=[1. 1.]>
    
  2. mhvk commented on Aug 13, 2020

    @mhvk
    Contributor

    p.s. Right now, for the same reason, np.add, np.subtract, etc., do not work either create object arrays as well.

  3. Antetokounpo commented on Sep 27, 2020

    @Antetokounpo
    Contributor

    I've written a quick and dirty implementation of __array_ufunc__ and although it fixes the problems np.add, np.abs,, etc., it creates a whole lot of new ones. For example:

    >>> t0 = TimeDelta(10., format='jd')
    >>> q = 10. * u.one
    >>> q * t0
    <Quantity 100.>
    

    The expected behavior in this case would be that the returned result is a TimeDelta and not a Quantity. But I've noticed that this happens only if __array_ufunc__ is defined, even if it's only a simple pass (and it doesn't get called anyway). I haven't been able to track down why it happens though.

    So it seems that if we're going to implement __array_ufunc__ to fix this issue, we also need to modify how Quantity objects (and maybe others) interact with TimeDelta.

  4. mhvk commented on Sep 27, 2020

    @mhvk
    Contributor

    @Antetokounpo - Right now, without Time.__array_ufunc__, the quantity version never gets called because Time.__array_priority__ is defined and is higher than Quantity.__array_priority__. But if you do define Time.__array_ufunc__, then the priorities no longer get checked.

    But you did find a bug: Quantity.__array_ufunc__ should returning NotImplemented for any Time input, as it does not know how to deal with those. I raised #10776.

  5. mhvk commented on Sep 28, 2020

    @mhvk
    Contributor

    Note that @maxnoe has also started to implement Time.__array_ufunc__ - see #10272.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions