You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CartesianRepresentation objects could be made more powerful #5255
This is prompted by the code to create CartesianRepresentation objects for geographic velocities and positions in #5253 and the code snippet in #5231 to calculate barycentric velocity corrections.
@mhvk and I think it would be nice if CartesianRepresentation objects gained the ability to be added together or multiplied by Quantity objects. Indeed, one ought to be able to calculate the scalar and vector product of CartesianRepresentations as well.
After having a brief look at this, it is not quite as trivial as I thought it would be. The issue lies in the codebase for units.Quanitity.
You can implement __add__ and __radd__ on the CartesianRepresentation class, but the latter will never get called because the Quantity class already has an _add__ which gets called. This should return NotImplemented, but doesn't because Quantity.__array_prepare__ is called first and this raises Exceptions. So in summary:
@StuartLittlefair - I think all that would be needed is to define an __array_priority__ that is greater than that of Quantity.
(Of course, for addition itself, I would hope that it would not work with Quantity at all: which component should the number be added to? If we go ahead with this, we do have to think through carefully what we would like to work; I think it is a relatively limited set.)
I see your point about addition; I was thinking of it as a shift in origin, but on reflection it's not that intuitive and should probably not be allowed. In which case I propose the following changes:
CartesianRepresentations can be added and subtracted, but not multiplied?
CartesianRepresentations can be multiplied or divided by a Quantity
the dot and scalar product of CartesianRepresentations is defined
This sounds good (even if rather than a length property, I'd probably just have __abs__ return the length, just like for complex numbers).
Note that multiplication/division and abs are meaningful for all representations but UnitSpherical, while dot and perhaps even cross could go through CartesianRepresentation. But I don't think I would want to advocate defining addition and subtraction for any but cartesian coordinates.
In #5253, we originally introduced an __eq__ for representations, which ended up being taken out. Any follow-up here would be a good place to reintroduce this. I add the actual code below. @eteq had commented on this that
The point about the equality being the same shape as the representation should be mentioned here (although also see my comment inline).
Actually, this point should maybe even be added to the narrative docs, because it's behavior that is not really like anything else (it's sensible, but by no means obvious).
def __eq__(self, other):
"""
Check for equality with another representation.
"""
try:
# this ensures that other can be compared sensibly to self.
# note that it immediately returns if the classes are the same.
other = other.represent_as(self.__class__)
except Exception:
return False
# Ensure we return a bool or array of bool as appropriate.
return functools.reduce(np.logical_and,
(getattr(self, component) ==
getattr(other, component)
for component in self.components))
def __ne__(self, other):
return np.logical_not(self.__eq__(other))
Activity
StuartLittlefair commentedon Aug 25, 2016
After having a brief look at this, it is not quite as trivial as I thought it would be. The issue lies in the codebase for
units.Quanitity.You can implement
__add__and__radd__on theCartesianRepresentationclass, but the latter will never get called because theQuantityclass already has an_add__which gets called. This should returnNotImplemented, but doesn't becauseQuantity.__array_prepare__is called first and this raises Exceptions. So in summary:would work but
would raise a
TypeError.mhvk commentedon Aug 26, 2016
@StuartLittlefair - I think all that would be needed is to define an
__array_priority__that is greater than that ofQuantity.(Of course, for addition itself, I would hope that it would not work with
Quantityat all: which component should the number be added to? If we go ahead with this, we do have to think through carefully what we would like to work; I think it is a relatively limited set.)StuartLittlefair commentedon Aug 26, 2016
I see your point about addition; I was thinking of it as a shift in origin, but on reflection it's not that intuitive and should probably not be allowed. In which case I propose the following changes:
CartesianRepresentationscan be added and subtracted, but not multiplied?CartesianRepresentationscan be multiplied or divided by aQuantityCartesianRepresentationsis definedCartesianRepresentationgets alengthproperty.mhvk commentedon Aug 27, 2016
This sounds good (even if rather than a
lengthproperty, I'd probably just have__abs__return the length, just like for complex numbers).Note that multiplication/division and
absare meaningful for all representations butUnitSpherical, whiledotand perhaps evencrosscould go throughCartesianRepresentation. But I don't think I would want to advocate defining addition and subtraction for any but cartesian coordinates.StuartLittlefair commentedon Aug 28, 2016
Thanks for the comments @mhvk.
I'm away on holiday for three weeks from next Monday, so I'll probably leave this until after that.
mhvk commentedon Aug 31, 2016
In #5253, we originally introduced an
__eq__for representations, which ended up being taken out. Any follow-up here would be a good place to reintroduce this. I add the actual code below. @eteq had commented on this thatmhvk commentedon Sep 2, 2016
See my attempt in #5301. I think it is reasonably complete.
StuartLittlefair commentedon Nov 16, 2016
Closing on merge of #5301