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 self
This 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 different
This 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 self
But 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,
Hi,
I discovered a strange behavior playing with Sympy units and Dimensions.
Issue
From the
Dimensionclass 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
Dimensionwith aQuantity, but adding two different dimensions is allowed: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)This 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:
This is why, instead of equality, we could look for equivalence:
But it seems that
Dimensionobjects don't know about the concept of "equivalence". This seems to belong toDimensionSysteminstead. I thinkDimensionobjects should know what they are composed of.Note: this behavior is also allowed in
Quantityclass, 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,