Skip to content

Incompatible dimensions can be added #25754

@Teskann

Description

@Teskann

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,

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions