-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Hi,
I discovered a strange behavior playing with Sympy units and Dimensions.
Issue
From the Dimension class documentation, we can read « Addition and subtraction is defined only when the two objects are the same dimension. ».
This is, actually not true. It's impossible to add a Dimension with a Quantity, but adding two different dimensions is allowed:
>>> from sympy.physics.units.systems.si import length, velocity, time
>>> length + time + velocity
Dimension(length, L) + Dimension(time, T) + Dimension(velocity)Proposed Solution
Easy Fix
I took a look at the code and I was thinking about something like this to fix the issue: throw instead of returning super().__add__(other)
def __add__(self, other):
from sympy.physics.units.quantities import Quantity
other = sympify(other)
if isinstance(other, Basic):
if other.has(Quantity):
raise TypeError("cannot sum dimension and quantity")
if isinstance(other, Dimension) and self == other:
return self
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
else:
raise IncompatibleDimensionsError(f"Cannot sum {self} and {other} because these dimensions are different")
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
return selfThis now works as in the documentation.
Going further...
I don't think the fix above is satisfying anyway, because it will throw even with the following operation, despite it has a physical meaning:
>>> length + velocity*time
sympy.physics.units.dimensions.IncompatibleDimensionsError: Cannot sum Dimension(length, L) and Dimension(time*velocity) because these dimensions are differentThis is why, instead of equality, we could look for equivalence:
def __add__(self, other):
from sympy.physics.units.quantities import Quantity
other = sympify(other)
if isinstance(other, Basic):
if other.has(Quantity):
raise TypeError("cannot sum dimension and quantity")
# >>>>>>>>>>>>>>>>>>>>>>>>
if not self.is_equivalent_to(other):
raise IncompatibleDimensionsError(f"Cannot sum {self} and {other} because these dimensions are not equivalent.")
# <<<<<<<<<<<<<<<<<<<<<<<<
return selfBut it seems that Dimension objects don't know about the concept of "equivalence". This seems to belong to DimensionSystem instead. I think Dimension objects should know what they are composed of.
Note: this behavior is also allowed in Quantity class, we should override addition operators to disallow these inconsistent additions as well.
Let me know what is the best for you and I'll be glad to propose a PR.
Cheers,