From 69d0a89177fa725478a963dd3c77fb946ee58d67 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Mon, 19 Feb 2024 15:13:26 +0100 Subject: [PATCH 01/11] feat: allow momentum coords in to_Vector*D methods + cleanup feat: error while out on operations on vectors of different geomtric dimensions + new `like` method --- .gitignore | 3 + src/vector/_methods.py | 142 +++++++--- tests/backends/test_awkward.py | 263 ++++++++++-------- tests/backends/test_numpy.py | 161 ----------- tests/backends/test_object.py | 75 ------ tests/compute/test_conversions.py | 427 ++++++++++++++++++++++++++++++ tests/test_methods.py | 30 ++- 7 files changed, 701 insertions(+), 400 deletions(-) diff --git a/.gitignore b/.gitignore index 1c09a8df..28e662a6 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,6 @@ dmypy.json /node_modules /package.json /yarn.lock + +# MacOS +.DS_Store diff --git a/src/vector/_methods.py b/src/vector/_methods.py index d8febb3e..5ce3b7c6 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -184,7 +184,9 @@ def to_Vector3D(self) -> VectorProtocolSpatial: Projects this vector/these vectors onto azimuthal and longitudinal coordinates only. - If 2D, a $z$ component of $0$ is imputed. + If 2D, a default $z$ component of $0$ is imputed. + + The longitudinal coordinate can be passed as a named argument. """ raise AssertionError @@ -193,9 +195,12 @@ def to_Vector4D(self) -> VectorProtocolLorentz: Projects this vector/these vectors onto azimuthal, longitudinal, and temporal coordinates. - If 2D or 3D, a $t$ component of $0$ is imputed. + If 3D, a default $t$ component of $0$ is imputed. + + If 2D, a $z$ component of $0$ is imputed along with a default + $t$ component of $0$. - If 2D, a $z$ component of $0$ is imputed. + The longitudinal and temporal coordinates can be passed as named arguments. """ raise AssertionError @@ -563,6 +568,31 @@ def isclose( """ raise AssertionError + def like(self, other: VectorProtocol) -> VectorProtocol: + """ + Projects the vector into the geometric coordinates of the `other` + vector. + + Value(s) of $0$ is/are imputed while transforming vector from a lower + geometric dimension to a higher geometric dimension. + + .. code-block:: python + + vec_4d + vec_3d.like(vec_4d) + + For more flexibility (passing new coordinate values), see + :meth:`vector._methods.Vector2D.to_Vector3D`, + :meth:`vector._methods.Vector2D.to_Vector4D`, and + :meth:`vector._methods.Vector3D.to_Vector4D`, which can be used as: + + .. code-block:: python + + vec_2d.to_Vector3D(z=3.0) + vec_2d.to_Vector4D(z=3.0, t=4.0) + vec_3d.to_Vector4D(t=4.0) + """ + raise AssertionError + class VectorProtocolPlanar(VectorProtocol): @property @@ -3154,6 +3184,14 @@ def to_ptphithetamass(self) -> VectorProtocolLorentz: def to_ptphietamass(self) -> VectorProtocolLorentz: return self.to_rhophietatau() + def like(self, other: VectorProtocol) -> VectorProtocol: + if isinstance(other, Vector2D): + return self.to_Vector2D() + elif isinstance(other, Vector3D): + return self.to_Vector3D() + else: + return self.to_Vector4D() + class Vector2D(Vector, VectorProtocolPlanar): def to_Vector2D(self) -> VectorProtocolPlanar: @@ -3163,6 +3201,7 @@ def to_Vector3D( self, *, z: float | None = None, + pz: float | None = None, theta: float | None = None, eta: float | None = None, ) -> VectorProtocolSpatial: @@ -3170,8 +3209,7 @@ def to_Vector3D( Converts a 2D vector to 3D vector. The scalar longitudinal coordinate is broadcasted for NumPy and Awkward - vectors. Only a single longitudinal coordinate should be provided. Generic - coordinate counterparts should be provided for the momentum coordinates. + vectors. Only a single longitudinal coordinate should be provided. Examples: >>> import vector @@ -3179,18 +3217,18 @@ def to_Vector3D( >>> vec.to_Vector3D(z=1) VectorObject3D(x=1, y=2, z=1) >>> vec = vector.MomentumObject2D(px=1, py=2) - >>> vec.to_Vector3D(z=4) + >>> vec.to_Vector3D(pz=4) MomentumObject3D(px=1, py=2, pz=4) """ if sum(x is not None for x in (z, theta, eta)) > 1: raise TypeError( - "At most one longitudinal coordinate (`z`, `theta`, or `eta`) may be assigned (non-None)" + "At most one longitudinal coordinate (`z`/`pz`, `theta`, or `eta`) may be assigned (non-None)" ) l_value = 0.0 l_type: type[Longitudinal] = LongitudinalZ - if z is not None: - l_value = z + if any(coord is not None for coord in [z, pz]): + l_value = next(coord for coord in [z, pz] if coord is not None) elif eta is not None: l_value = eta l_type = LongitudinalEta @@ -3209,18 +3247,24 @@ def to_Vector4D( self, *, z: float | None = None, + pz: float | None = None, theta: float | None = None, eta: float | None = None, t: float | None = None, + e: float | None = None, + E: float | None = None, + energy: float | None = None, tau: float | None = None, + m: float | None = None, + M: float | None = None, + mass: float | None = None, ) -> VectorProtocolLorentz: """ Converts a 2D vector to 4D vector. The scalar longitudinal and temporal coordinates are broadcasted for NumPy and Awkward vectors. Only a single longitudinal and temporal coordinate should be - provided. Generic coordinate counterparts should be provided for the momentum - coordinates. + provided. Examples: >>> import vector @@ -3228,30 +3272,30 @@ def to_Vector4D( >>> vec.to_Vector4D(z=3, t=4) VectorObject4D(x=1, y=2, z=3, t=4) >>> vec = vector.MomentumObject2D(px=1, py=2) - >>> vec.to_Vector4D(z=4, t=4) + >>> vec.to_Vector4D(pz=4, energy=4) MomentumObject4D(px=1, py=2, pz=4, E=4) """ if sum(x is not None for x in (z, theta, eta)) > 1: raise TypeError( - "At most one longitudinal coordinate (`z`, `theta`, or `eta`) may be assigned (non-None)" + "At most one longitudinal coordinate (`z`/`pz`, `theta`, or `eta`) may be assigned (non-None)" ) elif sum(x is not None for x in (t, tau)) > 1: raise TypeError( - "At most one longitudinal coordinate (`t`, `tau`) may be assigned (non-None)" + "At most one longitudinal coordinate (`t`/`e`/`E`/`energy`, `tau`/`m`/`M`/`mass`) may be assigned (non-None)" ) t_value = 0.0 t_type: type[Temporal] = TemporalT - if t is not None: - t_value = t - elif tau is not None: - t_value = tau + if any(coord is not None for coord in [tau, m, M, mass]): t_type = TemporalTau + t_value = next(coord for coord in [tau, m, M, mass] if coord is not None) + elif any(coord is not None for coord in [t, e, E, energy]): + t_value = next(coord for coord in [t, e, E, energy] if coord is not None) l_value = 0.0 l_type: type[Longitudinal] = LongitudinalZ - if z is not None: - l_value = z + if any(coord is not None for coord in [z, pz]): + l_value = next(coord for coord in [z, pz] if coord is not None) elif eta is not None: l_value = eta l_type = LongitudinalEta @@ -3283,14 +3327,19 @@ def to_Vector4D( self, *, t: float | None = None, + e: float | None = None, + E: float | None = None, + energy: float | None = None, tau: float | None = None, + m: float | None = None, + M: float | None = None, + mass: float | None = None, ) -> VectorProtocolLorentz: """ Converts a 3D vector to 4D vector. The scalar temporal coordinate are broadcasted for NumPy and Awkward vectors. - Only a single temporal coordinate should be provided. Generic coordinate - counterparts should be provided for the momentum coordinates. + Only a single temporal coordinate should be provided. Examples: >>> import vector @@ -3298,21 +3347,21 @@ def to_Vector4D( >>> vec.to_Vector4D(t=4) VectorObject4D(x=1, y=2, z=3, t=4) >>> vec = vector.MomentumObject3D(px=1, py=2, pz=3) - >>> vec.to_Vector4D(tau=4) + >>> vec.to_Vector4D(M=4) MomentumObject4D(px=1, py=2, pz=3, mass=4) """ if sum(x is not None for x in (t, tau)) > 1: raise TypeError( - "At most one longitudinal coordinate (`t`, `tau`) may be assigned (non-None)" + "At most one longitudinal coordinate (`t`/`e`/`E`/`energy`, `tau`/`m`/`M`/`mass`) may be assigned (non-None)" ) t_value = 0.0 t_type: type[Temporal] = TemporalT - if t is not None: - t_value = t - elif tau is not None: - t_value = tau + if any(coord is not None for coord in [tau, m, M, mass]): t_type = TemporalTau + t_value = next(coord for coord in [tau, m, M, mass] if coord is not None) + elif any(coord is not None for coord in [t, e, E, energy]): + t_value = next(coord for coord in [t, e, E, energy] if coord is not None) return self._wrap_result( type(self), @@ -4390,17 +4439,32 @@ def _handler_of(*objects: VectorProtocol) -> VectorProtocol: assert handler is not None - if _check_instance(all, objects, Vector): - # if there is a 2D vector in objects - if _check_instance(any, objects, Vector2D): - handler = _demote_handler_vector( - handler, objects, Vector2D, handler.to_Vector2D() - ) - # if there is no 2D vector but a 3D vector in objects - elif _check_instance(any, objects, Vector3D): - handler = _demote_handler_vector( - handler, objects, Vector3D, handler.to_Vector3D() - ) + if _check_instance(all, objects, Vector) and ( + ( + _check_instance(any, objects, Vector2D) + and _check_instance(any, objects, Vector3D) + ) + or ( + _check_instance(any, objects, Vector2D) + and _check_instance(any, objects, Vector4D) + ) + or ( + _check_instance(any, objects, Vector3D) + and _check_instance(any, objects, Vector4D) + ) + ): + raise TypeError( + """cannot perform the operation on vectors of different dimensionality; use + + a.like(b) + b + + or + + a + b.like(a) + + to project or embed one of the vectors to match the other's dimensionality + """ + ) return handler diff --git a/tests/backends/test_awkward.py b/tests/backends/test_awkward.py index 1c1ca931..f2671063 100644 --- a/tests/backends/test_awkward.py +++ b/tests/backends/test_awkward.py @@ -11,7 +11,7 @@ import pytest import vector -from vector import VectorObject2D, VectorObject3D, VectorObject4D +from vector import VectorObject2D, VectorObject4D ak = pytest.importorskip("awkward") @@ -70,6 +70,36 @@ def test_dimension_conversion(): assert ak.all(vec.to_Vector4D(t=1).y == vec.y) assert ak.all(vec.to_Vector4D(t=1).z == vec.z) + # check if momentum coords work + vec = vector.Array( + [ + [{"px": 1, "py": 1.1}, {"px": 2, "py": 2.1}], + [], + ] + ) + assert ak.all(vec.to_Vector3D(pz=1).pz == 1) + + assert ak.all(vec.to_Vector4D(pz=1, m=1).pz == 1) + assert ak.all(vec.to_Vector4D(pz=1, m=1).m == 1) + assert ak.all(vec.to_Vector4D(pz=1, mass=1).mass == 1) + assert ak.all(vec.to_Vector4D(pz=1, M=1).M == 1) + assert ak.all(vec.to_Vector4D(pz=1, e=1).e == 1) + assert ak.all(vec.to_Vector4D(pz=1, energy=1).energy == 1) + assert ak.all(vec.to_Vector4D(pz=1, E=1).E == 1) + + vec = vector.Array( + [ + [{"px": 1, "py": 1.1, "pz": 1.2}, {"px": 2, "py": 2.1, "pz": 2.2}], + [], + ] + ) + assert ak.all(vec.to_Vector4D(m=1).m == 1) + assert ak.all(vec.to_Vector4D(mass=1).mass == 1) + assert ak.all(vec.to_Vector4D(M=1).M == 1) + assert ak.all(vec.to_Vector4D(e=1).e == 1) + assert ak.all(vec.to_Vector4D(energy=1).energy == 1) + assert ak.all(vec.to_Vector4D(E=1).E == 1) + def test_type_checks(): with pytest.raises(TypeError): @@ -605,7 +635,7 @@ def test_count_4d(): ] -def test_demotion(): +def test_like(): v1 = vector.zip( { "x": [10.0, 20.0, 30.0], @@ -634,6 +664,13 @@ def test_demotion(): "y": [-20.0, 40.0, 60.0], }, ) + v2_v1 = vector.zip( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [5.0, 1.0, 1.0], + }, + ) v2_v3 = vector.zip( { "x": [20.0, 40.0, 60.0], @@ -641,20 +678,48 @@ def test_demotion(): "z": [10.0, 2.0, 2.0], }, ) + v3_v2 = vector.zip( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [10.0, 2.0, 2.0], + "t": [16.0, 31.0, 46.0], + }, + ) v1_v3 = vector.zip( { "x": [20.0, 40.0, 60.0], "y": [-20.0, 40.0, 60.0], + "z": [5.0, 1.0, 1.0], + "t": [16.0, 31.0, 46.0], }, ) - # order should not matter - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # 2D + 3D.like(2D) = 2D + assert ak.all(v1 + v2.like(v1) == v1_v2) + assert ak.all(v2.like(v1) + v1 == v1_v2) + # 2D + 4D.like(2D) = 2D + assert ak.all(v1 + v3.like(v1) == v1_v2) + assert ak.all(v3.like(v1) + v1 == v1_v2) + # 3D + 2D.like(3D) = 3D + assert ak.all(v2 + v1.like(v2) == v2_v1) + assert ak.all(v1.like(v2) + v2 == v2_v1) + # 3D + 4D.like(3D) = 3D + assert ak.all(v2 + v3.like(v2) == v2_v3) + assert ak.all(v3.like(v2) + v2 == v2_v3) + # 4D + 2D.like(4D) = 4D + assert ak.all(v3 + v1.like(v3) == v1_v3) + assert ak.all(v1.like(v3) + v3 == v1_v3) + # 4D + 3D.like(4D) = 4D + assert ak.all(v3 + v2.like(v3) == v3_v2) + assert ak.all(v2.like(v3) + v3 == v3_v2) v1 = vector.zip( { @@ -678,13 +743,31 @@ def test_demotion(): }, ) - # order should not matter - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # 2D + 3D.like(2D) = 2D + assert ak.all(v1 + v2.like(v1) == v1_v2) + assert ak.all(v2.like(v1) + v1 == v1_v2) + # 2D + 4D.like(2D) = 2D + assert ak.all(v1 + v3.like(v1) == v1_v2) + assert ak.all(v3.like(v1) + v1 == v1_v2) + # 3D + 2D.like(3D) = 3D + assert ak.all(v2 + v1.like(v2) == v2_v1) + assert ak.all(v1.like(v2) + v2 == v2_v1) + # 3D + 4D.like(3D) = 3D + assert ak.all(v2 + v3.like(v2) == v2_v3) + assert ak.all(v3.like(v2) + v2 == v2_v3) + # 4D + 2D.like(4D) = 4D + assert ak.all(v3 + v1.like(v3) == v1_v3) + assert ak.all(v1.like(v3) + v3 == v1_v3) + # 4D + 3D.like(4D) = 4D + assert ak.all(v3 + v2.like(v3) == v3_v2) + assert ak.all(v2.like(v3) + v3 == v3_v2) v2 = vector.zip( { @@ -695,16 +778,28 @@ def test_demotion(): ) # momentum + generic = generic - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) + # 2D + 3D.like(2D) = 2D + assert ak.all(v1 + v2.like(v1) == v1_v2) + assert ak.all(v2.like(v1) + v1 == v1_v2) + # 2D + 4D.like(2D) = 2D + assert ak.all(v1 + v3.like(v1) == v1_v2) + assert ak.all(v3.like(v1) + v1 == v1_v2) + # 3D + 2D.like(3D) = 3D + assert ak.all(v2 + v1.like(v2) == v2_v1) + assert ak.all(v1.like(v2) + v2 == v2_v1) + # 3D + 4D.like(3D) = 3D + assert ak.all(v2 + v3.like(v2) == v2_v3) + assert ak.all(v3.like(v2) + v2 == v2_v3) + # 4D + 2D.like(4D) = 4D + assert ak.all(v3 + v1.like(v3) == v1_v3) + assert ak.all(v1.like(v3) + v3 == v1_v3) + # 4D + 3D.like(4D) = 4D + assert ak.all(v3 + v2.like(v3) == v3_v2) + assert ak.all(v2.like(v3) + v3 == v3_v2) def test_handler_of(): - awkward_a = vector.zip( + awkward_vec = vector.zip( { "x": [10.0, 20.0, 30.0], "y": [-10.0, 20.0, 30.0], @@ -712,51 +807,33 @@ def test_handler_of(): "t": [16.0, 31.0, 46.0], }, ) - object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(awkward_a, object_b) - # chooses awkward backend and converts the vector to 2D - assert all(protocol == awkward_a.to_Vector2D()) - - awkward_a = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - }, - ) - object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_b, awkward_a) - # chooses awkward backend and the vector is already of the - # lower dimension - assert all(protocol == awkward_a) + object_vec = VectorObject2D.from_xy(1.0, 1.0) + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(awkward_vec, object_vec) + protocol = vector._methods._handler_of(awkward_vec, object_vec.like(awkward_vec)) + # chooses awkward backend + assert all(protocol == awkward_vec) - awkward_a = vector.zip( + awkward_vec = vector.zip( { "x": [10.0, 20.0, 30.0], "y": [-10.0, 20.0, 30.0], }, ) - awkward_b = vector.zip( - { - "x": [1.0, 2.0, 3.0], - "y": [-1.0, 2.0, 3.0], - "z": [5.0, 10.0, 15.0], - "t": [16.0, 31.0, 46.0], - }, - ) - object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_b, awkward_a, awkward_b) - # chooses awkward backend and the 2D awkward vector - # (first encountered awkward vector) - assert all(protocol == awkward_a) + object_vec = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(awkward_vec, object_vec) + protocol = vector._methods._handler_of(object_vec, awkward_vec.like(object_vec)) + # chooses awkward backend + assert all(protocol == awkward_vec.like(object_vec)) - awkward_a = vector.zip( + awkward_vec = vector.zip( { "x": [10.0, 20.0, 30.0], "y": [-10.0, 20.0, 30.0], - "z": [-10.0, 20.0, 30.0], }, ) - awkward_b = vector.zip( + awkward_vec2 = vector.zip( { "x": [1.0, 2.0, 3.0], "y": [-1.0, 2.0, 3.0], @@ -764,41 +841,24 @@ def test_handler_of(): "t": [16.0, 31.0, 46.0], }, ) - object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(awkward_b, object_b, awkward_a) - # chooses awkward backend and converts awkward_b to 2D - # (first encountered awkward vector) - assert all(protocol == awkward_b.to_Vector2D()) - - awkward_a = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - awkward_b = vector.zip( - { - "x": [1.0, 2.0, 3.0], - "y": [-1.0, 2.0, 3.0], - "z": [5.0, 10.0, 15.0], - "t": [16.0, 31.0, 46.0], - }, + object_vec = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_vec, awkward_vec, awkward_vec2) + protocol = vector._methods._handler_of( + object_vec, awkward_vec.like(awkward_vec2), awkward_vec2 ) - object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(object_b, awkward_a, awkward_b) - # chooses awkward backend and converts the vector to 2D - # (the first awkward vector encountered is used as the base) - assert all(protocol == awkward_a.to_Vector2D()) + # chooses awkward backend and the + # first encountered awkward vector + assert all(protocol == awkward_vec.like(awkward_vec2)) - numpy_a = vector.array( + numpy_vec = vector.array( { "x": [1.1, 1.2, 1.3, 1.4, 1.5], "y": [2.1, 2.2, 2.3, 2.4, 2.5], "z": [3.1, 3.2, 3.3, 3.4, 3.5], } ) - awkward_b = vector.zip( + awkward_vec2 = vector.zip( { "x": [1.0, 2.0, 3.0], "y": [-1.0, 2.0, 3.0], @@ -806,37 +866,14 @@ def test_handler_of(): "t": [16.0, 31.0, 46.0], }, ) - object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(object_b, numpy_a, awkward_b) - # chooses awkward backend and converts the vector to 2D - assert all(protocol == awkward_b.to_Vector2D()) - - awkward_a = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - numpy_a = vector.array( - { - "x": [1.1, 1.2, 1.3, 1.4, 1.5], - "y": [2.1, 2.2, 2.3, 2.4, 2.5], - } - ) - awkward_b = vector.zip( - { - "x": [1.0, 2.0, 3.0], - "y": [-1.0, 2.0, 3.0], - "z": [5.0, 10.0, 15.0], - "t": [16.0, 31.0, 46.0], - }, + object_vec = VectorObject2D.from_xy(1.0, 1.0) + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_vec, awkward_vec, numpy_vec) + protocol = vector._methods._handler_of( + object_vec, numpy_vec.like(object_vec), awkward_vec2.like(object_vec) ) - object_b = VectorObject3D.from_xyz(1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_b, awkward_a, awkward_b, numpy_a) - # chooses awkward backend and converts the vector to 2D - # (the first awkward vector encountered is used as the base) - assert all(protocol == awkward_a.to_Vector2D()) + # chooses awkward backend + assert all(protocol == awkward_vec2.to_Vector2D()) def test_momentum_coordinate_transforms(): diff --git a/tests/backends/test_numpy.py b/tests/backends/test_numpy.py index e1a389de..431e5cea 100644 --- a/tests/backends/test_numpy.py +++ b/tests/backends/test_numpy.py @@ -14,49 +14,6 @@ import vector.backends.numpy -def test_dimension_conversion(): - # 2D -> 3D - vec = vector.VectorNumpy2D( - [(1.0, 1.0), (2.0, 2.0)], - dtype=[("x", float), ("y", float)], - ) - assert all(vec.to_Vector3D(z=1).z == 1) - assert all(vec.to_Vector3D(eta=1).eta == 1) - assert all(vec.to_Vector3D(theta=1).theta == 1) - - assert all(vec.to_Vector3D(z=1).x == vec.x) - assert all(vec.to_Vector3D(z=1).y == vec.y) - - # 2D -> 4D - assert all(vec.to_Vector4D(z=1, t=1).t == 1) - assert all(vec.to_Vector4D(z=1, t=1).z == 1) - assert all(vec.to_Vector4D(eta=1, t=1).eta == 1) - assert all(vec.to_Vector4D(eta=1, t=1).t == 1) - assert all(vec.to_Vector4D(theta=1, t=1).theta == 1) - assert all(vec.to_Vector4D(theta=1, t=1).t == 1) - assert all(vec.to_Vector4D(z=1, tau=1).z == 1) - assert all(vec.to_Vector4D(z=1, tau=1).tau == 1) - assert all(vec.to_Vector4D(eta=1, tau=1).eta == 1) - assert all(vec.to_Vector4D(eta=1, tau=1).tau == 1) - assert all(vec.to_Vector4D(theta=1, tau=1).theta == 1) - assert all(vec.to_Vector4D(theta=1, tau=1).tau == 1) - - assert all(vec.to_Vector4D(z=1, t=1).x == vec.x) - assert all(vec.to_Vector4D(z=1, t=1).y == vec.y) - - # 3D -> 4D - vec = vector.VectorNumpy3D( - [(1.0, 1.0, 1.0), (2.0, 2.0, 2.0)], - dtype=[("x", float), ("y", float), ("z", float)], - ) - assert all(vec.to_Vector4D(t=1).t == 1) - assert all(vec.to_Vector4D(tau=1).tau == 1) - - assert all(vec.to_Vector4D(t=1).x == vec.x) - assert all(vec.to_Vector4D(t=1).y == vec.y) - assert all(vec.to_Vector4D(t=1).z == vec.z) - - def test_type_checks(): with pytest.raises(TypeError): vector.backends.numpy.VectorNumpy2D( @@ -486,121 +443,3 @@ def test_count_nonzero_4d(): assert numpy.count_nonzero(v2, axis=1, keepdims=True).tolist() == [[3], [2]] assert numpy.count_nonzero(v2, axis=0).tolist() == [2, 2, 1] assert numpy.count_nonzero(v2, axis=0, keepdims=True).tolist() == [[2, 2, 1]] - - -def test_demotion(): - v1 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - }, - ) - v2 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - v3 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - "t": [16.0, 31.0, 46.0], - }, - ) - - v1_v2 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - }, - ) - v2_v3 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - "z": [10.0, 2.0, 2.0], - }, - ) - v1_v3 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - }, - ) - - # order should not matter - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) - - v1 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - }, - ) - v2 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - "pz": [5.0, 1.0, 1.0], - }, - ) - v3 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - "pz": [5.0, 1.0, 1.0], - "t": [16.0, 31.0, 46.0], - }, - ) - - p_v1_v2 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - }, - ) - p_v2_v3 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - "pz": [10.0, 2.0, 2.0], - }, - ) - p_v1_v3 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - }, - ) - - # order should not matter - assert all(v1 + v2 == p_v1_v2) - assert all(v2 + v1 == p_v1_v2) - assert all(v1 + v3 == p_v1_v3) - assert all(v3 + v1 == p_v1_v3) - assert all(v2 + v3 == p_v2_v3) - assert all(v3 + v2 == p_v2_v3) - - v2 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - - # momentum + generic = generic - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) diff --git a/tests/backends/test_object.py b/tests/backends/test_object.py index c50598c2..bad95740 100644 --- a/tests/backends/test_object.py +++ b/tests/backends/test_object.py @@ -11,43 +11,6 @@ import vector -def test_dimension_conversion(): - # 2D -> 3D - vec = vector.VectorObject2D(x=1, y=2) - assert vec.to_Vector3D(z=1).z == 1 - assert vec.to_Vector3D(eta=1).eta == 1 - assert vec.to_Vector3D(theta=1).theta == 1 - - assert vec.to_Vector3D(z=1).x == vec.x - assert vec.to_Vector3D(z=1).y == vec.y - - # 2D -> 4D - assert vec.to_Vector4D(z=1, t=1).z == 1 - assert vec.to_Vector4D(z=1, t=1).t == 1 - assert vec.to_Vector4D(eta=1, t=1).eta == 1 - assert vec.to_Vector4D(eta=1, t=1).t == 1 - assert vec.to_Vector4D(theta=1, t=1).theta == 1 - assert vec.to_Vector4D(theta=1, t=1).t == 1 - assert vec.to_Vector4D(z=1, tau=1).z == 1 - assert vec.to_Vector4D(z=1, tau=1).tau == 1 - assert vec.to_Vector4D(eta=1, tau=1).eta == 1 - assert vec.to_Vector4D(eta=1, tau=1).tau == 1 - assert vec.to_Vector4D(theta=1, tau=1).theta == 1 - assert vec.to_Vector4D(theta=1, tau=1).tau == 1 - - assert vec.to_Vector4D(z=1, t=1).x == vec.x - assert vec.to_Vector4D(z=1, t=1).y == vec.y - - # 3D -> 4D - vec = vector.VectorObject3D(x=1, y=2, z=3) - assert vec.to_Vector4D(t=1).t == 1 - assert vec.to_Vector4D(tau=1).tau == 1 - - assert vec.to_Vector4D(t=1).x == vec.x - assert vec.to_Vector4D(t=1).y == vec.y - assert vec.to_Vector4D(t=1).z == vec.z - - def test_constructors_2D(): vec = vector.VectorObject2D(x=1, y=2) assert vec.x == 1 @@ -257,41 +220,3 @@ def test_array_casting(): with pytest.raises(TypeError): vector.obj(x=1, y=False) - - -def test_demotion(): - v1 = vector.obj(x=0.1, y=0.2) - v2 = vector.obj(x=1, y=2, z=3) - v3 = vector.obj(x=10, y=20, z=30, t=40) - - # order should not matter - assert v1 + v2 == vector.obj(x=1.1, y=2.2) - assert v2 + v1 == vector.obj(x=1.1, y=2.2) - assert v1 + v3 == vector.obj(x=10.1, y=20.2) - assert v3 + v1 == vector.obj(x=10.1, y=20.2) - assert v2 + v3 == vector.obj(x=11, y=22, z=33) - assert v3 + v2 == vector.obj(x=11, y=22, z=33) - - v1 = vector.obj(px=0.1, py=0.2) - v2 = vector.obj(px=1, py=2, pz=3) - v3 = vector.obj(px=10, py=20, pz=30, t=40) - - # order should not matter - assert v1 + v2 == vector.obj(px=1.1, py=2.2) - assert v2 + v1 == vector.obj(px=1.1, py=2.2) - assert v1 + v3 == vector.obj(px=10.1, py=20.2) - assert v3 + v1 == vector.obj(px=10.1, py=20.2) - assert v2 + v3 == vector.obj(px=11, py=22, pz=33) - assert v3 + v2 == vector.obj(px=11, py=22, pz=33) - - v1 = vector.obj(px=0.1, py=0.2) - v2 = vector.obj(x=1, y=2, z=3) - v3 = vector.obj(px=10, py=20, pz=30, t=40) - - # momentum + generic = generic - assert v1 + v2 == vector.obj(x=1.1, y=2.2) - assert v2 + v1 == vector.obj(x=1.1, y=2.2) - assert v1 + v3 == vector.obj(px=10.1, py=20.2) - assert v3 + v1 == vector.obj(px=10.1, py=20.2) - assert v2 + v3 == vector.obj(x=11, y=22, z=33) - assert v3 + v2 == vector.obj(x=11, y=22, z=33) diff --git a/tests/compute/test_conversions.py b/tests/compute/test_conversions.py index d6889e06..f041a8d2 100644 --- a/tests/compute/test_conversions.py +++ b/tests/compute/test_conversions.py @@ -491,3 +491,430 @@ def test_MomentumNumpy4D(): assert tv.y[0] == pytest.approx(2) assert tv.z[0] == pytest.approx(3) assert tv.t[0] == pytest.approx(4) + + +def test_conversion_with_coords_object(): + # 2D -> 3D + vec = vector.VectorObject2D(x=1, y=2) + assert vec.to_Vector3D(z=1).z == 1 + assert vec.to_Vector3D(eta=1).eta == 1 + assert vec.to_Vector3D(theta=1).theta == 1 + + assert vec.to_Vector3D(z=1).x == vec.x + assert vec.to_Vector3D(z=1).y == vec.y + + # 2D -> 4D + assert vec.to_Vector4D(z=1, t=1).z == 1 + assert vec.to_Vector4D(z=1, t=1).t == 1 + assert vec.to_Vector4D(eta=1, t=1).eta == 1 + assert vec.to_Vector4D(eta=1, t=1).t == 1 + assert vec.to_Vector4D(theta=1, t=1).theta == 1 + assert vec.to_Vector4D(theta=1, t=1).t == 1 + assert vec.to_Vector4D(z=1, tau=1).z == 1 + assert vec.to_Vector4D(z=1, tau=1).tau == 1 + assert vec.to_Vector4D(eta=1, tau=1).eta == 1 + assert vec.to_Vector4D(eta=1, tau=1).tau == 1 + assert vec.to_Vector4D(theta=1, tau=1).theta == 1 + assert vec.to_Vector4D(theta=1, tau=1).tau == 1 + + assert vec.to_Vector4D(z=1, t=1).x == vec.x + assert vec.to_Vector4D(z=1, t=1).y == vec.y + + # 3D -> 4D + vec = vector.VectorObject3D(x=1, y=2, z=3) + assert vec.to_Vector4D(t=1).t == 1 + assert vec.to_Vector4D(tau=1).tau == 1 + + assert vec.to_Vector4D(t=1).x == vec.x + assert vec.to_Vector4D(t=1).y == vec.y + assert vec.to_Vector4D(t=1).z == vec.z + + # check if momentum coords work + vec = vector.MomentumObject2D(px=1, py=2) + assert vec.to_Vector3D(pz=1).pz == 1 + + assert vec.to_Vector4D(pz=1, m=1).pz == 1 + assert vec.to_Vector4D(pz=1, m=1).m == 1 + assert vec.to_Vector4D(pz=1, mass=1).mass == 1 + assert vec.to_Vector4D(pz=1, M=1).M == 1 + assert vec.to_Vector4D(pz=1, e=1).e == 1 + assert vec.to_Vector4D(pz=1, energy=1).energy == 1 + assert vec.to_Vector4D(pz=1, E=1).E == 1 + + vec = vector.MomentumObject3D(px=1, py=2, pz=3) + assert vec.to_Vector4D(m=1).m == 1 + assert vec.to_Vector4D(mass=1).mass == 1 + assert vec.to_Vector4D(M=1).M == 1 + assert vec.to_Vector4D(e=1).e == 1 + assert vec.to_Vector4D(energy=1).energy == 1 + assert vec.to_Vector4D(E=1).E == 1 + + +def test_conversion_with_coords_numpy(): + # 2D -> 3D + vec = vector.VectorNumpy2D( + [(1.0, 1.0), (2.0, 2.0)], + dtype=[("x", float), ("y", float)], + ) + assert all(vec.to_Vector3D(z=1).z == 1) + assert all(vec.to_Vector3D(eta=1).eta == 1) + assert all(vec.to_Vector3D(theta=1).theta == 1) + + assert all(vec.to_Vector3D(z=1).x == vec.x) + assert all(vec.to_Vector3D(z=1).y == vec.y) + + # 2D -> 4D + assert all(vec.to_Vector4D(z=1, t=1).t == 1) + assert all(vec.to_Vector4D(z=1, t=1).z == 1) + assert all(vec.to_Vector4D(eta=1, t=1).eta == 1) + assert all(vec.to_Vector4D(eta=1, t=1).t == 1) + assert all(vec.to_Vector4D(theta=1, t=1).theta == 1) + assert all(vec.to_Vector4D(theta=1, t=1).t == 1) + assert all(vec.to_Vector4D(z=1, tau=1).z == 1) + assert all(vec.to_Vector4D(z=1, tau=1).tau == 1) + assert all(vec.to_Vector4D(eta=1, tau=1).eta == 1) + assert all(vec.to_Vector4D(eta=1, tau=1).tau == 1) + assert all(vec.to_Vector4D(theta=1, tau=1).theta == 1) + assert all(vec.to_Vector4D(theta=1, tau=1).tau == 1) + + assert all(vec.to_Vector4D(z=1, t=1).x == vec.x) + assert all(vec.to_Vector4D(z=1, t=1).y == vec.y) + + # 3D -> 4D + vec = vector.VectorNumpy3D( + [(1.0, 1.0, 1.0), (2.0, 2.0, 2.0)], + dtype=[("x", float), ("y", float), ("z", float)], + ) + assert all(vec.to_Vector4D(t=1).t == 1) + assert all(vec.to_Vector4D(tau=1).tau == 1) + + assert all(vec.to_Vector4D(t=1).x == vec.x) + assert all(vec.to_Vector4D(t=1).y == vec.y) + assert all(vec.to_Vector4D(t=1).z == vec.z) + + # check if momentum coords work + vec = vector.MomentumNumpy2D( + [(1.0, 1.0), (2.0, 2.0)], + dtype=[("px", float), ("py", float)], + ) + assert all(vec.to_Vector3D(pz=1).pz == 1) + + assert all(vec.to_Vector4D(pz=1, m=1).pz == 1) + assert all(vec.to_Vector4D(pz=1, m=1).m == 1) + assert all(vec.to_Vector4D(pz=1, mass=1).mass == 1) + assert all(vec.to_Vector4D(pz=1, M=1).M == 1) + assert all(vec.to_Vector4D(pz=1, e=1).e == 1) + assert all(vec.to_Vector4D(pz=1, energy=1).energy == 1) + assert all(vec.to_Vector4D(pz=1, E=1).E == 1) + + vec = vector.MomentumNumpy3D( + [(1.0, 1.0, 1.0), (2.0, 2.0, 2.0)], + dtype=[("px", float), ("py", float), ("pz", float)], + ) + assert all(vec.to_Vector4D(m=1).m == 1) + assert all(vec.to_Vector4D(mass=1).mass == 1) + assert all(vec.to_Vector4D(M=1).M == 1) + assert all(vec.to_Vector4D(e=1).e == 1) + assert all(vec.to_Vector4D(energy=1).energy == 1) + assert all(vec.to_Vector4D(E=1).E == 1) + + +def test_like_object(): + v1 = vector.obj(x=0.1, y=0.2) + v2 = vector.obj(x=1, y=2, z=3) + v3 = vector.obj(x=10, y=20, z=30, t=40) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # 2D + 3D.like(2D) = 2D + assert v1 + v2.like(v1) == vector.obj(x=1.1, y=2.2) + assert v2.like(v1) + v1 == vector.obj(x=1.1, y=2.2) + # 2D + 4D.like(2D) = 2D + assert v1 + v3.like(v1) == vector.obj(x=10.1, y=20.2) + assert v3.like(v1) + v1 == vector.obj(x=10.1, y=20.2) + # 3D + 2D.like(3D) = 3D + assert v2 + v1.like(v2) == vector.obj(x=1.1, y=2.2, z=3) + assert v1.like(v2) + v2 == vector.obj(x=1.1, y=2.2, z=3) + # 3D + 4D.like(3D) = 3D + assert v2 + v3.like(v2) == vector.obj(x=11, y=22, z=33) + assert v3.like(v2) + v2 == vector.obj(x=11, y=22, z=33) + # 4D + 2D.like(4D) = 4D + assert v3 + v1.like(v3) == vector.obj(x=10.1, y=20.2, z=30.0, t=40.0) + assert v1.like(v3) + v3 == vector.obj(x=10.1, y=20.2, z=30.0, t=40.0) + # 4D + 3D.like(4D) = 4D + assert v3 + v2.like(v3) == vector.obj(x=11, y=22, z=33, t=40) + assert v2.like(v3) + v3 == vector.obj(x=11, y=22, z=33, t=40) + + v1 = vector.obj(px=0.1, py=0.2) + v2 = vector.obj(px=1, py=2, pz=3) + v3 = vector.obj(px=10, py=20, pz=30, t=40) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # order should not matter + # 2D + 3D.like(2D) = 2D + assert v1 + v2.like(v1) == vector.obj(px=1.1, py=2.2) + assert v2.like(v1) + v1 == vector.obj(px=1.1, py=2.2) + # 2D + 4D.like(2D) = 2D + assert v1 + v3.like(v1) == vector.obj(px=10.1, py=20.2) + assert v3.like(v1) + v1 == vector.obj(px=10.1, py=20.2) + # 3D + 2D.like(3D) = 3D + assert v2 + v1.like(v2) == vector.obj(px=1.1, py=2.2, pz=3) + assert v1.like(v2) + v2 == vector.obj(px=1.1, py=2.2, pz=3) + # 3D + 4D.like(3D) = 3D + assert v2 + v3.like(v2) == vector.obj(px=11, py=22, pz=33) + assert v3.like(v2) + v2 == vector.obj(px=11, py=22, pz=33) + # 4D + 2D.like(4D) = 4D + assert v3 + v1.like(v3) == vector.obj(px=10.1, py=20.2, pz=30.0, E=40.0) + assert v1.like(v3) + v3 == vector.obj(px=10.1, py=20.2, pz=30.0, E=40.0) + # 4D + 3D.like(4D) = 4D + assert v3 + v2.like(v3) == vector.obj(px=11, py=22, pz=33, E=40) + assert v2.like(v3) + v3 == vector.obj(px=11, py=22, pz=33, E=40) + + v1 = vector.obj(px=0.1, py=0.2) + v2 = vector.obj(x=1, y=2, z=3) + v3 = vector.obj(px=10, py=20, pz=30, t=40) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # momentum + generic = generic + # 2D + 3D.like(2D) = 2D + assert v1 + v2.like(v1) == vector.obj(x=1.1, y=2.2) + assert v2.like(v1) + v1 == vector.obj(x=1.1, y=2.2) + # 2D + 4D.like(2D) = 2D + assert v1 + v3.like(v1) == vector.obj(x=10.1, y=20.2) + assert v3.like(v1) + v1 == vector.obj(x=10.1, y=20.2) + # 3D + 2D.like(3D) = 3D + assert v2 + v1.like(v2) == vector.obj(x=1.1, y=2.2, z=3) + assert v1.like(v2) + v2 == vector.obj(x=1.1, y=2.2, z=3) + # 3D + 4D.like(3D) = 3D + assert v2 + v3.like(v2) == vector.obj(x=11, y=22, z=33) + assert v3.like(v2) + v2 == vector.obj(x=11, y=22, z=33) + # 4D + 2D.like(4D) = 4D + assert v3 + v1.like(v3) == vector.obj(x=10.1, y=20.2, z=30.0, t=40.0) + assert v1.like(v3) + v3 == vector.obj(x=10.1, y=20.2, z=30.0, t=40.0) + # 4D + 3D.like(4D) = 4D + assert v3 + v2.like(v3) == vector.obj(x=11, y=22, z=33, t=40) + assert v2.like(v3) + v3 == vector.obj(x=11, y=22, z=33, t=40) + + +def test_like_numpy(): + v1 = vector.array( + { + "x": [10.0, 20.0, 30.0], + "y": [-10.0, 20.0, 30.0], + }, + ) + v2 = vector.array( + { + "x": [10.0, 20.0, 30.0], + "y": [-10.0, 20.0, 30.0], + "z": [5.0, 1.0, 1.0], + }, + ) + v3 = vector.array( + { + "x": [10.0, 20.0, 30.0], + "y": [-10.0, 20.0, 30.0], + "z": [5.0, 1.0, 1.0], + "t": [16.0, 31.0, 46.0], + }, + ) + + v1_v2 = vector.array( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + }, + ) + v2_v1 = vector.array( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [5.0, 1.0, 1.0], + }, + ) + v2_v3 = vector.array( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [10.0, 2.0, 2.0], + }, + ) + v3_v2 = vector.array( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [10.0, 2.0, 2.0], + "t": [16.0, 31.0, 46.0], + }, + ) + v1_v3 = vector.array( + { + "x": [20.0, 40.0, 60.0], + "y": [-20.0, 40.0, 60.0], + "z": [5.0, 1.0, 1.0], + "t": [16.0, 31.0, 46.0], + }, + ) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # 2D + 3D.like(2D) = 2D + assert all(v1 + v2.like(v1) == v1_v2) + assert all(v2.like(v1) + v1 == v1_v2) + # 2D + 4D.like(2D) = 2D + assert all(v1 + v3.like(v1) == v1_v2) + assert all(v3.like(v1) + v1 == v1_v2) + # 3D + 2D.like(3D) = 3D + assert all(v2 + v1.like(v2) == v2_v1) + assert all(v1.like(v2) + v2 == v2_v1) + # 3D + 4D.like(3D) = 3D + assert all(v2 + v3.like(v2) == v2_v3) + assert all(v3.like(v2) + v2 == v2_v3) + # 4D + 2D.like(4D) = 4D + assert all(v3 + v1.like(v3) == v1_v3) + assert all(v1.like(v3) + v3 == v1_v3) + # 4D + 3D.like(4D) = 4D + assert all(v3 + v2.like(v3) == v3_v2) + assert all(v2.like(v3) + v3 == v3_v2) + + v1 = vector.array( + { + "px": [10.0, 20.0, 30.0], + "py": [-10.0, 20.0, 30.0], + }, + ) + v2 = vector.array( + { + "px": [10.0, 20.0, 30.0], + "py": [-10.0, 20.0, 30.0], + "pz": [5.0, 1.0, 1.0], + }, + ) + v3 = vector.array( + { + "px": [10.0, 20.0, 30.0], + "py": [-10.0, 20.0, 30.0], + "pz": [5.0, 1.0, 1.0], + "t": [16.0, 31.0, 46.0], + }, + ) + + pv1_v2 = vector.array( + { + "px": [20.0, 40.0, 60.0], + "py": [-20.0, 40.0, 60.0], + }, + ) + pv2_v1 = vector.array( + { + "px": [20.0, 40.0, 60.0], + "py": [-20.0, 40.0, 60.0], + "pz": [5.0, 1.0, 1.0], + }, + ) + pv2_v3 = vector.array( + { + "px": [20.0, 40.0, 60.0], + "py": [-20.0, 40.0, 60.0], + "pz": [10.0, 2.0, 2.0], + }, + ) + pv3_v2 = vector.array( + { + "px": [20.0, 40.0, 60.0], + "py": [-20.0, 40.0, 60.0], + "pz": [10.0, 2.0, 2.0], + "t": [16.0, 31.0, 46.0], + }, + ) + pv1_v3 = vector.array( + { + "px": [20.0, 40.0, 60.0], + "py": [-20.0, 40.0, 60.0], + "pz": [5.0, 1.0, 1.0], + "t": [16.0, 31.0, 46.0], + }, + ) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # 2D + 3D.like(2D) = 2D + assert all(v1 + v2.like(v1) == pv1_v2) + assert all(v2.like(v1) + v1 == pv1_v2) + # 2D + 4D.like(2D) = 2D + assert all(v1 + v3.like(v1) == pv1_v2) + assert all(v3.like(v1) + v1 == pv1_v2) + # 3D + 2D.like(3D) = 3D + assert all(v2 + v1.like(v2) == pv2_v1) + assert all(v1.like(v2) + v2 == pv2_v1) + # 3D + 4D.like(3D) = 3D + assert all(v2 + v3.like(v2) == pv2_v3) + assert all(v3.like(v2) + v2 == pv2_v3) + # 4D + 2D.like(4D) = 4D + assert all(v3 + v1.like(v3) == pv1_v3) + assert all(v1.like(v3) + v3 == pv1_v3) + # 4D + 3D.like(4D) = 4D + assert all(v3 + v2.like(v3) == pv3_v2) + assert all(v2.like(v3) + v3 == pv3_v2) + + v2 = vector.array( + { + "x": [10.0, 20.0, 30.0], + "y": [-10.0, 20.0, 30.0], + "z": [5.0, 1.0, 1.0], + }, + ) + + with pytest.raises(TypeError): + v1 + v2 + with pytest.raises(TypeError): + v2 + v3 + with pytest.raises(TypeError): + v1 + v3 + + # momentum + generic = generic + # 2D + 3D.like(2D) = 2D + assert all(v1 + v2.like(v1) == pv1_v2) + assert all(v2.like(v1) + v1 == pv1_v2) + # 2D + 4D.like(2D) = 2D + assert all(v1 + v3.like(v1) == pv1_v2) + assert all(v3.like(v1) + v1 == pv1_v2) + # 3D + 2D.like(3D) = 3D + assert all(v2 + v1.like(v2) == pv2_v1) + assert all(v1.like(v2) + v2 == pv2_v1) + # 3D + 4D.like(3D) = 3D + assert all(v2 + v3.like(v2) == pv2_v3) + assert all(v3.like(v2) + v2 == pv2_v3) + # 4D + 2D.like(4D) = 4D + assert all(v3 + v1.like(v3) == pv1_v3) + assert all(v1.like(v3) + v3 == pv1_v3) + # 4D + 3D.like(4D) = 4D + assert all(v3 + v2.like(v3) == pv3_v2) + assert all(v2.like(v3) + v3 == pv3_v2) diff --git a/tests/test_methods.py b/tests/test_methods.py index b31c9977..9bcb7d69 100644 --- a/tests/test_methods.py +++ b/tests/test_methods.py @@ -5,6 +5,8 @@ from __future__ import annotations +import pytest + import vector from vector import ( MomentumNumpy2D, @@ -27,33 +29,37 @@ def test_handler_of(): object_a = VectorObject3D.from_xyz(0.0, 0.0, 0.0) object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_a + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) + protocol = vector._methods._handler_of(object_a.like(object_b), object_b) + assert protocol == object_a.like(object_b) object_a = VectorObject4D.from_xyzt(0.0, 0.0, 0.0, 0.0) object_b = VectorObject3D.from_xyz(1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_b + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) + protocol = vector._methods._handler_of(object_b.like(object_a), object_a) + assert protocol == object_b.like(object_a) object_a = VectorObject2D.from_xy(0.0, 0.0) object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_a + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) object_a = VectorObject4D.from_xyzt(0.0, 0.0, 0.0, 0.0) object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_b + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) object_a = VectorObject2D.from_xy(0.0, 0.0) object_b = VectorObject3D.from_xyz(1.0, 1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_a + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) object_a = VectorObject3D.from_xyz(0.0, 0.0, 0.0) object_b = VectorObject2D.from_xy(1.0, 1.0) - protocol = vector._methods._handler_of(object_a, object_b) - assert protocol == object_b + with pytest.raises(TypeError): + protocol = vector._methods._handler_of(object_a, object_b) def test_momentum_coordinate_transforms(): From b8682f6db327f4cd7a55c439a0f00355f6ba0d8c Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Fri, 23 Feb 2024 18:17:10 +0100 Subject: [PATCH 02/11] fix: raise error only on a few operations --- src/vector/_methods.py | 81 ++++++++++++--------------- tests/backends/test_awkward.py | 93 +++++++++---------------------- tests/backends/test_operators.py | 21 +++++++ tests/compute/test_conversions.py | 42 -------------- tests/test_methods.py | 38 ------------- 5 files changed, 83 insertions(+), 192 deletions(-) diff --git a/src/vector/_methods.py b/src/vector/_methods.py index 5ce3b7c6..c5150f8f 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -3474,14 +3474,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3504,15 +3507,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import not_equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return not_equal.dispatch(self, other) def isclose( @@ -3524,8 +3525,7 @@ def isclose( ) -> BoolCollection: from vector._compute.planar import isclose - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3689,14 +3689,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3730,15 +3733,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import not_equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return not_equal.dispatch(self, other) def isclose( @@ -3750,8 +3751,7 @@ def isclose( ) -> BoolCollection: from vector._compute.spatial import isclose - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3933,14 +3933,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: + _is_same_dimension(self, other) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3985,15 +3988,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import not_equal - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return not_equal.dispatch(self, other) def isclose( @@ -4005,8 +4006,7 @@ def isclose( ) -> BoolCollection: from vector._compute.lorentz import isclose - if dim(self) != dim(other): - raise TypeError(f"{self!r} and {other!r} do not have the same dimension") + _is_same_dimension(self, other) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -4176,6 +4176,23 @@ def dim(v: VectorProtocol) -> int: raise TypeError(f"{v!r} is not a vector.Vector") +def _is_same_dimension(v1: VectorProtocol, v2: VectorProtocol) -> None: + """Raises an error if the vectors are not of the same dimension.""" + if dim(v1) != dim(v2): + raise TypeError( + f"""{v1!r} and {v2!r} do not have the same dimension; use + + a.like(b) + b + + or + + a + b.like(a) + + to project or embed one of the vectors to match the other's dimensionality + """ + ) + + def _compute_module_of( one: VectorProtocol, two: VectorProtocol, nontemporal: bool = False ) -> Module: @@ -4438,34 +4455,6 @@ def _handler_of(*objects: VectorProtocol) -> VectorProtocol: handler = obj assert handler is not None - - if _check_instance(all, objects, Vector) and ( - ( - _check_instance(any, objects, Vector2D) - and _check_instance(any, objects, Vector3D) - ) - or ( - _check_instance(any, objects, Vector2D) - and _check_instance(any, objects, Vector4D) - ) - or ( - _check_instance(any, objects, Vector3D) - and _check_instance(any, objects, Vector4D) - ) - ): - raise TypeError( - """cannot perform the operation on vectors of different dimensionality; use - - a.like(b) + b - - or - - a + b.like(a) - - to project or embed one of the vectors to match the other's dimensionality - """ - ) - return handler diff --git a/tests/backends/test_awkward.py b/tests/backends/test_awkward.py index f2671063..cf8a757f 100644 --- a/tests/backends/test_awkward.py +++ b/tests/backends/test_awkward.py @@ -11,7 +11,7 @@ import pytest import vector -from vector import VectorObject2D, VectorObject4D +from vector import VectorObject2D ak = pytest.importorskip("awkward") @@ -701,6 +701,30 @@ def test_like(): v2 + v3 with pytest.raises(TypeError): v1 + v3 + with pytest.raises(TypeError): + v1 - v2 + with pytest.raises(TypeError): + v2 - v3 + with pytest.raises(TypeError): + v1 - v3 + with pytest.raises(TypeError): + v1.equal(v2) + with pytest.raises(TypeError): + v2.equal(v3) + with pytest.raises(TypeError): + v1.equal(v3) + with pytest.raises(TypeError): + v1.not_equal(v2) + with pytest.raises(TypeError): + v2.not_equal(v3) + with pytest.raises(TypeError): + v1.not_equal(v3) + with pytest.raises(TypeError): + v1.dot(v2) + with pytest.raises(TypeError): + v2.dot(v3) + with pytest.raises(TypeError): + v1.dot(v3) # 2D + 3D.like(2D) = 2D assert ak.all(v1 + v2.like(v1) == v1_v2) @@ -743,13 +767,6 @@ def test_like(): }, ) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # 2D + 3D.like(2D) = 2D assert ak.all(v1 + v2.like(v1) == v1_v2) assert ak.all(v2.like(v1) + v1 == v1_v2) @@ -799,58 +816,6 @@ def test_like(): def test_handler_of(): - awkward_vec = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 10.0, 15.0], - "t": [16.0, 31.0, 46.0], - }, - ) - object_vec = VectorObject2D.from_xy(1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(awkward_vec, object_vec) - protocol = vector._methods._handler_of(awkward_vec, object_vec.like(awkward_vec)) - # chooses awkward backend - assert all(protocol == awkward_vec) - - awkward_vec = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - }, - ) - object_vec = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(awkward_vec, object_vec) - protocol = vector._methods._handler_of(object_vec, awkward_vec.like(object_vec)) - # chooses awkward backend - assert all(protocol == awkward_vec.like(object_vec)) - - awkward_vec = vector.zip( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - }, - ) - awkward_vec2 = vector.zip( - { - "x": [1.0, 2.0, 3.0], - "y": [-1.0, 2.0, 3.0], - "z": [5.0, 10.0, 15.0], - "t": [16.0, 31.0, 46.0], - }, - ) - object_vec = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_vec, awkward_vec, awkward_vec2) - protocol = vector._methods._handler_of( - object_vec, awkward_vec.like(awkward_vec2), awkward_vec2 - ) - # chooses awkward backend and the - # first encountered awkward vector - assert all(protocol == awkward_vec.like(awkward_vec2)) - numpy_vec = vector.array( { "x": [1.1, 1.2, 1.3, 1.4, 1.5], @@ -867,13 +832,9 @@ def test_handler_of(): }, ) object_vec = VectorObject2D.from_xy(1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_vec, awkward_vec, numpy_vec) - protocol = vector._methods._handler_of( - object_vec, numpy_vec.like(object_vec), awkward_vec2.like(object_vec) - ) + protocol = vector._methods._handler_of(object_vec, numpy_vec, awkward_vec2) # chooses awkward backend - assert all(protocol == awkward_vec2.to_Vector2D()) + assert all(protocol == awkward_vec2) def test_momentum_coordinate_transforms(): diff --git a/tests/backends/test_operators.py b/tests/backends/test_operators.py index 432e3278..96c36c31 100644 --- a/tests/backends/test_operators.py +++ b/tests/backends/test_operators.py @@ -26,6 +26,10 @@ def test_eq(): assert not (v1 == a1).all() assert (a1 == v1).any() assert not (a1 == v1).all() + with pytest.raises(TypeError): + v1.equal(v2.to_Vector3D()) + with pytest.raises(TypeError): + a1.equal(a2.to_Vector3D()) def test_ne(): @@ -37,6 +41,10 @@ def test_ne(): assert not (v1 != a1).all() assert (a1 != v1).any() assert not (a1 != v1).all() + with pytest.raises(TypeError): + v1.not_equal(v2.to_Vector3D()) + with pytest.raises(TypeError): + a1.not_equal(a2.to_Vector3D()) def test_abs(): @@ -49,10 +57,15 @@ def test_abs(): def test_add(): assert v1 + v2 == vector.obj(x=11, y=25) + assert v1 + v2.to_Vector3D().like(v1) == vector.obj(x=11, y=25) assert numpy.allclose( a1 + a2, vector.array({"x": [11, 102, 1003, 10004], "y": [25, 206, 2007, 20008]}), ) + assert numpy.allclose( + a1 + a2.to_Vector3D().like(a1), + vector.array({"x": [11, 102, 1003, 10004], "y": [25, 206, 2007, 20008]}), + ) assert numpy.allclose( v1 + a2, vector.array({"x": [11, 101, 1001, 10001], "y": [25, 205, 2005, 20005]}), @@ -65,6 +78,10 @@ def test_add(): v1 + 5 with pytest.raises(TypeError): 5 + v1 + with pytest.raises(TypeError): + v1 + v2.to_Vector3D() + with pytest.raises(TypeError): + a1 + a2.to_Vector3D() def test_sub(): @@ -85,6 +102,10 @@ def test_sub(): v1 - 5 with pytest.raises(TypeError): 5 - v1 + with pytest.raises(TypeError): + v1 - v2.to_Vector3D() + with pytest.raises(TypeError): + a1 - a2.to_Vector3D() def test_mul(): diff --git a/tests/compute/test_conversions.py b/tests/compute/test_conversions.py index f041a8d2..8aa6f2b9 100644 --- a/tests/compute/test_conversions.py +++ b/tests/compute/test_conversions.py @@ -624,13 +624,6 @@ def test_like_object(): v2 = vector.obj(x=1, y=2, z=3) v3 = vector.obj(x=10, y=20, z=30, t=40) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # 2D + 3D.like(2D) = 2D assert v1 + v2.like(v1) == vector.obj(x=1.1, y=2.2) assert v2.like(v1) + v1 == vector.obj(x=1.1, y=2.2) @@ -654,13 +647,6 @@ def test_like_object(): v2 = vector.obj(px=1, py=2, pz=3) v3 = vector.obj(px=10, py=20, pz=30, t=40) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # order should not matter # 2D + 3D.like(2D) = 2D assert v1 + v2.like(v1) == vector.obj(px=1.1, py=2.2) @@ -685,13 +671,6 @@ def test_like_object(): v2 = vector.obj(x=1, y=2, z=3) v3 = vector.obj(px=10, py=20, pz=30, t=40) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # momentum + generic = generic # 2D + 3D.like(2D) = 2D assert v1 + v2.like(v1) == vector.obj(x=1.1, y=2.2) @@ -773,13 +752,6 @@ def test_like_numpy(): }, ) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # 2D + 3D.like(2D) = 2D assert all(v1 + v2.like(v1) == v1_v2) assert all(v2.like(v1) + v1 == v1_v2) @@ -858,13 +830,6 @@ def test_like_numpy(): }, ) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # 2D + 3D.like(2D) = 2D assert all(v1 + v2.like(v1) == pv1_v2) assert all(v2.like(v1) + v1 == pv1_v2) @@ -892,13 +857,6 @@ def test_like_numpy(): }, ) - with pytest.raises(TypeError): - v1 + v2 - with pytest.raises(TypeError): - v2 + v3 - with pytest.raises(TypeError): - v1 + v3 - # momentum + generic = generic # 2D + 3D.like(2D) = 2D assert all(v1 + v2.like(v1) == pv1_v2) diff --git a/tests/test_methods.py b/tests/test_methods.py index 9bcb7d69..1deab18d 100644 --- a/tests/test_methods.py +++ b/tests/test_methods.py @@ -5,8 +5,6 @@ from __future__ import annotations -import pytest - import vector from vector import ( MomentumNumpy2D, @@ -15,8 +13,6 @@ MomentumObject2D, MomentumObject3D, MomentumObject4D, - VectorObject2D, - VectorObject3D, VectorObject4D, ) @@ -27,40 +23,6 @@ def test_handler_of(): protocol = vector._methods._handler_of(object_a, object_b) assert protocol == object_a - object_a = VectorObject3D.from_xyz(0.0, 0.0, 0.0) - object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - protocol = vector._methods._handler_of(object_a.like(object_b), object_b) - assert protocol == object_a.like(object_b) - - object_a = VectorObject4D.from_xyzt(0.0, 0.0, 0.0, 0.0) - object_b = VectorObject3D.from_xyz(1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - protocol = vector._methods._handler_of(object_b.like(object_a), object_a) - assert protocol == object_b.like(object_a) - - object_a = VectorObject2D.from_xy(0.0, 0.0) - object_b = VectorObject4D.from_xyzt(1.0, 1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - - object_a = VectorObject4D.from_xyzt(0.0, 0.0, 0.0, 0.0) - object_b = VectorObject2D.from_xy(1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - - object_a = VectorObject2D.from_xy(0.0, 0.0) - object_b = VectorObject3D.from_xyz(1.0, 1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - - object_a = VectorObject3D.from_xyz(0.0, 0.0, 0.0) - object_b = VectorObject2D.from_xy(1.0, 1.0) - with pytest.raises(TypeError): - protocol = vector._methods._handler_of(object_a, object_b) - def test_momentum_coordinate_transforms(): numpy_vec = vector.array( From 3de5daa040f22cf6c223f62c966b6c68c8c442d0 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Fri, 23 Feb 2024 18:56:04 +0100 Subject: [PATCH 03/11] update notebook and README --- README.md | 13 +- docs/usage/intro.ipynb | 367 ++++++++++++++++++++++------------------- 2 files changed, 207 insertions(+), 173 deletions(-) diff --git a/README.md b/README.md index 613d7115..57749ba2 100644 --- a/README.md +++ b/README.md @@ -531,10 +531,18 @@ vector.obj(pt=1, phi=1.3, eta=2, mass=5).deltaR( ) ``` -The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed. +For a few operations - `+`, `-`, `==`, `!=`, ... - the dimension of the vectors should be equal. This can be achieved by using the `like` method, `to_{coordinate_name}` methods, `to_Vector*D` methods. The `to_Vector*D` methods provide more flexibility to the users, that is, new coordinate values can be passed into the methods as named arguments. ```python -vector.obj(x=1, y=2, z=3) - vector.obj(x=1, y=2) +v1 = vector.obj(x=1, y=2, z=3) +v2 = vector.obj(x=1, y=2) + +v1 - v2.like(v1), v1.like(v2) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D(z=3), v1.to_Vector2D() - v2 +``` + +The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed. + +``` vector.obj(x=1, y=2, z=0).is_parallel(vector.obj(x=1, y=2)) ``` @@ -625,6 +633,7 @@ The (current) list of properties and methods is: - `isclose(vector, rtol=1e-5, atol=1e-8, equal_nan=False)`: works like [np.isclose](https://numpy.org/doc/stable/reference/generated/numpy.isclose.html); arrays also have an [allclose](https://numpy.org/doc/stable/reference/generated/numpy.allclose.html) method - `to_Vector*D(coordinates)`: replace `*` with the reuquired vector dimension - `to_{coordinate-names}`: for example - `to_rhophietatau` +- `like(other)`: projects the vector into the dimensions of `other`, for example - `two_d_vector.like(three_d_vector)` ## Compiling your Python with Numba diff --git a/docs/usage/intro.ipynb b/docs/usage/intro.ipynb index 3b2aa3be..12df82c3 100644 --- a/docs/usage/intro.ipynb +++ b/docs/usage/intro.ipynb @@ -1452,60 +1452,60 @@ { "data": { "text/plain": [ - "MomentumNumpy3D([[[( 2.26039025, -1.98481124, -1.29907057),\n", - " ( 0.95952588, -2.00396017, -0.4404866 )],\n", - " [(-2.55169443, 0.45531406, 0.2200994 ),\n", - " (-1.0996391 , -0.73624228, -0.80890089)],\n", - " [(-0.7411634 , -0.110458 , -0.19701435),\n", - " ( 1.35582837, 0.200836 , -1.27418951)],\n", - " [(-0.62333052, 0.52145296, 0.24492175),\n", - " ( 0.38686249, -1.62346243, -1.06885481)],\n", - " [( 0.54233445, -0.72464489, 0.70890249),\n", - " (-0.10019824, 0.93090357, 0.73060395)]],\n", + "MomentumNumpy3D([[[(-1.42913487, -0.20404998, -0.8992022 ),\n", + " (-1.50965637, -1.58581616, -2.26896045)],\n", + " [( 0.5793101 , -0.47534844, -1.28655128),\n", + " ( 1.74174173, -0.44064342, 0.75934888)],\n", + " [(-0.63649546, 0.5248589 , 0.4353472 ),\n", + " (-0.29766214, 0.28088943, -0.38635832)],\n", + " [(-1.58539851, -0.90099393, 0.73724365),\n", + " ( 0.48743887, -0.56026569, 0.16054964)],\n", + " [(-1.1635853 , 0.00537231, 0.58857628),\n", + " (-1.21782518, -0.00401369, -0.33790633)]],\n", "\n", - " [[( 0.41104402, 0.5590012 , 2.36215303),\n", - " ( 1.73855749, -0.75679797, 0.15862517)],\n", - " [(-0.0985614 , 0.57614691, -0.13468802),\n", - " (-1.75545141, 0.31520659, -1.0191747 )],\n", - " [( 0.52953509, -0.454113 , 0.9103319 ),\n", - " ( 1.06982529, -0.73796475, 0.47365608)],\n", - " [( 0.70143481, -2.48893272, 0.60751234),\n", - " ( 0.26390769, 0.19964715, -0.37988363)],\n", - " [(-2.00117585, 0.07216232, 0.3443312 ),\n", - " (-0.54123369, 1.42881317, 0.39421562)]],\n", + " [[(-1.25874469, -0.75320216, -1.50702232),\n", + " ( 0.21525424, 0.34164511, 0.23212705)],\n", + " [( 1.38764489, -1.55627838, 0.26229165),\n", + " ( 0.10222743, 0.62900046, -1.31097117)],\n", + " [(-0.65710113, 0.89476612, -0.41780337),\n", + " ( 0.36444657, 0.07499156, 0.76627191)],\n", + " [(-0.74980871, 1.17914399, -0.73711352),\n", + " (-0.47166194, -0.30031473, 0.75332702)],\n", + " [(-0.67590893, -0.22366163, 1.0278958 ),\n", + " ( 0.06939478, 0.37879193, -0.68323822)]],\n", "\n", - " [[(-0.0130378 , 0.51884925, 0.38741933),\n", - " ( 0.12128434, 1.63382031, 0.62769807)],\n", - " [(-0.02453509, 0.0088992 , -1.97146483),\n", - " ( 0.52108073, -1.77611003, -0.17590794)],\n", - " [(-2.14835586, 0.16964633, 2.02826159),\n", - " ( 0.73103243, 0.85196301, 1.1617289 )],\n", - " [(-0.16432348, 0.39310727, 0.00777254),\n", - " (-1.05791558, 0.55587963, 0.23693828)],\n", - " [( 0.94864117, 0.77488342, -0.74026367),\n", - " ( 0.71154967, -0.36412087, 0.09636387)]],\n", + " [[( 1.51628366, -0.52196473, 0.71691781),\n", + " ( 2.55630317, 0.99490967, -1.13367178)],\n", + " [(-0.11869339, -0.69920031, -0.34393436),\n", + " ( 0.54860171, -1.50186676, -1.0930652 )],\n", + " [(-0.87201802, -1.29564802, -0.44148477),\n", + " (-0.57861467, -1.31234899, 1.82999728)],\n", + " [( 0.13586229, 0.96615212, 1.82739502),\n", + " (-0.94599231, -1.32164925, -0.65439075)],\n", + " [(-0.01598523, -0.33254174, 0.24804779),\n", + " (-0.10264518, -0.81005823, 1.44981102)]],\n", "\n", - " [[( 0.91218559, 1.17236545, -0.0619832 ),\n", - " (-0.13943885, -0.53065792, 0.13009332)],\n", - " [( 0.0400739 , -1.33943471, -0.04176005),\n", - " (-0.47738235, 2.08961029, -1.48695025)],\n", - " [(-0.84699974, -0.16730622, -0.20521711),\n", - " ( 0.37491512, 0.6729008 , -0.47241812)],\n", - " [(-0.83194681, 1.62940666, 0.44099987),\n", - " ( 0.63878738, 1.46062868, -0.41644439)],\n", - " [(-0.10227976, 0.74096051, -1.31529571),\n", - " ( 1.09401836, 0.77294462, 0.27773291)]],\n", + " [[( 1.08589702, -0.63395122, -0.67596226),\n", + " (-0.09043662, -1.02783004, 0.14100503)],\n", + " [( 0.36900529, -0.20551341, 1.20770009),\n", + " (-1.45570726, 1.44865298, 1.70384269)],\n", + " [(-1.61330367, -0.16610241, -0.68345571),\n", + " ( 0.18759582, 1.87281996, -0.57175207)],\n", + " [( 0.63015684, -0.91842193, -0.91528516),\n", + " (-0.3936394 , -1.61370204, -0.57485609)],\n", + " [(-0.8178419 , 0.32550864, 1.10467835),\n", + " (-0.55037021, 1.04750445, 0.4554011 )]],\n", "\n", - " [[( 1.17205984, -0.15417393, 0.31004223),\n", - " ( 0.99275882, -1.11519843, 1.08783846)],\n", - " [(-0.54770178, -1.69687857, 0.25023612),\n", - " (-0.27828739, 1.14492199, 2.29676035)],\n", - " [(-0.20599501, 0.54057953, -0.83481415),\n", - " (-0.68719168, -2.08795544, 0.83253276)],\n", - " [(-2.55054126, -1.46269813, 1.79934732),\n", - " ( 1.77585908, -1.33620677, -0.35172656)],\n", - " [( 0.50447696, 2.09937313, 0.23885731),\n", - " (-0.21897479, -0.84282187, 2.71267012)]]],\n", + " [[(-0.97167348, -0.13764255, -0.73902296),\n", + " ( 2.14773563, 0.07980281, -0.91068575)],\n", + " [(-0.16119949, 0.49284801, 0.04834321),\n", + " (-0.95413822, -0.3790709 , 0.25909865)],\n", + " [(-1.56135351, -0.01127451, 1.24677082),\n", + " (-0.28788099, -0.02051752, -1.03206188)],\n", + " [(-1.40280634, 0.84274277, 1.21150726),\n", + " ( 0.37774258, 0.27045825, -0.80279231)],\n", + " [( 0.89741189, 0.72263796, 1.17414993),\n", + " (-0.39162535, 1.88167979, 0.15871216)]]],\n", " dtype=[('x', '[[{x: -0.376, y: 1.92, z: -1.87}],\n", - " [{x: -0.106, y: -0.827, z: -0.61}],\n", - " [{x: 0.682, y: -0.445, z: 1.25}, {...}, {x: 0.336, y: -1.04, z: 1.59}],\n", - " [{x: 0.236, y: -0.778, z: 2.41}, {x: -0.627, y: -0.654, z: 1.6}],\n", - " [],\n", - " [{x: -0.689, y: -1.14, z: -0.376}, {x: 0.141, y: 0.546, z: -1.1}],\n", + "
[[{x: -0.714, y: 0.847, z: 0.146}, {x: 0.256, y: -0.56, z: -1.42}],\n",
+       " [{x: -0.835, y: 0.471, z: -0.0945}, ..., {x: -1.87, y: -2.23, z: -0.498}],\n",
+       " [{x: 0.0678, y: -0.28, z: 0.942}, {...}, ..., {x: -1.71, y: 0.315, z: 1.19}],\n",
+       " [{x: -0.162, y: -1.22, z: -1.76}, {...}, {x: -0.717, y: -0.219, z: -1.1}],\n",
+       " [{x: -0.325, y: 0.296, z: -1.3}, {...}, {x: -2.26, y: 1.14, z: 0.533}],\n",
+       " [{x: -0.77, y: 0.2, z: 0.235}],\n",
+       " [{x: 0.0141, y: 2.02, z: -0.323}, {x: -0.76, y: 1.08, z: -0.828}],\n",
+       " [{x: 0.338, y: 1.1, z: 0.0861}, {...}, {x: -0.354, y: -1.27, z: 1.35}],\n",
+       " [{x: -0.602, y: 1.84, z: 0.611}],\n",
+       " [{x: -1.25, y: -0.707, z: -0.113}],\n",
+       " ...,\n",
        " [],\n",
-       " [{x: 0.426, y: 1.25, z: -0.33}, {...}, {x: 0.792, y: 0.0574, z: -1.69}],\n",
+       " [{x: -0.171, y: 1.32, z: -0.144}, {x: -0.607, y: -0.153, z: -1.06}],\n",
+       " [{x: 0.261, y: 0.786, z: 0.233}],\n",
+       " [{x: -0.0354, y: -0.71, z: 0.75}],\n",
+       " [{x: 0.0199, y: -0.0305, z: 1.22}],\n",
        " [],\n",
-       " [{x: -0.165, y: 0.0744, z: 1}],\n",
-       " ...,\n",
-       " [{x: -0.922, y: -0.895, z: -1.07}],\n",
-       " [{x: -1.95, y: -1.75, z: 1.41}, {...}, {x: 0.73, y: 0.472, z: -0.969}],\n",
-       " [{x: -0.139, y: 1.62, z: -0.308}, {x: -0.0608, y: 0.825, z: -1.75}],\n",
-       " [{x: 1.41, y: 0.951, z: -1.47}, {x: -0.836, y: -0.196, z: -0.887}],\n",
-       " [{x: -1, y: 0.94, z: 1.12}],\n",
        " [],\n",
-       " [{x: 0.718, y: -1.04, z: -0.305}, {x: -0.228, y: 0.862, z: -0.5}],\n",
-       " [{x: 0.754, y: 0.365, z: 0.465}],\n",
-       " [{x: -0.99, y: 0.726, z: -1.38}, {x: 1.03, y: 0.119, z: -0.0639}]]\n",
-       "-------------------------------------------------------------------------\n",
+       " [{x: 0.937, y: 0.925, z: 0.643}, {x: 0.998, y: 2.86, z: -1.27}],\n",
+       " [{x: 1.59, y: 2.88, z: -0.971}, {...}, ..., {x: -1.08, y: -2.18, z: 0.961}]]\n",
+       "------------------------------------------------------------------------------\n",
        "type: 50 * var * Momentum3D[\n",
        "    x: float64,\n",
        "    y: float64,\n",
@@ -1655,7 +1655,7 @@
        "]
" ], "text/plain": [ - "" + "" ] }, "execution_count": 53, @@ -1686,31 +1686,31 @@ { "data": { "text/html": [ - "
[[1.96],\n",
-       " [0.834],\n",
-       " [0.814, 1.72, 1.09],\n",
-       " [0.813, 0.906],\n",
-       " [],\n",
-       " [1.33, 0.564],\n",
+       "
[[1.11, 0.615],\n",
+       " [0.958, 1.35, 2.81, 1.89, 2.91],\n",
+       " [0.289, 1.72, 1.04, 1.74],\n",
+       " [1.23, 0.331, 0.75],\n",
+       " [0.44, 1.41, 2.53],\n",
+       " [0.795],\n",
+       " [2.02, 1.32],\n",
+       " [1.15, 1.28, 1.32],\n",
+       " [1.94],\n",
+       " [1.43],\n",
+       " ...,\n",
        " [],\n",
-       " [1.32, 1.75, 0.794],\n",
+       " [1.33, 0.626],\n",
+       " [0.828],\n",
+       " [0.711],\n",
+       " [0.0364],\n",
        " [],\n",
-       " [0.181],\n",
-       " ...,\n",
-       " [1.29],\n",
-       " [2.62, 2.66, 0.869],\n",
-       " [1.63, 0.828],\n",
-       " [1.7, 0.859],\n",
-       " [1.37],\n",
        " [],\n",
-       " [1.26, 0.892],\n",
-       " [0.838],\n",
-       " [1.23, 1.04]]\n",
-       "------------------------\n",
+       " [1.32, 3.02],\n",
+       " [3.29, 0.719, 1.39, 2.93, 2.44]]\n",
+       "---------------------------------\n",
        "type: 50 * var * float64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 54, @@ -1732,31 +1732,31 @@ { "data": { "text/html": [ - "
[1,\n",
-       " 1,\n",
+       "
[2,\n",
+       " 5,\n",
+       " 4,\n",
        " 3,\n",
+       " 3,\n",
+       " 1,\n",
        " 2,\n",
-       " 0,\n",
-       " 2,\n",
-       " 0,\n",
        " 3,\n",
-       " 0,\n",
        " 1,\n",
-       " ...,\n",
        " 1,\n",
-       " 3,\n",
-       " 2,\n",
+       " ...,\n",
+       " 0,\n",
        " 2,\n",
        " 1,\n",
+       " 1,\n",
+       " 1,\n",
+       " 0,\n",
        " 0,\n",
        " 2,\n",
-       " 1,\n",
-       " 2]\n",
+       " 5]\n",
        "----------------\n",
        "type: 50 * int64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 55, @@ -1778,31 +1778,31 @@ { "data": { "text/html": [ - "
[1,\n",
-       " 1,\n",
+       "
[2,\n",
+       " 5,\n",
+       " 4,\n",
        " 3,\n",
+       " 3,\n",
+       " 1,\n",
        " 2,\n",
-       " 0,\n",
-       " 2,\n",
-       " 0,\n",
        " 3,\n",
-       " 0,\n",
        " 1,\n",
-       " ...,\n",
        " 1,\n",
-       " 3,\n",
-       " 2,\n",
+       " ...,\n",
+       " 0,\n",
        " 2,\n",
        " 1,\n",
+       " 1,\n",
+       " 1,\n",
+       " 0,\n",
        " 0,\n",
        " 2,\n",
-       " 1,\n",
-       " 2]\n",
+       " 5]\n",
        "----------------\n",
        "type: 50 * int64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 56, @@ -2623,7 +2623,7 @@ "id": "sensitive-booking", "metadata": {}, "source": [ - "The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed." + "For a few operations - `+`, `-`, `==`, `!=`, ... - the dimension of the vectors should be equal. This can be achieved by using the `like` method, `to_{coordinate_name}` methods, `to_Vector*D` methods. The `to_Vector*D` methods provide more flexibility to the users, that is, new coordinate values can be passed into the methods as named arguments." ] }, { @@ -2635,7 +2635,12 @@ { "data": { "text/plain": [ - "VectorObject3D(x=0, y=0, z=3)" + "(VectorObject3D(x=0, y=0, z=3.0),\n", + " VectorObject2D(x=0, y=0),\n", + " VectorObject3D(x=0, y=0, z=3),\n", + " VectorObject2D(x=0, y=0),\n", + " VectorObject3D(x=0, y=0, z=0),\n", + " VectorObject2D(x=0, y=0))" ] }, "execution_count": 88, @@ -2644,7 +2649,18 @@ } ], "source": [ - "vector.obj(x=1, y=2, z=3) - vector.obj(x=1, y=2)" + "v1 = vector.obj(x=1, y=2, z=3)\n", + "v2 = vector.obj(x=1, y=2)\n", + "\n", + "v1 - v2.like(v1), v1.like(v2) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D(z=3), v1.to_Vector2D() - v2" + ] + }, + { + "cell_type": "markdown", + "id": "e43155a9-9d3a-4e2e-b21e-192f5bb86d94", + "metadata": {}, + "source": [ + "The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed." ] }, { @@ -2782,7 +2798,8 @@ " * `count()`: can also use `awkward.count`, only for Awkward vectors\n", " * `isclose(vector, rtol=1e-5, atol=1e-8, equal_nan=False)`: works like [np.isclose](https://numpy.org/doc/stable/reference/generated/numpy.isclose.html); arrays also have an [allclose](https://numpy.org/doc/stable/reference/generated/numpy.allclose.html) method\n", " * `to_Vector*D(coordinates)`: replace `*` with the reuquired vector dimension\n", - " * `to_{coordinate-names}`: for example - `to_rhophietatau`\n" + " * `to_{coordinate-names}`: for example - `to_rhophietatau`\n", + " * `like(other)`: projects the vector into the dimensions of `other`, for example - `two_d_vector.like(three_d_vector)`\n" ] }, { @@ -2851,27 +2868,27 @@ { "data": { "text/html": [ - "
[[{x: 0.687, y: 1.15, z: -0.272, t: 11.5}],\n",
-       " [{x: -0.00848, y: 0.739, z: 1.91, t: 11.2}, {x: 0.684, y: 0.686, ...}],\n",
-       " [{x: -0.348, y: 1.72, z: -0.385, t: 10.3}],\n",
-       " [{x: -0.818, y: -1.59, z: -0.719, t: 9.27}],\n",
-       " [{x: -0.15, y: -1.29, z: 1.05, t: 8.68}],\n",
-       " [{x: 0.789, y: 1.43, z: 0.76, t: 8.26}],\n",
-       " [],\n",
-       " [{x: -0.151, y: 1.87, z: -0.418, t: 10.8}, ..., {x: 1.16, y: -0.342, ...}],\n",
+       "
[[{x: 1.41, y: -0.901, z: 0.763, t: 10.6}, {x: -0.38, y: -0.899, ...}],\n",
+       " [{x: 0.694, y: 0.695, z: -0.0238, t: 10.6}],\n",
+       " [{x: 0.112, y: 0.807, z: -0.219, t: 11.2}],\n",
+       " [{x: -0.259, y: 1.98, z: -0.841, t: 8.5}, ..., {x: -0.939, y: 1.68, ...}],\n",
+       " [{x: -0.0887, y: -0.262, z: -0.644, t: 10.8}, {x: 0.491, y: 0.922, ...}],\n",
+       " [{x: -1.08, y: 0.385, z: -0.338, t: 10.6}],\n",
+       " [{x: 0.00183, y: -1.68, z: -3, t: 9.62}, {x: -2.42, y: -0.388, ...}],\n",
        " [],\n",
-       " [{x: 0.111, y: -0.17, z: -1.85, t: 10.4}],\n",
+       " [{x: -0.926, y: 0.902, z: -1.42, t: 10.6}],\n",
+       " [{x: 0.947, y: -0.514, z: 0.964, t: 9.3}, ..., {x: 0.0534, y: -1.37, ...}],\n",
        " ...,\n",
-       " [{x: 0.281, y: 1.15, z: -0.604, t: 9.11}],\n",
-       " [{x: 1.19, y: 0.0225, z: 0.453, t: 10.4}],\n",
-       " [],\n",
-       " [{x: 0.637, y: 1.12, z: -0.651, t: 9.12}],\n",
-       " [{x: -0.609, y: -0.739, z: -0.225, t: 8.64}, {x: 0.326, y: -0.913, ...}],\n",
-       " [{x: 0.996, y: 1.03, z: 1.92, t: 9.4}],\n",
-       " [{x: 0.174, y: 0.759, z: 0.298, t: 9.74}],\n",
-       " [{x: 0.0768, y: -1.53, z: 1.87, t: 10.4}],\n",
-       " [{x: -1.22, y: -0.848, z: -0.486, t: 8.1}, {x: 0.487, y: 2.11, ...}]]\n",
-       "----------------------------------------------------------------------------\n",
+       " [{x: 0.192, y: -1.67, z: 0.301, t: 9.35}, ..., {x: -0.0262, y: -0.865, ...}],\n",
+       " [{x: -0.0415, y: 1.21, z: 0.00125, t: 10.3}, {x: -0.839, y: -1.75, ...}],\n",
+       " [{x: 1.27, y: -0.237, z: 0.983, t: 11.9}, {x: -0.694, y: -1.02, ...}],\n",
+       " [{x: 1.36, y: -1.6, z: 0.367, t: 10.7}],\n",
+       " [{x: 0.814, y: 0.736, z: 0.477, t: 9.68}, {x: -0.584, y: -0.839, ...}],\n",
+       " [{x: -0.655, y: -0.226, z: -1.33, t: 10.9}],\n",
+       " [{x: 1.52, y: -1.55, z: -0.0578, t: 10.7}, ..., {x: -0.518, y: 0.536, ...}],\n",
+       " [{x: 0.108, y: -1.15, z: 0.0149, t: 10.8}],\n",
+       " [{x: 1.43, y: 0.865, z: 0.714, t: 11.7}]]\n",
+       "------------------------------------------------------------------------------\n",
        "type: 50 * var * Momentum4D[\n",
        "    x: float64,\n",
        "    y: float64,\n",
@@ -2880,7 +2897,7 @@
        "]
" ], "text/plain": [ - "" + "" ] }, "execution_count": 93, @@ -2932,16 +2949,16 @@ { "data": { "text/plain": [ - "array([11.41642718, 22.27865971, 10.18939374, 9.07252983, 8.51331485,\n", - " 8.06422211, 0. , 29.352758 , 0. , 10.21844468,\n", - " 11.34362616, 21.10216985, 11.4527522 , 20.14324739, 9.98358839,\n", - " 18.23053058, 10.98279243, 11.19606712, 10.26290851, 0. ,\n", - " 38.84013335, 8.15996425, 0. , 0. , 30.09499597,\n", - " 19.91427266, 19.72327799, 8.73084137, 20.89841204, 31.50194351,\n", - " 21.27361129, 9.11625113, 16.13237037, 31.6223863 , 52.00371003,\n", - " 9.42533027, 18.02849722, 9.26139639, 0. , 9.28157987,\n", - " 30.40031906, 9.01300947, 10.32904192, 0. , 9.0039702 ,\n", - " 18.76867382, 9.0933228 , 9.70217628, 10.06981863, 19.48030101])" + "array([20.88220754, 10.53170609, 11.21468016, 26.33429737, 20.48308935,\n", + " 10.51241181, 20.78089779, 0. , 10.45554506, 28.2211139 ,\n", + " 22.22801872, 11.45653631, 0. , 7.96604642, 9.95269283,\n", + " 30.19888184, 11.71400053, 0. , 8.83214695, 9.68286926,\n", + " 19.89135993, 9.41755798, 20.90063205, 18.0202406 , 27.40962418,\n", + " 20.30674879, 20.87463364, 0. , 6.90502287, 21.26435081,\n", + " 40.96597368, 8.12985287, 9.66074722, 27.32425275, 0. ,\n", + " 8.90431149, 28.39958412, 11.00856468, 18.64689922, 11.0683125 ,\n", + " 8.67699199, 27.02091581, 19.71353858, 22.29015586, 10.53469868,\n", + " 18.40816583, 10.82519197, 28.88657042, 10.71976876, 11.58433718])" ] }, "execution_count": 95, @@ -2976,6 +2993,14 @@ "\n", "First major release of vector is out and the package has reached a stable position. The work is spearheaded by bug reports and feature requests created on GitHub. It can only be improved by your feedback!" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ab4764f-b030-4831-9568-e46e47faf40a", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From 5e2e77265c7c0cab3ccfcdf2a68313035015a0a4 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Fri, 23 Feb 2024 18:56:37 +0100 Subject: [PATCH 04/11] format --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 57749ba2..d433f247 100644 --- a/README.md +++ b/README.md @@ -537,7 +537,11 @@ For a few operations - `+`, `-`, `==`, `!=`, ... - the dimension of the vectors v1 = vector.obj(x=1, y=2, z=3) v2 = vector.obj(x=1, y=2) -v1 - v2.like(v1), v1.like(v2) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D(z=3), v1.to_Vector2D() - v2 +v1 - v2.like(v1), v1.like( + v2 +) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D( + z=3 +), v1.to_Vector2D() - v2 ``` The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed. From 09b2de8eeac9310920d19f80f5124b1621c2381c Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Mon, 26 Feb 2024 13:33:22 +0100 Subject: [PATCH 05/11] Better type checks and better type hints for vector methods --- src/vector/_methods.py | 131 ++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/src/vector/_methods.py b/src/vector/_methods.py index c5150f8f..cb292382 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -788,7 +788,7 @@ def neg3D(self: SameVectorType) -> SameVectorType: """ raise AssertionError - def cross(self, other: VectorProtocol) -> VectorProtocolSpatial: + def cross(self, other: VectorProtocolSpatial) -> VectorProtocolSpatial: """ The 3D cross-product of ``self`` with ``other``. @@ -796,18 +796,24 @@ def cross(self, other: VectorProtocol) -> VectorProtocolSpatial: """ raise AssertionError - def deltaangle(self, other: VectorProtocol) -> ScalarCollection: + def deltaangle( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: r""" Angle in 3D space between ``self`` and ``other``, which is always positive, between $0$ and $\pi$. """ raise AssertionError - def deltaeta(self, other: VectorProtocol) -> ScalarCollection: + def deltaeta( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: r"""Signed difference in $\eta$ of ``self`` minus ``other``.""" raise AssertionError - def deltaR(self, other: VectorProtocol) -> ScalarCollection: + def deltaR( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: r""" Sum in quadrature of :meth:`vector._methods.VectorProtocolPlanar.deltaphi` and :meth:`vector._methods.VectorProtocolSpatial.deltaeta`: @@ -816,7 +822,9 @@ def deltaR(self, other: VectorProtocol) -> ScalarCollection: """ raise AssertionError - def deltaR2(self, other: VectorProtocol) -> ScalarCollection: + def deltaR2( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: r""" Square of the sum in quadrature of :meth:`vector._methods.VectorProtocolPlanar.deltaphi` and @@ -847,7 +855,7 @@ def rotateY(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: raise AssertionError def rotate_axis( - self: SameVectorType, axis: VectorProtocol, angle: ScalarCollection + self: SameVectorType, axis: VectorProtocolSpatial, angle: ScalarCollection ) -> SameVectorType: """ Rotates the vector(s) by a given ``angle`` (in radians) around the @@ -1054,7 +1062,7 @@ def rapidity(self) -> ScalarCollection: """ raise AssertionError - def deltaRapidityPhi(self, other: VectorProtocol) -> ScalarCollection: + def deltaRapidityPhi(self, other: VectorProtocolLorentz) -> ScalarCollection: r""" Sum in quadrature of :meth:`vector._methods.VectorProtocolPlanar.deltaphi` and the difference in :attr:`vector._methods.VectorProtocolLorentz.rapidity` @@ -1064,7 +1072,7 @@ def deltaRapidityPhi(self, other: VectorProtocol) -> ScalarCollection: """ raise AssertionError - def deltaRapidityPhi2(self, other: VectorProtocol) -> ScalarCollection: + def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: r""" Square of the sum in quadrature of :meth:`vector._methods.VectorProtocolPlanar.deltaphi` and the difference in @@ -3443,30 +3451,24 @@ def is_parallel( ) -> BoolCollection: from vector._compute.planar import is_parallel - if not isinstance(other, Vector2D): - return self.to_Vector3D().is_parallel(other, tolerance=tolerance) - else: - return is_parallel.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_parallel.__name__) + return is_parallel.dispatch(tolerance, self, other) def is_antiparallel( self, other: VectorProtocol, tolerance: ScalarCollection = 1e-5 ) -> BoolCollection: from vector._compute.planar import is_antiparallel - if not isinstance(other, Vector2D): - return self.to_Vector3D().is_antiparallel(other, tolerance=tolerance) - else: - return is_antiparallel.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_antiparallel.__name__) + return is_antiparallel.dispatch(tolerance, self, other) def is_perpendicular( self, other: VectorProtocol, tolerance: ScalarCollection = 1e-5 ) -> BoolCollection: from vector._compute.planar import is_perpendicular - if not isinstance(other, Vector2D): - return self.to_Vector3D().is_perpendicular(other, tolerance=tolerance) - else: - return is_perpendicular.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_perpendicular.__name__) + return is_perpendicular.dispatch(tolerance, self, other) def unit(self: SameVectorType) -> SameVectorType: from vector._compute.planar import unit @@ -3474,17 +3476,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3507,13 +3509,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import not_equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -3525,7 +3527,7 @@ def isclose( ) -> BoolCollection: from vector._compute.planar import isclose - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3572,27 +3574,35 @@ def mag2(self) -> ScalarCollection: return mag2.dispatch(self) - def cross(self, other: VectorProtocol) -> VectorProtocolSpatial: + def cross(self, other: VectorProtocolSpatial) -> VectorProtocolSpatial: from vector._compute.spatial import cross return cross.dispatch(self, other) - def deltaangle(self, other: VectorProtocol) -> ScalarCollection: + def deltaangle( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: from vector._compute.spatial import deltaangle return deltaangle.dispatch(self, other) - def deltaeta(self, other: VectorProtocol) -> ScalarCollection: + def deltaeta( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: from vector._compute.spatial import deltaeta return deltaeta.dispatch(self, other) - def deltaR(self, other: VectorProtocol) -> ScalarCollection: + def deltaR( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: from vector._compute.spatial import deltaR return deltaR.dispatch(self, other) - def deltaR2(self, other: VectorProtocol) -> ScalarCollection: + def deltaR2( + self, other: VectorProtocolSpatial | VectorProtocolLorentz + ) -> ScalarCollection: from vector._compute.spatial import deltaR2 return deltaR2.dispatch(self, other) @@ -3608,7 +3618,7 @@ def rotateY(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: return rotateY.dispatch(angle, self) def rotate_axis( - self: SameVectorType, axis: VectorProtocol, angle: ScalarCollection + self: SameVectorType, axis: VectorProtocolSpatial, angle: ScalarCollection ) -> SameVectorType: from vector._compute.spatial import rotate_axis @@ -3658,30 +3668,24 @@ def is_parallel( ) -> BoolCollection: from vector._compute.spatial import is_parallel - if isinstance(other, Vector2D): - return is_parallel.dispatch(tolerance, self, other.to_Vector3D()) - else: - return is_parallel.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_parallel.__name__) + return is_parallel.dispatch(tolerance, self, other) def is_antiparallel( self, other: VectorProtocol, tolerance: ScalarCollection = 1e-5 ) -> BoolCollection: from vector._compute.spatial import is_antiparallel - if isinstance(other, Vector2D): - return is_antiparallel.dispatch(tolerance, self, other.to_Vector3D()) - else: - return is_antiparallel.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_antiparallel.__name__) + return is_antiparallel.dispatch(tolerance, self, other) def is_perpendicular( self, other: VectorProtocol, tolerance: ScalarCollection = 1e-5 ) -> BoolCollection: from vector._compute.spatial import is_perpendicular - if isinstance(other, Vector2D): - return is_perpendicular.dispatch(tolerance, self, other.to_Vector3D()) - else: - return is_perpendicular.dispatch(tolerance, self, other) + _maybe_dimension_error(self, other, self.is_perpendicular.__name__) + return is_perpendicular.dispatch(tolerance, self, other) def unit(self: SameVectorType) -> SameVectorType: from vector._compute.spatial import unit @@ -3689,17 +3693,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3733,13 +3737,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import not_equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -3751,7 +3755,7 @@ def isclose( ) -> BoolCollection: from vector._compute.spatial import isclose - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3798,12 +3802,12 @@ def rapidity(self) -> ScalarCollection: return rapidity.dispatch(self) - def deltaRapidityPhi(self, other: VectorProtocol) -> ScalarCollection: + def deltaRapidityPhi(self, other: VectorProtocolLorentz) -> ScalarCollection: from vector._compute.lorentz import deltaRapidityPhi return deltaRapidityPhi.dispatch(self, other) - def deltaRapidityPhi2(self, other: VectorProtocol) -> ScalarCollection: + def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: from vector._compute.lorentz import deltaRapidityPhi2 return deltaRapidityPhi2.dispatch(self, other) @@ -3933,17 +3937,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3988,13 +3992,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import not_equal - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -4006,7 +4010,7 @@ def isclose( ) -> BoolCollection: from vector._compute.lorentz import isclose - _is_same_dimension(self, other) + _maybe_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -4176,19 +4180,22 @@ def dim(v: VectorProtocol) -> int: raise TypeError(f"{v!r} is not a vector.Vector") -def _is_same_dimension(v1: VectorProtocol, v2: VectorProtocol) -> None: +def _maybe_dimension_error( + v1: VectorProtocol, v2: VectorProtocol, operation: str +) -> None: """Raises an error if the vectors are not of the same dimension.""" if dim(v1) != dim(v2): raise TypeError( f"""{v1!r} and {v2!r} do not have the same dimension; use - a.like(b) + b + a.like(b).{operation}(b) or - a + b.like(a) + a.{operation}(b.like(a)) - to project or embed one of the vectors to match the other's dimensionality + or the binary operation equivalent to project or embed one of the vectors + to match the other's dimensionality """ ) From c9636f0e29b31428fcd800b895fbc53961e4b6d8 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Mon, 26 Feb 2024 15:39:42 +0100 Subject: [PATCH 06/11] Fix notebook tests --- README.md | 6 - docs/usage/intro.ipynb | 383 +++++++++++++++++++---------------------- 2 files changed, 177 insertions(+), 212 deletions(-) diff --git a/README.md b/README.md index d433f247..6bd2efc6 100644 --- a/README.md +++ b/README.md @@ -544,12 +544,6 @@ v1 - v2.like(v1), v1.like( ), v1.to_Vector2D() - v2 ``` -The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed. - -``` -vector.obj(x=1, y=2, z=0).is_parallel(vector.obj(x=1, y=2)) -``` - And finally, in some cases, the function excludes a higher-dimensional component, even if the input vectors had them. It would be confusing if the 3D cross-product returned a fourth component. diff --git a/docs/usage/intro.ipynb b/docs/usage/intro.ipynb index 12df82c3..6a17d4e5 100644 --- a/docs/usage/intro.ipynb +++ b/docs/usage/intro.ipynb @@ -1452,60 +1452,60 @@ { "data": { "text/plain": [ - "MomentumNumpy3D([[[(-1.42913487, -0.20404998, -0.8992022 ),\n", - " (-1.50965637, -1.58581616, -2.26896045)],\n", - " [( 0.5793101 , -0.47534844, -1.28655128),\n", - " ( 1.74174173, -0.44064342, 0.75934888)],\n", - " [(-0.63649546, 0.5248589 , 0.4353472 ),\n", - " (-0.29766214, 0.28088943, -0.38635832)],\n", - " [(-1.58539851, -0.90099393, 0.73724365),\n", - " ( 0.48743887, -0.56026569, 0.16054964)],\n", - " [(-1.1635853 , 0.00537231, 0.58857628),\n", - " (-1.21782518, -0.00401369, -0.33790633)]],\n", + "MomentumNumpy3D([[[( 1.14310134, 0.04076119, -2.38674108),\n", + " (-1.59113482, -1.41531688, -0.00415859)],\n", + " [(-0.85778946, 1.19156618, 0.42684957),\n", + " ( 0.87415999, 0.03776744, -0.06974114)],\n", + " [( 1.12112981, 0.91596911, 0.26536476),\n", + " ( 0.60581628, 0.01216962, -0.53123266)],\n", + " [( 1.35383052, 1.17849912, 0.29147758),\n", + " ( 1.69584683, -0.34846407, -1.77237757)],\n", + " [( 0.38728751, 0.60588514, 0.38205531),\n", + " ( 0.56495441, -0.51471862, -1.08648223)]],\n", "\n", - " [[(-1.25874469, -0.75320216, -1.50702232),\n", - " ( 0.21525424, 0.34164511, 0.23212705)],\n", - " [( 1.38764489, -1.55627838, 0.26229165),\n", - " ( 0.10222743, 0.62900046, -1.31097117)],\n", - " [(-0.65710113, 0.89476612, -0.41780337),\n", - " ( 0.36444657, 0.07499156, 0.76627191)],\n", - " [(-0.74980871, 1.17914399, -0.73711352),\n", - " (-0.47166194, -0.30031473, 0.75332702)],\n", - " [(-0.67590893, -0.22366163, 1.0278958 ),\n", - " ( 0.06939478, 0.37879193, -0.68323822)]],\n", + " [[( 0.75605075, -0.31525392, 1.72202298),\n", + " (-1.53589478, 0.43887318, -1.32548718)],\n", + " [( 1.10545645, 0.13606777, 2.38726118),\n", + " ( 1.01183334, -1.21837694, -0.06722514)],\n", + " [( 0.42525065, 1.16954822, -1.74887793),\n", + " (-1.19231098, 0.08543114, -0.76000438)],\n", + " [(-2.13832662, 1.64487571, -0.87539254),\n", + " ( 0.57871964, -1.2624124 , -0.76478936)],\n", + " [( 0.85573079, 2.00232795, -0.41417169),\n", + " (-0.66196943, -2.97189753, 0.18161709)]],\n", "\n", - " [[( 1.51628366, -0.52196473, 0.71691781),\n", - " ( 2.55630317, 0.99490967, -1.13367178)],\n", - " [(-0.11869339, -0.69920031, -0.34393436),\n", - " ( 0.54860171, -1.50186676, -1.0930652 )],\n", - " [(-0.87201802, -1.29564802, -0.44148477),\n", - " (-0.57861467, -1.31234899, 1.82999728)],\n", - " [( 0.13586229, 0.96615212, 1.82739502),\n", - " (-0.94599231, -1.32164925, -0.65439075)],\n", - " [(-0.01598523, -0.33254174, 0.24804779),\n", - " (-0.10264518, -0.81005823, 1.44981102)]],\n", + " [[(-1.59381428, 0.14395391, -0.38304042),\n", + " (-0.64830114, -0.72871718, 0.0791469 )],\n", + " [( 1.24400048, -1.22252657, -0.66663965),\n", + " (-1.29169976, 0.40907738, -1.26536454)],\n", + " [( 0.07929 , 0.97787651, 0.49180193),\n", + " (-0.29955594, -1.17971501, 0.60312468)],\n", + " [( 0.43048906, -1.03071749, 1.15226996),\n", + " ( 1.44488059, -0.43218728, 0.98032298)],\n", + " [( 0.01860346, -1.5267734 , -0.40886292),\n", + " (-1.2987315 , -0.51493367, 0.05935923)]],\n", "\n", - " [[( 1.08589702, -0.63395122, -0.67596226),\n", - " (-0.09043662, -1.02783004, 0.14100503)],\n", - " [( 0.36900529, -0.20551341, 1.20770009),\n", - " (-1.45570726, 1.44865298, 1.70384269)],\n", - " [(-1.61330367, -0.16610241, -0.68345571),\n", - " ( 0.18759582, 1.87281996, -0.57175207)],\n", - " [( 0.63015684, -0.91842193, -0.91528516),\n", - " (-0.3936394 , -1.61370204, -0.57485609)],\n", - " [(-0.8178419 , 0.32550864, 1.10467835),\n", - " (-0.55037021, 1.04750445, 0.4554011 )]],\n", + " [[(-0.1351796 , 1.15099635, -0.79196155),\n", + " (-0.41065448, 1.56503126, -1.21529644)],\n", + " [( 0.98858534, 0.57254881, 1.34039538),\n", + " (-0.12529945, 0.38560386, -0.81094122)],\n", + " [( 0.70603463, 0.91762652, -0.51801275),\n", + " ( 0.91189934, -1.40406059, 0.71311764)],\n", + " [(-2.05783447, -0.652841 , 0.33237834),\n", + " (-0.46177674, -0.37394158, 0.84820453)],\n", + " [(-0.00412412, 0.44646467, 1.26564905),\n", + " ( 0.03241197, -0.13041014, -0.24966663)]],\n", "\n", - " [[(-0.97167348, -0.13764255, -0.73902296),\n", - " ( 2.14773563, 0.07980281, -0.91068575)],\n", - " [(-0.16119949, 0.49284801, 0.04834321),\n", - " (-0.95413822, -0.3790709 , 0.25909865)],\n", - " [(-1.56135351, -0.01127451, 1.24677082),\n", - " (-0.28788099, -0.02051752, -1.03206188)],\n", - " [(-1.40280634, 0.84274277, 1.21150726),\n", - " ( 0.37774258, 0.27045825, -0.80279231)],\n", - " [( 0.89741189, 0.72263796, 1.17414993),\n", - " (-0.39162535, 1.88167979, 0.15871216)]]],\n", + " [[( 1.25108608, -0.24668532, -0.56496872),\n", + " ( 1.55870783, -0.00336201, 1.1202958 )],\n", + " [( 0.31118974, 0.28744953, -1.11356153),\n", + " ( 1.42489052, -0.33189196, 0.58697126)],\n", + " [(-0.61623195, -0.73835331, -0.40281076),\n", + " ( 0.2628457 , -0.97571113, 0.83446954)],\n", + " [( 0.51875244, 0.02255606, 1.47724329),\n", + " ( 1.15313722, -0.63396881, -0.15501412)],\n", + " [(-1.17243173, -0.60935566, -0.28609093),\n", + " ( 0.07677401, -0.80639786, -0.50941015)]]],\n", " dtype=[('x', '[[{x: -0.714, y: 0.847, z: 0.146}, {x: 0.256, y: -0.56, z: -1.42}],\n", - " [{x: -0.835, y: 0.471, z: -0.0945}, ..., {x: -1.87, y: -2.23, z: -0.498}],\n", - " [{x: 0.0678, y: -0.28, z: 0.942}, {...}, ..., {x: -1.71, y: 0.315, z: 1.19}],\n", - " [{x: -0.162, y: -1.22, z: -1.76}, {...}, {x: -0.717, y: -0.219, z: -1.1}],\n", - " [{x: -0.325, y: 0.296, z: -1.3}, {...}, {x: -2.26, y: 1.14, z: 0.533}],\n", - " [{x: -0.77, y: 0.2, z: 0.235}],\n", - " [{x: 0.0141, y: 2.02, z: -0.323}, {x: -0.76, y: 1.08, z: -0.828}],\n", - " [{x: 0.338, y: 1.1, z: 0.0861}, {...}, {x: -0.354, y: -1.27, z: 1.35}],\n", - " [{x: -0.602, y: 1.84, z: 0.611}],\n", - " [{x: -1.25, y: -0.707, z: -0.113}],\n", - " ...,\n", - " [],\n", - " [{x: -0.171, y: 1.32, z: -0.144}, {x: -0.607, y: -0.153, z: -1.06}],\n", - " [{x: 0.261, y: 0.786, z: 0.233}],\n", - " [{x: -0.0354, y: -0.71, z: 0.75}],\n", - " [{x: 0.0199, y: -0.0305, z: 1.22}],\n", + "
[[{x: -0.738, y: 0.842, z: 0.387}],\n",
+       " [{x: 0.25, y: 1.04, z: -0.654}, {x: 0.21, y: -1.41, z: 1.04}],\n",
+       " [{x: -0.704, y: 1.81, z: 0.597}],\n",
        " [],\n",
+       " [{x: 0.512, y: -1.23, z: -1.2}],\n",
+       " [{x: -1.56, y: 0.219, z: 1.47}, {x: -0.501, y: -0.425, z: 1.96}],\n",
+       " [{x: -1.19, y: -1.09, z: 0.551}],\n",
+       " [{x: -0.636, y: -0.0598, z: -0.948}],\n",
+       " [{x: 1.69, y: -0.308, z: -0.519}, {x: 0.442, y: -0.375, z: -0.824}],\n",
+       " [{x: 1.97, y: -0.267, z: 0.727}],\n",
+       " ...,\n",
+       " [{x: 0.115, y: 0.511, z: 0.704}],\n",
+       " [{x: -0.363, y: -0.417, z: -0.36}],\n",
+       " [{x: 0.0166, y: 0.626, z: -1.22}],\n",
+       " [{x: 0.154, y: 1.1, z: 0.339}],\n",
+       " [{x: -1.19, y: 0.712, z: -2.57}],\n",
+       " [{x: -0.156, y: 2.11, z: -2.66}, ..., {x: -0.373, y: -0.611, z: -0.476}],\n",
        " [],\n",
-       " [{x: 0.937, y: 0.925, z: 0.643}, {x: 0.998, y: 2.86, z: -1.27}],\n",
-       " [{x: 1.59, y: 2.88, z: -0.971}, {...}, ..., {x: -1.08, y: -2.18, z: 0.961}]]\n",
-       "------------------------------------------------------------------------------\n",
+       " [{x: -1.39, y: 0.788, z: 1.42}, {x: 1.07, y: -1.52, z: 1.1}],\n",
+       " []]\n",
+       "--------------------------------------------------------------------------\n",
        "type: 50 * var * Momentum3D[\n",
        "    x: float64,\n",
        "    y: float64,\n",
@@ -1655,7 +1655,7 @@
        "]
" ], "text/plain": [ - "" + "" ] }, "execution_count": 53, @@ -1686,31 +1686,31 @@ { "data": { "text/html": [ - "
[[1.11, 0.615],\n",
-       " [0.958, 1.35, 2.81, 1.89, 2.91],\n",
-       " [0.289, 1.72, 1.04, 1.74],\n",
-       " [1.23, 0.331, 0.75],\n",
-       " [0.44, 1.41, 2.53],\n",
-       " [0.795],\n",
-       " [2.02, 1.32],\n",
-       " [1.15, 1.28, 1.32],\n",
+       "
[[1.12],\n",
+       " [1.07, 1.43],\n",
        " [1.94],\n",
-       " [1.43],\n",
-       " ...,\n",
-       " [],\n",
-       " [1.33, 0.626],\n",
-       " [0.828],\n",
-       " [0.711],\n",
-       " [0.0364],\n",
        " [],\n",
+       " [1.33],\n",
+       " [1.58, 0.657],\n",
+       " [1.61],\n",
+       " [0.639],\n",
+       " [1.72, 0.579],\n",
+       " [1.98],\n",
+       " ...,\n",
+       " [0.524],\n",
+       " [0.553],\n",
+       " [0.626],\n",
+       " [1.11],\n",
+       " [1.38],\n",
+       " [2.12, 0.381, 0.716],\n",
        " [],\n",
-       " [1.32, 3.02],\n",
-       " [3.29, 0.719, 1.39, 2.93, 2.44]]\n",
-       "---------------------------------\n",
+       " [1.6, 1.86],\n",
+       " []]\n",
+       "------------------------\n",
        "type: 50 * var * float64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 54, @@ -1732,31 +1732,31 @@ { "data": { "text/html": [ - "
[2,\n",
-       " 5,\n",
-       " 4,\n",
-       " 3,\n",
-       " 3,\n",
+       "
[1,\n",
+       " 2,\n",
+       " 1,\n",
+       " 0,\n",
        " 1,\n",
        " 2,\n",
-       " 3,\n",
        " 1,\n",
        " 1,\n",
-       " ...,\n",
-       " 0,\n",
        " 2,\n",
        " 1,\n",
+       " ...,\n",
        " 1,\n",
        " 1,\n",
-       " 0,\n",
+       " 1,\n",
+       " 1,\n",
+       " 1,\n",
+       " 3,\n",
        " 0,\n",
        " 2,\n",
-       " 5]\n",
+       " 0]\n",
        "----------------\n",
        "type: 50 * int64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 55, @@ -1778,31 +1778,31 @@ { "data": { "text/html": [ - "
[2,\n",
-       " 5,\n",
-       " 4,\n",
-       " 3,\n",
-       " 3,\n",
+       "
[1,\n",
+       " 2,\n",
+       " 1,\n",
+       " 0,\n",
        " 1,\n",
        " 2,\n",
-       " 3,\n",
        " 1,\n",
        " 1,\n",
-       " ...,\n",
-       " 0,\n",
        " 2,\n",
        " 1,\n",
+       " ...,\n",
        " 1,\n",
        " 1,\n",
-       " 0,\n",
+       " 1,\n",
+       " 1,\n",
+       " 1,\n",
+       " 3,\n",
        " 0,\n",
        " 2,\n",
-       " 5]\n",
+       " 0]\n",
        "----------------\n",
        "type: 50 * int64
" ], "text/plain": [ - "" + "" ] }, "execution_count": 56, @@ -2655,35 +2655,6 @@ "v1 - v2.like(v1), v1.like(v2) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D(z=3), v1.to_Vector2D() - v2" ] }, - { - "cell_type": "markdown", - "id": "e43155a9-9d3a-4e2e-b21e-192f5bb86d94", - "metadata": {}, - "source": [ - "The opposite—using low-dimensional vectors in operations defined for higher numbers of dimensions—is sometimes defined. In these cases, a zero longitudinal or temporal component has to be imputed." - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "atomic-corps", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 89, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vector.obj(x=1, y=2, z=0).is_parallel(vector.obj(x=1, y=2))" - ] - }, { "cell_type": "markdown", "id": "willing-detail", @@ -2696,7 +2667,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 89, "id": "preceding-possibility", "metadata": {}, "outputs": [ @@ -2706,7 +2677,7 @@ "VectorObject3D(x=-0.03, y=0.06, z=-0.030000000000000013)" ] }, - "execution_count": 90, + "execution_count": 89, "metadata": {}, "output_type": "execute_result" } @@ -2818,7 +2789,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 90, "id": "sporting-champion", "metadata": {}, "outputs": [], @@ -2830,7 +2801,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 91, "id": "blocked-attribute", "metadata": {}, "outputs": [ @@ -2840,7 +2811,7 @@ "8.0" ] }, - "execution_count": 92, + "execution_count": 91, "metadata": {}, "output_type": "execute_result" } @@ -2861,34 +2832,34 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 92, "id": "round-supplier", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
[[{x: 1.41, y: -0.901, z: 0.763, t: 10.6}, {x: -0.38, y: -0.899, ...}],\n",
-       " [{x: 0.694, y: 0.695, z: -0.0238, t: 10.6}],\n",
-       " [{x: 0.112, y: 0.807, z: -0.219, t: 11.2}],\n",
-       " [{x: -0.259, y: 1.98, z: -0.841, t: 8.5}, ..., {x: -0.939, y: 1.68, ...}],\n",
-       " [{x: -0.0887, y: -0.262, z: -0.644, t: 10.8}, {x: 0.491, y: 0.922, ...}],\n",
-       " [{x: -1.08, y: 0.385, z: -0.338, t: 10.6}],\n",
-       " [{x: 0.00183, y: -1.68, z: -3, t: 9.62}, {x: -2.42, y: -0.388, ...}],\n",
-       " [],\n",
-       " [{x: -0.926, y: 0.902, z: -1.42, t: 10.6}],\n",
-       " [{x: 0.947, y: -0.514, z: 0.964, t: 9.3}, ..., {x: 0.0534, y: -1.37, ...}],\n",
+       "
[[{x: 1.7, y: 0.249, z: -0.301, t: 9.68}, ..., {x: -0.395, y: 0.503, ...}],\n",
+       " [{x: 0.93, y: 0.156, z: -1.84, t: 9.23}, {x: 0.937, y: 0.018, ...}],\n",
+       " [{x: 2.6, y: 0.0762, z: -1.75, t: 9.02}, ..., {x: -1.03, y: 0.604, ...}],\n",
+       " [{x: -0.409, y: -0.199, z: 1.25, t: 11.3}],\n",
+       " [{x: 1.12, y: -0.537, z: -0.617, t: 9.6}],\n",
+       " [{x: -0.703, y: -1.95, z: 0.877, t: 10}, {x: -0.0276, y: 0.224, ...}],\n",
+       " [{x: 0.603, y: 0.105, z: 0.264, t: 11.5}],\n",
+       " [{x: 0.245, y: -0.547, z: -0.578, t: 10.4}],\n",
+       " [{x: -0.216, y: 1.01, z: 0.517, t: 10.8}, ..., {x: 0.0722, y: 0.25, ...}],\n",
+       " [{x: 0.472, y: -1.33, z: 2.03, t: 10.7}],\n",
        " ...,\n",
-       " [{x: 0.192, y: -1.67, z: 0.301, t: 9.35}, ..., {x: -0.0262, y: -0.865, ...}],\n",
-       " [{x: -0.0415, y: 1.21, z: 0.00125, t: 10.3}, {x: -0.839, y: -1.75, ...}],\n",
-       " [{x: 1.27, y: -0.237, z: 0.983, t: 11.9}, {x: -0.694, y: -1.02, ...}],\n",
-       " [{x: 1.36, y: -1.6, z: 0.367, t: 10.7}],\n",
-       " [{x: 0.814, y: 0.736, z: 0.477, t: 9.68}, {x: -0.584, y: -0.839, ...}],\n",
-       " [{x: -0.655, y: -0.226, z: -1.33, t: 10.9}],\n",
-       " [{x: 1.52, y: -1.55, z: -0.0578, t: 10.7}, ..., {x: -0.518, y: 0.536, ...}],\n",
-       " [{x: 0.108, y: -1.15, z: 0.0149, t: 10.8}],\n",
-       " [{x: 1.43, y: 0.865, z: 0.714, t: 11.7}]]\n",
-       "------------------------------------------------------------------------------\n",
+       " [],\n",
+       " [{x: 0.755, y: 0.6, z: -0.514, t: 11}],\n",
+       " [{x: 0.285, y: 0.578, z: -1.98, t: 11}, ..., {x: -0.265, y: 0.287, ...}],\n",
+       " [{x: -0.264, y: -0.604, z: 0.543, t: 10.4}],\n",
+       " [{x: 1.1, y: 0.508, z: -1.28, t: 10.2}, ..., {x: 0.543, y: 1.68, z: ..., ...}],\n",
+       " [{x: 0.524, y: 0.936, z: -0.827, t: 9.85}],\n",
+       " [{x: 0.0945, y: -0.195, z: -0.00756, t: 10.6}, ..., {x: -0.0538, y: ..., ...}],\n",
+       " [{x: -0.128, y: 0.0627, z: -1.4, t: 10.6}, ..., {x: 1.55, y: -0.909, ...}],\n",
+       " []]\n",
+       "--------------------------------------------------------------------------------\n",
        "type: 50 * var * Momentum4D[\n",
        "    x: float64,\n",
        "    y: float64,\n",
@@ -2897,10 +2868,10 @@
        "]
" ], "text/plain": [ - "" + "" ] }, - "execution_count": 93, + "execution_count": 92, "metadata": {}, "output_type": "execute_result" } @@ -2924,7 +2895,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 93, "id": "emotional-headquarters", "metadata": {}, "outputs": [], @@ -2942,26 +2913,26 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 94, "id": "recorded-grass", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([20.88220754, 10.53170609, 11.21468016, 26.33429737, 20.48308935,\n", - " 10.51241181, 20.78089779, 0. , 10.45554506, 28.2211139 ,\n", - " 22.22801872, 11.45653631, 0. , 7.96604642, 9.95269283,\n", - " 30.19888184, 11.71400053, 0. , 8.83214695, 9.68286926,\n", - " 19.89135993, 9.41755798, 20.90063205, 18.0202406 , 27.40962418,\n", - " 20.30674879, 20.87463364, 0. , 6.90502287, 21.26435081,\n", - " 40.96597368, 8.12985287, 9.66074722, 27.32425275, 0. ,\n", - " 8.90431149, 28.39958412, 11.00856468, 18.64689922, 11.0683125 ,\n", - " 8.67699199, 27.02091581, 19.71353858, 22.29015586, 10.53469868,\n", - " 18.40816583, 10.82519197, 28.88657042, 10.71976876, 11.58433718])" + "array([37.87458105, 19.89350458, 38.74617952, 11.25901267, 9.50308655,\n", + " 20.71338166, 11.53055761, 10.35598971, 31.74903367, 10.4220635 ,\n", + " 10.43149905, 10.31884446, 0. , 0. , 9.29368283,\n", + " 8.84646165, 18.98212112, 25.48676509, 0. , 53.34671524,\n", + " 0. , 10.61023154, 32.11159754, 7.43213454, 40.20275895,\n", + " 8.38033058, 9.98795583, 20.69913567, 9.8042269 , 18.20393596,\n", + " 28.50762131, 20.30326887, 10.79385404, 11.39869969, 9.33530947,\n", + " 10.67734045, 21.5368318 , 20.32839567, 10.82890729, 9.93452047,\n", + " 11.86800978, 0. , 10.9076571 , 30.08678732, 10.33515661,\n", + " 39.84025055, 9.7601356 , 30.493263 , 32.28139112, 0. ])" ] }, - "execution_count": 95, + "execution_count": 94, "metadata": {}, "output_type": "execute_result" } From d35f9ab96b22148eaad74ba882294320774e4eb6 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Thu, 29 Feb 2024 14:25:20 +0100 Subject: [PATCH 07/11] Remove demotion tests --- tests/compute/test_demotion.py | 164 --------------------------------- 1 file changed, 164 deletions(-) delete mode 100644 tests/compute/test_demotion.py diff --git a/tests/compute/test_demotion.py b/tests/compute/test_demotion.py deleted file mode 100644 index 6397c29c..00000000 --- a/tests/compute/test_demotion.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright (c) 2019-2024, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. -# -# Distributed under the 3-clause BSD license, see accompanying file LICENSE -# or https://github.com/scikit-hep/vector for details. - -from __future__ import annotations - -import vector - - -def test_demotion_object(): - v1 = vector.obj(x=0.1, y=0.2) - v2 = vector.obj(x=1, y=2, z=3) - v3 = vector.obj(x=10, y=20, z=30, t=40) - - # order should not matter - assert v1 + v2 == vector.obj(x=1.1, y=2.2) - assert v2 + v1 == vector.obj(x=1.1, y=2.2) - assert v1 + v3 == vector.obj(x=10.1, y=20.2) - assert v3 + v1 == vector.obj(x=10.1, y=20.2) - assert v2 + v3 == vector.obj(x=11, y=22, z=33) - assert v3 + v2 == vector.obj(x=11, y=22, z=33) - - v1 = vector.obj(px=0.1, py=0.2) - v2 = vector.obj(px=1, py=2, pz=3) - v3 = vector.obj(px=10, py=20, pz=30, t=40) - - # order should not matter - assert v1 + v2 == vector.obj(px=1.1, py=2.2) - assert v2 + v1 == vector.obj(px=1.1, py=2.2) - assert v1 + v3 == vector.obj(px=10.1, py=20.2) - assert v3 + v1 == vector.obj(px=10.1, py=20.2) - assert v2 + v3 == vector.obj(px=11, py=22, pz=33) - assert v3 + v2 == vector.obj(px=11, py=22, pz=33) - - v1 = vector.obj(px=0.1, py=0.2) - v2 = vector.obj(x=1, y=2, z=3) - v3 = vector.obj(px=10, py=20, pz=30, t=40) - - # momentum + generic = generic - assert v1 + v2 == vector.obj(x=1.1, y=2.2) - assert v2 + v1 == vector.obj(x=1.1, y=2.2) - assert v1 + v3 == vector.obj(px=10.1, py=20.2) - assert v3 + v1 == vector.obj(px=10.1, py=20.2) - assert v2 + v3 == vector.obj(x=11, y=22, z=33) - assert v3 + v2 == vector.obj(x=11, y=22, z=33) - - -def test_demotion_numpy(): - v1 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - }, - ) - v2 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - v3 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - "t": [16.0, 31.0, 46.0], - }, - ) - - v1_v2 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - }, - ) - v2_v3 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - "z": [10.0, 2.0, 2.0], - }, - ) - v1_v3 = vector.array( - { - "x": [20.0, 40.0, 60.0], - "y": [-20.0, 40.0, 60.0], - }, - ) - - # order should not matter - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) - - v1 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - }, - ) - v2 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - "pz": [5.0, 1.0, 1.0], - }, - ) - v3 = vector.array( - { - "px": [10.0, 20.0, 30.0], - "py": [-10.0, 20.0, 30.0], - "pz": [5.0, 1.0, 1.0], - "t": [16.0, 31.0, 46.0], - }, - ) - - p_v1_v2 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - }, - ) - p_v2_v3 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - "pz": [10.0, 2.0, 2.0], - }, - ) - p_v1_v3 = vector.array( - { - "px": [20.0, 40.0, 60.0], - "py": [-20.0, 40.0, 60.0], - }, - ) - - # order should not matter - assert all(v1 + v2 == p_v1_v2) - assert all(v2 + v1 == p_v1_v2) - assert all(v1 + v3 == p_v1_v3) - assert all(v3 + v1 == p_v1_v3) - assert all(v2 + v3 == p_v2_v3) - assert all(v3 + v2 == p_v2_v3) - - v2 = vector.array( - { - "x": [10.0, 20.0, 30.0], - "y": [-10.0, 20.0, 30.0], - "z": [5.0, 1.0, 1.0], - }, - ) - - # momentum + generic = generic - assert all(v1 + v2 == v1_v2) - assert all(v2 + v1 == v1_v2) - assert all(v1 + v3 == v1_v3) - assert all(v3 + v1 == v1_v3) - assert all(v2 + v3 == v2_v3) - assert all(v3 + v2 == v2_v3) From 0b11c7d39da4a00108a94036a5e0b66ffd7d3a3b Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Fri, 1 Mar 2024 12:55:15 +0100 Subject: [PATCH 08/11] Better usage example --- README.md | 11 ++++++----- docs/usage/intro.ipynb | 7 ++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6bd2efc6..6a81ab48 100644 --- a/README.md +++ b/README.md @@ -537,11 +537,12 @@ For a few operations - `+`, `-`, `==`, `!=`, ... - the dimension of the vectors v1 = vector.obj(x=1, y=2, z=3) v2 = vector.obj(x=1, y=2) -v1 - v2.like(v1), v1.like( - v2 -) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D( - z=3 -), v1.to_Vector2D() - v2 +v1 - v2.like(v1) # transforms v2 to v1's coordinate system (imputes z=0) +v1.like(v2) - v2 # transforms v1 to v2's coordinate system (removes z) +v1 - v2.to_xyz() # transforms v2 to xyz coordinates (imputes z=0) +v1.to_xy() - v2 # transforms v1 to xy coordinates (removes z) +v1 - v2.to_Vector3D(z=3) # transforms v2 to 3D (imputes z=3) +v1.to_Vector2D() - v2 # transforms v1 to 2D (removes z) ``` And finally, in some cases, the function excludes a higher-dimensional component, even if the input vectors had them. diff --git a/docs/usage/intro.ipynb b/docs/usage/intro.ipynb index 6a17d4e5..3270eaa9 100644 --- a/docs/usage/intro.ipynb +++ b/docs/usage/intro.ipynb @@ -2652,7 +2652,12 @@ "v1 = vector.obj(x=1, y=2, z=3)\n", "v2 = vector.obj(x=1, y=2)\n", "\n", - "v1 - v2.like(v1), v1.like(v2) - v2, v1 - v2.to_xyz(), v1.to_xy() - v2, v1 - v2.to_Vector3D(z=3), v1.to_Vector2D() - v2" + "v1 - v2.like(v1) # transforms v2 to v1's coordinate system (imputes z=0)\n", + "v1.like(v2) - v2 # transforms v1 to v2's coordinate system (removes z)\n", + "v1 - v2.to_xyz() # transforms v2 to xyz coordinates (imputes z=0)\n", + "v1.to_xy() - v2 # transforms v1 to xy coordinates (removes z)\n", + "v1 - v2.to_Vector3D(z=3) # transforms v2 to 3D (imputes z=3)\n", + "v1.to_Vector2D() - v2 # transforms v1 to 2D (removes z)" ] }, { From dfaa766fcc6f017412fdb159f803574c7f151345 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Tue, 5 Mar 2024 15:01:26 +0100 Subject: [PATCH 09/11] Explicit error for more methods --- src/vector/_methods.py | 114 ++++++++++++++-------- tests/compute/lorentz/test_boost_beta3.py | 2 +- tests/compute/lorentz/test_boost_p4.py | 2 +- tests/compute/spatial/test_cross.py | 80 ++++++--------- tests/compute/spatial/test_rotate_axis.py | 44 ++++----- 5 files changed, 124 insertions(+), 118 deletions(-) diff --git a/src/vector/_methods.py b/src/vector/_methods.py index cd232628..28ef7412 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -1091,7 +1091,7 @@ def neg4D(self: SameVectorType) -> SameVectorType: """Same as multiplying by -1.""" raise AssertionError - def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: + def boost_p4(self: SameVectorType, p4: MomentumProtocolLorentz) -> SameVectorType: """ Boosts the vector or array of vectors in a direction and magnitude given by the 4D vector or array of vectors ``p4``. @@ -1118,7 +1118,7 @@ def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: raise AssertionError def boost_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial + self: SameVectorType, beta3: MomentumProtocolSpatial ) -> SameVectorType: """ Boosts the vector or array of vectors in a direction and magnitude given @@ -1136,7 +1136,9 @@ def boost_beta3( """ raise AssertionError - def boost(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: + def boost( + self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + ) -> SameVectorType: """ Boosts the vector or array of vectors using the 3D or 4D ``booster``. @@ -1159,7 +1161,7 @@ def boost(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: raise AssertionError def boostCM_of_p4( - self: SameVectorType, p4: VectorProtocolLorentz + self: SameVectorType, p4: MomentumProtocolLorentz ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of @@ -1177,7 +1179,7 @@ def boostCM_of_p4( raise AssertionError def boostCM_of_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial + self: SameVectorType, beta3: MomentumProtocolSpatial ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of @@ -1188,7 +1190,9 @@ def boostCM_of_beta3( """ raise AssertionError - def boostCM_of(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: + def boostCM_of( + self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of the 3D or 4D ``booster``. @@ -3451,7 +3455,7 @@ def is_parallel( ) -> BoolCollection: from vector._compute.planar import is_parallel - _maybe_dimension_error(self, other, self.is_parallel.__name__) + _maybe_same_dimension_error(self, other, self.is_parallel.__name__) return is_parallel.dispatch(tolerance, self, other) def is_antiparallel( @@ -3459,7 +3463,7 @@ def is_antiparallel( ) -> BoolCollection: from vector._compute.planar import is_antiparallel - _maybe_dimension_error(self, other, self.is_antiparallel.__name__) + _maybe_same_dimension_error(self, other, self.is_antiparallel.__name__) return is_antiparallel.dispatch(tolerance, self, other) def is_perpendicular( @@ -3467,7 +3471,7 @@ def is_perpendicular( ) -> BoolCollection: from vector._compute.planar import is_perpendicular - _maybe_dimension_error(self, other, self.is_perpendicular.__name__) + _maybe_same_dimension_error(self, other, self.is_perpendicular.__name__) return is_perpendicular.dispatch(tolerance, self, other) def unit(self: SameVectorType) -> SameVectorType: @@ -3476,17 +3480,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _maybe_dimension_error(self, other, self.dot.__name__) + _maybe_same_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.add.__name__) + _maybe_same_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.subtract.__name__) + _maybe_same_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3509,13 +3513,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import equal - _maybe_dimension_error(self, other, self.equal.__name__) + _maybe_same_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.planar import not_equal - _maybe_dimension_error(self, other, self.not_equal.__name__) + _maybe_same_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -3527,7 +3531,7 @@ def isclose( ) -> BoolCollection: from vector._compute.planar import isclose - _maybe_dimension_error(self, other, self.isclose.__name__) + _maybe_same_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3577,6 +3581,8 @@ def mag2(self) -> ScalarCollection: def cross(self, other: VectorProtocolSpatial) -> VectorProtocolSpatial: from vector._compute.spatial import cross + if dim(self) != 3 or dim(other) != 3: + raise TypeError("cross is only defined for 3D vectors") return cross.dispatch(self, other) def deltaangle( @@ -3584,6 +3590,8 @@ def deltaangle( ) -> ScalarCollection: from vector._compute.spatial import deltaangle + if dim(other) != 3 and dim(other) != 4: + raise TypeError(f"{other!r} is not a 3D or a 4D vector") return deltaangle.dispatch(self, other) def deltaeta( @@ -3591,6 +3599,8 @@ def deltaeta( ) -> ScalarCollection: from vector._compute.spatial import deltaeta + if dim(other) != 3 and dim(other) != 4: + raise TypeError(f"{other!r} is not a 3D or a 4D vector") return deltaeta.dispatch(self, other) def deltaR( @@ -3598,6 +3608,8 @@ def deltaR( ) -> ScalarCollection: from vector._compute.spatial import deltaR + if dim(other) != 3 and dim(other) != 4: + raise TypeError(f"{other!r} is not a 3D or a 4D vector") return deltaR.dispatch(self, other) def deltaR2( @@ -3605,6 +3617,8 @@ def deltaR2( ) -> ScalarCollection: from vector._compute.spatial import deltaR2 + if dim(other) != 3 and dim(other) != 4: + raise TypeError(f"{other!r} is not a 3D or a 4D vector") return deltaR2.dispatch(self, other) def rotateX(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: @@ -3622,6 +3636,8 @@ def rotate_axis( ) -> SameVectorType: from vector._compute.spatial import rotate_axis + if dim(axis) != 3: + raise TypeError(f"{axis!r} is not a 3D vector") return rotate_axis.dispatch(angle, axis, self) def rotate_euler( @@ -3668,7 +3684,7 @@ def is_parallel( ) -> BoolCollection: from vector._compute.spatial import is_parallel - _maybe_dimension_error(self, other, self.is_parallel.__name__) + _maybe_same_dimension_error(self, other, self.is_parallel.__name__) return is_parallel.dispatch(tolerance, self, other) def is_antiparallel( @@ -3676,7 +3692,7 @@ def is_antiparallel( ) -> BoolCollection: from vector._compute.spatial import is_antiparallel - _maybe_dimension_error(self, other, self.is_antiparallel.__name__) + _maybe_same_dimension_error(self, other, self.is_antiparallel.__name__) return is_antiparallel.dispatch(tolerance, self, other) def is_perpendicular( @@ -3684,7 +3700,7 @@ def is_perpendicular( ) -> BoolCollection: from vector._compute.spatial import is_perpendicular - _maybe_dimension_error(self, other, self.is_perpendicular.__name__) + _maybe_same_dimension_error(self, other, self.is_perpendicular.__name__) return is_perpendicular.dispatch(tolerance, self, other) def unit(self: SameVectorType) -> SameVectorType: @@ -3693,17 +3709,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _maybe_dimension_error(self, other, self.dot.__name__) + _maybe_same_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.add.__name__) + _maybe_same_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.subtract.__name__) + _maybe_same_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3737,13 +3753,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import equal - _maybe_dimension_error(self, other, self.equal.__name__) + _maybe_same_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.spatial import not_equal - _maybe_dimension_error(self, other, self.not_equal.__name__) + _maybe_same_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -3755,7 +3771,7 @@ def isclose( ) -> BoolCollection: from vector._compute.spatial import isclose - _maybe_dimension_error(self, other, self.isclose.__name__) + _maybe_same_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -3805,31 +3821,41 @@ def rapidity(self) -> ScalarCollection: def deltaRapidityPhi(self, other: VectorProtocolLorentz) -> ScalarCollection: from vector._compute.lorentz import deltaRapidityPhi + if not dim(other) == 4: + raise TypeError(f"{other!r} is not a 4D vector") return deltaRapidityPhi.dispatch(self, other) def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: from vector._compute.lorentz import deltaRapidityPhi2 + if not dim(other) == 4: + raise TypeError(f"{other!r} is not a 4D vector") return deltaRapidityPhi2.dispatch(self, other) - def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: + def boost_p4(self: SameVectorType, p4: MomentumProtocolLorentz) -> SameVectorType: from vector._compute.lorentz import boost_p4 + if dim(p4) != 4 or not isinstance(p4, LorentzMomentum): + raise TypeError(f"{p4!r} is not a 4D momentum vector") return boost_p4.dispatch(self, p4) def boost_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial + self: SameVectorType, beta3: MomentumProtocolSpatial ) -> SameVectorType: from vector._compute.lorentz import boost_beta3 + if dim(beta3) != 3 or not isinstance(beta3, SpatialMomentum): + raise TypeError(f"{beta3!r} is not a 3D momentum vector") return boost_beta3.dispatch(self, beta3) - def boost(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: + def boost( + self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + ) -> SameVectorType: from vector._compute.lorentz import boost_beta3, boost_p4 - if isinstance(booster, Vector3D): + if isinstance(booster, SpatialMomentum): return boost_beta3.dispatch(self, booster) - elif isinstance(booster, Vector4D): + elif isinstance(booster, LorentzMomentum): return boost_p4.dispatch(self, booster) else: raise TypeError( @@ -3838,25 +3864,31 @@ def boost(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: ) def boostCM_of_p4( - self: SameVectorType, p4: VectorProtocolLorentz + self: SameVectorType, p4: MomentumProtocolLorentz ) -> SameVectorType: from vector._compute.lorentz import boost_p4 + if dim(p4) != 4 or not isinstance(p4, LorentzMomentum): + raise TypeError(f"{p4!r} is not a 4D momentum vector") return boost_p4.dispatch(self, p4.neg3D) def boostCM_of_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial + self: SameVectorType, beta3: MomentumProtocolSpatial ) -> SameVectorType: from vector._compute.lorentz import boost_beta3 + if dim(beta3) != 3 or not isinstance(beta3, SpatialMomentum): + raise TypeError(f"{beta3!r} is not a 3D momentum vector") return boost_beta3.dispatch(self, beta3.neg3D) - def boostCM_of(self: SameVectorType, booster: VectorProtocol) -> SameVectorType: + def boostCM_of( + self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + ) -> SameVectorType: from vector._compute.lorentz import boost_beta3, boost_p4 - if isinstance(booster, Vector3D): + if isinstance(booster, SpatialMomentum): return boost_beta3.dispatch(self, booster.neg3D) - elif isinstance(booster, Vector4D): + elif isinstance(booster, LorentzMomentum): return boost_p4.dispatch(self, booster.neg3D) else: raise TypeError( @@ -3937,17 +3969,17 @@ def unit(self: SameVectorType) -> SameVectorType: return unit.dispatch(self) def dot(self, other: VectorProtocol) -> ScalarCollection: - _maybe_dimension_error(self, other, self.dot.__name__) + _maybe_same_dimension_error(self, other, self.dot.__name__) module = _compute_module_of(self, other) return module.dot.dispatch(self, other) def add(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.add.__name__) + _maybe_same_dimension_error(self, other, self.add.__name__) module = _compute_module_of(self, other) return module.add.dispatch(self, other) def subtract(self, other: VectorProtocol) -> VectorProtocol: - _maybe_dimension_error(self, other, self.subtract.__name__) + _maybe_same_dimension_error(self, other, self.subtract.__name__) module = _compute_module_of(self, other) return module.subtract.dispatch(self, other) @@ -3992,13 +4024,13 @@ def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: def equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import equal - _maybe_dimension_error(self, other, self.equal.__name__) + _maybe_same_dimension_error(self, other, self.equal.__name__) return equal.dispatch(self, other) def not_equal(self, other: VectorProtocol) -> BoolCollection: from vector._compute.lorentz import not_equal - _maybe_dimension_error(self, other, self.not_equal.__name__) + _maybe_same_dimension_error(self, other, self.not_equal.__name__) return not_equal.dispatch(self, other) def isclose( @@ -4010,7 +4042,7 @@ def isclose( ) -> BoolCollection: from vector._compute.lorentz import isclose - _maybe_dimension_error(self, other, self.isclose.__name__) + _maybe_same_dimension_error(self, other, self.isclose.__name__) return isclose.dispatch(rtol, atol, equal_nan, self, other) @@ -4180,7 +4212,7 @@ def dim(v: VectorProtocol) -> int: raise TypeError(f"{v!r} is not a vector.Vector") -def _maybe_dimension_error( +def _maybe_same_dimension_error( v1: VectorProtocol, v2: VectorProtocol, operation: str ) -> None: """Raises an error if the vectors are not of the same dimension.""" diff --git a/tests/compute/lorentz/test_boost_beta3.py b/tests/compute/lorentz/test_boost_beta3.py index 574c8093..a3be58a8 100644 --- a/tests/compute/lorentz/test_boost_beta3.py +++ b/tests/compute/lorentz/test_boost_beta3.py @@ -17,7 +17,7 @@ def test(): longitudinal=vector.backends.object.LongitudinalObjectZ(3), temporal=vector.backends.object.TemporalObjectT(4), ) - beta = vector.backends.object.VectorObject3D( + beta = vector.backends.object.MomentumObject3D( azimuthal=vector.backends.object.AzimuthalObjectXY(5 / 15, 6 / 15), longitudinal=vector.backends.object.LongitudinalObjectZ(7 / 15), ) diff --git a/tests/compute/lorentz/test_boost_p4.py b/tests/compute/lorentz/test_boost_p4.py index 2d0358e7..16087e42 100644 --- a/tests/compute/lorentz/test_boost_p4.py +++ b/tests/compute/lorentz/test_boost_p4.py @@ -17,7 +17,7 @@ def test(): longitudinal=vector.backends.object.LongitudinalObjectZ(3), temporal=vector.backends.object.TemporalObjectT(4), ) - p4 = vector.backends.object.VectorObject4D( + p4 = vector.backends.object.MomentumObject4D( azimuthal=vector.backends.object.AzimuthalObjectXY(5, 6), longitudinal=vector.backends.object.LongitudinalObjectZ(7), temporal=vector.backends.object.TemporalObjectT(15), diff --git a/tests/compute/spatial/test_cross.py b/tests/compute/spatial/test_cross.py index 70ca82c4..1fe0eed8 100644 --- a/tests/compute/spatial/test_cross.py +++ b/tests/compute/spatial/test_cross.py @@ -79,6 +79,9 @@ def test_lorentz_object(): longitudinal=vector.backends.object.LongitudinalObjectZ(0.6), temporal=vector.backends.object.TemporalObjectT(99), ) + with pytest.raises(TypeError): + out = v1.cross(v2) + v1, v2 = v1.to_Vector3D(), v2.to_Vector3D() out = v1.cross(v2) assert isinstance(out, vector.backends.object.VectorObject3D) assert isinstance(out.azimuthal, vector.backends.object.AzimuthalObjectXY) @@ -86,32 +89,20 @@ def test_lorentz_object(): assert (out.x, out.y, out.z) == pytest.approx((-0.03, 0.06, -0.03)) for t1 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): for t2 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): transformed1, transformed2 = ( getattr(v1, "to_" + t1)(), @@ -127,7 +118,7 @@ def test_lorentz_object(): def test_lorentz_numpy(): - v1 = vector.backends.numpy.VectorNumpy4D( + v1 = vector.backends.numpy.VectorNumpy3D( [(0.1, 0.2, 0.3, 99)], dtype=[ ("x", numpy.float64), @@ -145,38 +136,29 @@ def test_lorentz_numpy(): ("t", numpy.float64), ], ) + with pytest.raises(TypeError): + out = v1.cross(v2) + v1, v2 = v1.to_Vector3D(), v2.to_Vector3D() out = v1.cross(v2) assert isinstance(out, vector.backends.numpy.VectorNumpy3D) assert out.dtype.names == ("x", "y", "z") assert out.tolist() == pytest.approx([(-0.03, 0.06, -0.030000000000000013)]) for t1 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): for t2 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): transformed1, transformed2 = ( getattr(v1, "to_" + t1)(), diff --git a/tests/compute/spatial/test_rotate_axis.py b/tests/compute/spatial/test_rotate_axis.py index 8c6f3c77..c50cd51d 100644 --- a/tests/compute/spatial/test_rotate_axis.py +++ b/tests/compute/spatial/test_rotate_axis.py @@ -87,7 +87,9 @@ def test_lorentz_object(): longitudinal=vector.backends.object.LongitudinalObjectZ(0.6), temporal=vector.backends.object.TemporalObjectT(99), ) - out = vec.rotate_axis(axis, 0.25) + with pytest.raises(TypeError): + out = vec.rotate_axis(axis, 0.25) + out = vec.rotate_axis(axis.to_Vector3D(), 0.25) assert isinstance(out, vector.backends.object.VectorObject4D) assert isinstance(out.azimuthal, vector.backends.object.AzimuthalObjectXY) assert isinstance(out.longitudinal, vector.backends.object.LongitudinalObjectZ) @@ -97,18 +99,12 @@ def test_lorentz_object(): assert out.z == pytest.approx(0.5828282027463345) for t1 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): for t2 in ( "xyzt", @@ -159,7 +155,9 @@ def test_lorentz_numpy(): ("t", numpy.float64), ], ) - out = vec.rotate_axis(axis, 0.25) + with pytest.raises(TypeError): + out = vec.rotate_axis(axis, 0.25) + out = vec.rotate_axis(axis.to_Vector3D(), 0.25) assert isinstance(out, vector.backends.numpy.VectorNumpy4D) assert out.dtype.names == ("x", "y", "z", "t") assert out[0].x == pytest.approx(0.37483425404335763) @@ -167,18 +165,12 @@ def test_lorentz_numpy(): assert out[0].z == pytest.approx(0.5828282027463345) for t1 in ( - "xyzt", - "xythetat", - "xyetat", - "rhophizt", - "rhophithetat", - "rhophietat", - "xyztau", - "xythetatau", - "xyetatau", - "rhophiztau", - "rhophithetatau", - "rhophietatau", + "xyz", + "xytheta", + "xyeta", + "rhophiz", + "rhophitheta", + "rhophieta", ): for t2 in ( "xyzt", From a5c33e76a89084c578466c88411468f71edf7ef8 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Tue, 5 Mar 2024 15:21:25 +0100 Subject: [PATCH 10/11] fix numba tests --- src/vector/_methods.py | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/vector/_methods.py b/src/vector/_methods.py index 28ef7412..8c8d3829 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -1091,7 +1091,7 @@ def neg4D(self: SameVectorType) -> SameVectorType: """Same as multiplying by -1.""" raise AssertionError - def boost_p4(self: SameVectorType, p4: MomentumProtocolLorentz) -> SameVectorType: + def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: """ Boosts the vector or array of vectors in a direction and magnitude given by the 4D vector or array of vectors ``p4``. @@ -1118,7 +1118,7 @@ def boost_p4(self: SameVectorType, p4: MomentumProtocolLorentz) -> SameVectorTyp raise AssertionError def boost_beta3( - self: SameVectorType, beta3: MomentumProtocolSpatial + self: SameVectorType, beta3: VectorProtocolSpatial ) -> SameVectorType: """ Boosts the vector or array of vectors in a direction and magnitude given @@ -1137,7 +1137,7 @@ def boost_beta3( raise AssertionError def boost( - self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz ) -> SameVectorType: """ Boosts the vector or array of vectors using the 3D or 4D ``booster``. @@ -1161,7 +1161,7 @@ def boost( raise AssertionError def boostCM_of_p4( - self: SameVectorType, p4: MomentumProtocolLorentz + self: SameVectorType, p4: VectorProtocolLorentz ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of @@ -1179,7 +1179,7 @@ def boostCM_of_p4( raise AssertionError def boostCM_of_beta3( - self: SameVectorType, beta3: MomentumProtocolSpatial + self: SameVectorType, beta3: VectorProtocolSpatial ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of @@ -1191,7 +1191,7 @@ def boostCM_of_beta3( raise AssertionError def boostCM_of( - self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz ) -> SameVectorType: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of @@ -3832,30 +3832,30 @@ def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: raise TypeError(f"{other!r} is not a 4D vector") return deltaRapidityPhi2.dispatch(self, other) - def boost_p4(self: SameVectorType, p4: MomentumProtocolLorentz) -> SameVectorType: + def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: from vector._compute.lorentz import boost_p4 - if dim(p4) != 4 or not isinstance(p4, LorentzMomentum): - raise TypeError(f"{p4!r} is not a 4D momentum vector") + if dim(p4) != 4: + raise TypeError(f"{p4!r} is not a 4D vector") return boost_p4.dispatch(self, p4) def boost_beta3( - self: SameVectorType, beta3: MomentumProtocolSpatial + self: SameVectorType, beta3: VectorProtocolSpatial ) -> SameVectorType: from vector._compute.lorentz import boost_beta3 - if dim(beta3) != 3 or not isinstance(beta3, SpatialMomentum): - raise TypeError(f"{beta3!r} is not a 3D momentum vector") + if dim(beta3) != 3: + raise TypeError(f"{beta3!r} is not a 3D vector") return boost_beta3.dispatch(self, beta3) def boost( - self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz ) -> SameVectorType: from vector._compute.lorentz import boost_beta3, boost_p4 - if isinstance(booster, SpatialMomentum): + if isinstance(booster, Vector3D): return boost_beta3.dispatch(self, booster) - elif isinstance(booster, LorentzMomentum): + elif isinstance(booster, Vector4D): return boost_p4.dispatch(self, booster) else: raise TypeError( @@ -3864,31 +3864,31 @@ def boost( ) def boostCM_of_p4( - self: SameVectorType, p4: MomentumProtocolLorentz + self: SameVectorType, p4: VectorProtocolLorentz ) -> SameVectorType: from vector._compute.lorentz import boost_p4 - if dim(p4) != 4 or not isinstance(p4, LorentzMomentum): + if dim(p4) != 4: raise TypeError(f"{p4!r} is not a 4D momentum vector") return boost_p4.dispatch(self, p4.neg3D) def boostCM_of_beta3( - self: SameVectorType, beta3: MomentumProtocolSpatial + self: SameVectorType, beta3: VectorProtocolSpatial ) -> SameVectorType: from vector._compute.lorentz import boost_beta3 - if dim(beta3) != 3 or not isinstance(beta3, SpatialMomentum): + if dim(beta3) != 3: raise TypeError(f"{beta3!r} is not a 3D momentum vector") return boost_beta3.dispatch(self, beta3.neg3D) def boostCM_of( - self: SameVectorType, booster: MomentumProtocolSpatial | MomentumProtocolLorentz + self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz ) -> SameVectorType: from vector._compute.lorentz import boost_beta3, boost_p4 - if isinstance(booster, SpatialMomentum): + if isinstance(booster, Vector3D): return boost_beta3.dispatch(self, booster.neg3D) - elif isinstance(booster, LorentzMomentum): + elif isinstance(booster, Vector4D): return boost_p4.dispatch(self, booster.neg3D) else: raise TypeError( From ddad59418635ed4dbe00a587887af2bb102f8d33 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Tue, 5 Mar 2024 15:33:16 +0100 Subject: [PATCH 11/11] Fix notebook tests --- README.md | 6 +- docs/usage/intro.ipynb | 424 ++++++++++++----------------------------- 2 files changed, 122 insertions(+), 308 deletions(-) diff --git a/README.md b/README.md index 6a81ab48..7cdb0769 100644 --- a/README.md +++ b/README.md @@ -545,12 +545,12 @@ v1 - v2.to_Vector3D(z=3) # transforms v2 to 3D (imputes z=3) v1.to_Vector2D() - v2 # transforms v1 to 2D (removes z) ``` -And finally, in some cases, the function excludes a higher-dimensional component, even if the input vectors had them. +Similarly, for a few vector methods, the dimension of the input vectors are type checked strictly. -It would be confusing if the 3D cross-product returned a fourth component. +For instance, a cross-product is only defined for 3D and 7D vectors; hence, running the method on a 4D vector will error out. ```python -vector.obj(x=0.1, y=0.2, z=0.3, t=10).cross(vector.obj(x=0.4, y=0.5, z=0.6, t=20)) +vector.obj(x=0.1, y=0.2, z=0.3).cross(vector.obj(x=0.4, y=0.5, z=0.6)) ``` The (current) list of properties and methods is: diff --git a/docs/usage/intro.ipynb b/docs/usage/intro.ipynb index 3270eaa9..f289a94f 100644 --- a/docs/usage/intro.ipynb +++ b/docs/usage/intro.ipynb @@ -956,20 +956,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[{x: 1, y: 1.1, z: 0.1}, {x: 2, y: 2.2, z: 0.2}],\n",
-       " [],\n",
-       " [{x: 3, y: 3.3, z: 0.3}],\n",
-       " [{x: 4, y: 4.4, z: 0.4}, {x: 5, y: 5.5, ...}, {x: 6, y: 6.6, z: 0.6}]]\n",
-       "-----------------------------------------------------------------------\n",
-       "type: 4 * var * Vector3D[\n",
-       "    x: int64,\n",
-       "    y: float64,\n",
-       "    z: float64\n",
-       "]
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 31, @@ -1018,20 +1006,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[{x: 1, y: 1.1, z: 0.1}, {x: 2, y: 2.2, z: 0.2}],\n",
-       " [],\n",
-       " [{x: 3, y: 3.3, z: 0.3}],\n",
-       " [{x: 4, y: 4.4, z: 0.4}, {x: 5, y: 5.5, ...}, {x: 6, y: 6.6, z: 0.6}]]\n",
-       "-----------------------------------------------------------------------\n",
-       "type: 4 * var * Vector3D[\n",
-       "    x: int64,\n",
-       "    y: float64,\n",
-       "    z: float64\n",
-       "]
" - ], "text/plain": [ - "" + "" ] }, "execution_count": 33, @@ -1415,14 +1391,6 @@ "outputs": [ { "data": { - "text/html": [ - "
[[1.5, 1.5],\n",
-       " [],\n",
-       " [1.5],\n",
-       " [1.5, 1.5]]\n",
-       "-----------------------\n",
-       "type: 4 * var * float64
" - ], "text/plain": [ "" ] @@ -1452,60 +1420,60 @@ { "data": { "text/plain": [ - "MomentumNumpy3D([[[( 1.14310134, 0.04076119, -2.38674108),\n", - " (-1.59113482, -1.41531688, -0.00415859)],\n", - " [(-0.85778946, 1.19156618, 0.42684957),\n", - " ( 0.87415999, 0.03776744, -0.06974114)],\n", - " [( 1.12112981, 0.91596911, 0.26536476),\n", - " ( 0.60581628, 0.01216962, -0.53123266)],\n", - " [( 1.35383052, 1.17849912, 0.29147758),\n", - " ( 1.69584683, -0.34846407, -1.77237757)],\n", - " [( 0.38728751, 0.60588514, 0.38205531),\n", - " ( 0.56495441, -0.51471862, -1.08648223)]],\n", + "MomentumNumpy3D([[[(-1.28111366, -0.03739087, -0.07545124),\n", + " ( 1.06708043, 0.97346557, -0.19277744)],\n", + " [(-0.23630574, 0.44316921, -1.22301664),\n", + " (-0.21826562, 0.31016588, -0.28959995)],\n", + " [(-1.58731867, -0.16787318, 0.78579993),\n", + " ( 1.32631401, -0.42905606, -1.10015408)],\n", + " [(-1.98659247, 0.38280964, 1.58770278),\n", + " ( 0.74213839, 0.30165301, -0.25113917)],\n", + " [( 0.78490232, 1.26226008, -0.76560468),\n", + " ( 0.25209577, -0.68758547, 1.45163241)]],\n", "\n", - " [[( 0.75605075, -0.31525392, 1.72202298),\n", - " (-1.53589478, 0.43887318, -1.32548718)],\n", - " [( 1.10545645, 0.13606777, 2.38726118),\n", - " ( 1.01183334, -1.21837694, -0.06722514)],\n", - " [( 0.42525065, 1.16954822, -1.74887793),\n", - " (-1.19231098, 0.08543114, -0.76000438)],\n", - " [(-2.13832662, 1.64487571, -0.87539254),\n", - " ( 0.57871964, -1.2624124 , -0.76478936)],\n", - " [( 0.85573079, 2.00232795, -0.41417169),\n", - " (-0.66196943, -2.97189753, 0.18161709)]],\n", + " [[(-0.14200396, -0.14399414, -0.35272254),\n", + " (-0.67984015, 1.30776276, 0.36465356)],\n", + " [(-0.22503716, 0.63175451, -0.01989071),\n", + " ( 0.82195282, 0.13522461, 0.09509848)],\n", + " [( 0.03447106, 0.96871536, 0.21010707),\n", + " (-0.8698646 , -0.77621204, 0.40058609)],\n", + " [( 0.20848069, 1.01548712, -0.85426311),\n", + " ( 0.06095666, 0.71386182, 0.37158603)],\n", + " [( 0.66663264, -0.04903835, -1.11774726),\n", + " (-2.39836887, 1.88709819, 1.37915756)]],\n", "\n", - " [[(-1.59381428, 0.14395391, -0.38304042),\n", - " (-0.64830114, -0.72871718, 0.0791469 )],\n", - " [( 1.24400048, -1.22252657, -0.66663965),\n", - " (-1.29169976, 0.40907738, -1.26536454)],\n", - " [( 0.07929 , 0.97787651, 0.49180193),\n", - " (-0.29955594, -1.17971501, 0.60312468)],\n", - " [( 0.43048906, -1.03071749, 1.15226996),\n", - " ( 1.44488059, -0.43218728, 0.98032298)],\n", - " [( 0.01860346, -1.5267734 , -0.40886292),\n", - " (-1.2987315 , -0.51493367, 0.05935923)]],\n", + " [[( 0.04679556, 1.18193822, -0.68347002),\n", + " ( 1.32968718, -1.22745787, -2.07644921)],\n", + " [(-0.48392287, 1.21293123, -0.89212269),\n", + " ( 0.08891877, 0.47951847, -0.32271716)],\n", + " [(-2.51062534, 0.28547534, -0.02872058),\n", + " ( 1.23980306, -1.18747183, -1.13954732)],\n", + " [( 0.98850636, 0.31716296, -1.75326658),\n", + " ( 0.47257719, -1.95447454, 1.64815549)],\n", + " [(-1.11751157, 0.57985208, 0.68405595),\n", + " ( 0.90640743, 0.3252713 , 0.45997663)]],\n", "\n", - " [[(-0.1351796 , 1.15099635, -0.79196155),\n", - " (-0.41065448, 1.56503126, -1.21529644)],\n", - " [( 0.98858534, 0.57254881, 1.34039538),\n", - " (-0.12529945, 0.38560386, -0.81094122)],\n", - " [( 0.70603463, 0.91762652, -0.51801275),\n", - " ( 0.91189934, -1.40406059, 0.71311764)],\n", - " [(-2.05783447, -0.652841 , 0.33237834),\n", - " (-0.46177674, -0.37394158, 0.84820453)],\n", - " [(-0.00412412, 0.44646467, 1.26564905),\n", - " ( 0.03241197, -0.13041014, -0.24966663)]],\n", + " [[( 1.23167693, -0.0138671 , -0.28351331),\n", + " (-0.55242017, -0.76347505, 2.65230372)],\n", + " [(-1.55964887, -1.83923968, 0.13636228),\n", + " ( 2.98497113, -0.83197579, -0.69486487)],\n", + " [( 1.91190798, -1.51432909, 0.28146617),\n", + " ( 1.03501284, -1.16765322, -0.24032661)],\n", + " [( 0.42566688, -0.49780587, -0.92254891),\n", + " ( 1.3981141 , -0.08558606, -0.99102221)],\n", + " [( 1.3275643 , 0.89537104, 0.61550022),\n", + " ( 0.50082994, -0.85531455, -0.81540409)]],\n", "\n", - " [[( 1.25108608, -0.24668532, -0.56496872),\n", - " ( 1.55870783, -0.00336201, 1.1202958 )],\n", - " [( 0.31118974, 0.28744953, -1.11356153),\n", - " ( 1.42489052, -0.33189196, 0.58697126)],\n", - " [(-0.61623195, -0.73835331, -0.40281076),\n", - " ( 0.2628457 , -0.97571113, 0.83446954)],\n", - " [( 0.51875244, 0.02255606, 1.47724329),\n", - " ( 1.15313722, -0.63396881, -0.15501412)],\n", - " [(-1.17243173, -0.60935566, -0.28609093),\n", - " ( 0.07677401, -0.80639786, -0.50941015)]]],\n", + " [[(-0.831434 , -0.38982444, -1.37106712),\n", + " ( 1.37606582, -1.27148566, -0.63527537)],\n", + " [( 1.26147372, -0.11481016, -0.771715 ),\n", + " ( 3.17139268, 0.12957072, -0.9483 )],\n", + " [( 1.78684372, -0.50542474, -0.85576546),\n", + " (-1.63062017, 1.75286287, -1.89527705)],\n", + " [(-0.94314179, 0.39386664, 0.40824193),\n", + " ( 1.08814245, -1.53473737, 0.83560381)],\n", + " [(-0.09420044, -0.96442976, 0.63416259),\n", + " ( 2.41228061, -0.92962671, 0.59070564)]]],\n", " dtype=[('x', '[[{x: -0.738, y: 0.842, z: 0.387}],\n", - " [{x: 0.25, y: 1.04, z: -0.654}, {x: 0.21, y: -1.41, z: 1.04}],\n", - " [{x: -0.704, y: 1.81, z: 0.597}],\n", - " [],\n", - " [{x: 0.512, y: -1.23, z: -1.2}],\n", - " [{x: -1.56, y: 0.219, z: 1.47}, {x: -0.501, y: -0.425, z: 1.96}],\n", - " [{x: -1.19, y: -1.09, z: 0.551}],\n", - " [{x: -0.636, y: -0.0598, z: -0.948}],\n", - " [{x: 1.69, y: -0.308, z: -0.519}, {x: 0.442, y: -0.375, z: -0.824}],\n", - " [{x: 1.97, y: -0.267, z: 0.727}],\n", - " ...,\n", - " [{x: 0.115, y: 0.511, z: 0.704}],\n", - " [{x: -0.363, y: -0.417, z: -0.36}],\n", - " [{x: 0.0166, y: 0.626, z: -1.22}],\n", - " [{x: 0.154, y: 1.1, z: 0.339}],\n", - " [{x: -1.19, y: 0.712, z: -2.57}],\n", - " [{x: -0.156, y: 2.11, z: -2.66}, ..., {x: -0.373, y: -0.611, z: -0.476}],\n", - " [],\n", - " [{x: -1.39, y: 0.788, z: 1.42}, {x: 1.07, y: -1.52, z: 1.1}],\n", - " []]\n", - "--------------------------------------------------------------------------\n", - "type: 50 * var * Momentum3D[\n", - " x: float64,\n", - " y: float64,\n", - " z: float64\n", - "]
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 53, @@ -1685,32 +1625,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[1.12],\n",
-       " [1.07, 1.43],\n",
-       " [1.94],\n",
-       " [],\n",
-       " [1.33],\n",
-       " [1.58, 0.657],\n",
-       " [1.61],\n",
-       " [0.639],\n",
-       " [1.72, 0.579],\n",
-       " [1.98],\n",
-       " ...,\n",
-       " [0.524],\n",
-       " [0.553],\n",
-       " [0.626],\n",
-       " [1.11],\n",
-       " [1.38],\n",
-       " [2.12, 0.381, 0.716],\n",
-       " [],\n",
-       " [1.6, 1.86],\n",
-       " []]\n",
-       "------------------------\n",
-       "type: 50 * var * float64
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 54, @@ -1731,32 +1647,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[1,\n",
-       " 2,\n",
-       " 1,\n",
-       " 0,\n",
-       " 1,\n",
-       " 2,\n",
-       " 1,\n",
-       " 1,\n",
-       " 2,\n",
-       " 1,\n",
-       " ...,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 3,\n",
-       " 0,\n",
-       " 2,\n",
-       " 0]\n",
-       "----------------\n",
-       "type: 50 * int64
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 55, @@ -1777,32 +1669,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[1,\n",
-       " 2,\n",
-       " 1,\n",
-       " 0,\n",
-       " 1,\n",
-       " 2,\n",
-       " 1,\n",
-       " 1,\n",
-       " 2,\n",
-       " 1,\n",
-       " ...,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 1,\n",
-       " 3,\n",
-       " 0,\n",
-       " 2,\n",
-       " 0]\n",
-       "----------------\n",
-       "type: 50 * int64
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 56, @@ -2346,19 +2214,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[{x: 11, y: 6.1}, {x: 12, y: 7.2}],\n",
-       " [],\n",
-       " [{x: 13, y: 8.3}],\n",
-       " [{x: 14, y: 9.4}, {x: 15, y: 10.5}]]\n",
-       "-------------------------------------\n",
-       "type: 4 * var * Vector2D[\n",
-       "    x: int64,\n",
-       "    y: float64\n",
-       "]
" - ], "text/plain": [ - "" + "" ] }, "execution_count": 78, @@ -2388,19 +2245,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[{x: 5, y: 1.2}, {x: 6, y: 2.3}],\n",
-       " [],\n",
-       " [{x: 5, y: 3.4}],\n",
-       " [{x: 5, y: 4.5}, {x: 6, y: 5.6}]]\n",
-       "----------------------------------\n",
-       "type: 4 * var * Vector2D[\n",
-       "    x: float64,\n",
-       "    y: float64\n",
-       "]
" - ], "text/plain": [ - "" + "" ] }, "execution_count": 79, @@ -2633,31 +2479,28 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "(VectorObject3D(x=0, y=0, z=3.0),\n", - " VectorObject2D(x=0, y=0),\n", - " VectorObject3D(x=0, y=0, z=3),\n", - " VectorObject2D(x=0, y=0),\n", - " VectorObject3D(x=0, y=0, z=0),\n", - " VectorObject2D(x=0, y=0))" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "VectorObject3D(x=0, y=0, z=3.0)\n", + "VectorObject2D(x=0, y=0)\n", + "VectorObject3D(x=0, y=0, z=3)\n", + "VectorObject2D(x=0, y=0)\n", + "VectorObject3D(x=0, y=0, z=0)\n", + "VectorObject2D(x=0, y=0)\n" + ] } ], "source": [ "v1 = vector.obj(x=1, y=2, z=3)\n", "v2 = vector.obj(x=1, y=2)\n", "\n", - "v1 - v2.like(v1) # transforms v2 to v1's coordinate system (imputes z=0)\n", - "v1.like(v2) - v2 # transforms v1 to v2's coordinate system (removes z)\n", - "v1 - v2.to_xyz() # transforms v2 to xyz coordinates (imputes z=0)\n", - "v1.to_xy() - v2 # transforms v1 to xy coordinates (removes z)\n", - "v1 - v2.to_Vector3D(z=3) # transforms v2 to 3D (imputes z=3)\n", - "v1.to_Vector2D() - v2 # transforms v1 to 2D (removes z)" + "print(v1 - v2.like(v1)) # transforms v2 to v1's coordinate system (imputes z=0)\n", + "print(v1.like(v2) - v2) # transforms v1 to v2's coordinate system (removes z)\n", + "print(v1 - v2.to_xyz()) # transforms v2 to xyz coordinates (imputes z=0)\n", + "print(v1.to_xy() - v2) # transforms v1 to xy coordinates (removes z)\n", + "print(v1 - v2.to_Vector3D(z=3)) # transforms v2 to 3D (imputes z=3)\n", + "print(v1.to_Vector2D() - v2) # transforms v1 to 2D (removes z)" ] }, { @@ -2665,9 +2508,9 @@ "id": "willing-detail", "metadata": {}, "source": [ - "And finally, in some cases, the function excludes a higher-dimensional component, even if the input vectors had them.\n", + "Similarly, for a few vector methods, the dimension of the input vectors are type checked strictly.\n", "\n", - "It would be confusing if the 3D cross-product returned a fourth component." + "For instance, a cross-product is only defined for 3D and 7D vectors; hence, running the method on a 4D vector will error out." ] }, { @@ -2688,7 +2531,7 @@ } ], "source": [ - "vector.obj(x=0.1, y=0.2, z=0.3, t=10).cross(vector.obj(x=0.4, y=0.5, z=0.6, t=20))" + "vector.obj(x=0.1, y=0.2, z=0.3).cross(vector.obj(x=0.4, y=0.5, z=0.6))" ] }, { @@ -2843,37 +2686,8 @@ "outputs": [ { "data": { - "text/html": [ - "
[[{x: 1.7, y: 0.249, z: -0.301, t: 9.68}, ..., {x: -0.395, y: 0.503, ...}],\n",
-       " [{x: 0.93, y: 0.156, z: -1.84, t: 9.23}, {x: 0.937, y: 0.018, ...}],\n",
-       " [{x: 2.6, y: 0.0762, z: -1.75, t: 9.02}, ..., {x: -1.03, y: 0.604, ...}],\n",
-       " [{x: -0.409, y: -0.199, z: 1.25, t: 11.3}],\n",
-       " [{x: 1.12, y: -0.537, z: -0.617, t: 9.6}],\n",
-       " [{x: -0.703, y: -1.95, z: 0.877, t: 10}, {x: -0.0276, y: 0.224, ...}],\n",
-       " [{x: 0.603, y: 0.105, z: 0.264, t: 11.5}],\n",
-       " [{x: 0.245, y: -0.547, z: -0.578, t: 10.4}],\n",
-       " [{x: -0.216, y: 1.01, z: 0.517, t: 10.8}, ..., {x: 0.0722, y: 0.25, ...}],\n",
-       " [{x: 0.472, y: -1.33, z: 2.03, t: 10.7}],\n",
-       " ...,\n",
-       " [],\n",
-       " [{x: 0.755, y: 0.6, z: -0.514, t: 11}],\n",
-       " [{x: 0.285, y: 0.578, z: -1.98, t: 11}, ..., {x: -0.265, y: 0.287, ...}],\n",
-       " [{x: -0.264, y: -0.604, z: 0.543, t: 10.4}],\n",
-       " [{x: 1.1, y: 0.508, z: -1.28, t: 10.2}, ..., {x: 0.543, y: 1.68, z: ..., ...}],\n",
-       " [{x: 0.524, y: 0.936, z: -0.827, t: 9.85}],\n",
-       " [{x: 0.0945, y: -0.195, z: -0.00756, t: 10.6}, ..., {x: -0.0538, y: ..., ...}],\n",
-       " [{x: -0.128, y: 0.0627, z: -1.4, t: 10.6}, ..., {x: 1.55, y: -0.909, ...}],\n",
-       " []]\n",
-       "--------------------------------------------------------------------------------\n",
-       "type: 50 * var * Momentum4D[\n",
-       "    x: float64,\n",
-       "    y: float64,\n",
-       "    z: float64,\n",
-       "    t: float64\n",
-       "]
" - ], - "text/plain": [ - "" + "text/plain": [ + "" ] }, "execution_count": 92, @@ -2925,16 +2739,16 @@ { "data": { "text/plain": [ - "array([37.87458105, 19.89350458, 38.74617952, 11.25901267, 9.50308655,\n", - " 20.71338166, 11.53055761, 10.35598971, 31.74903367, 10.4220635 ,\n", - " 10.43149905, 10.31884446, 0. , 0. , 9.29368283,\n", - " 8.84646165, 18.98212112, 25.48676509, 0. , 53.34671524,\n", - " 0. , 10.61023154, 32.11159754, 7.43213454, 40.20275895,\n", - " 8.38033058, 9.98795583, 20.69913567, 9.8042269 , 18.20393596,\n", - " 28.50762131, 20.30326887, 10.79385404, 11.39869969, 9.33530947,\n", - " 10.67734045, 21.5368318 , 20.32839567, 10.82890729, 9.93452047,\n", - " 11.86800978, 0. , 10.9076571 , 30.08678732, 10.33515661,\n", - " 39.84025055, 9.7601356 , 30.493263 , 32.28139112, 0. ])" + "array([17.8909645 , 10.55040759, 20.07523827, 9.84004207, 20.67409871,\n", + " 27.88106879, 0. , 32.26388208, 28.44712907, 8.82669677,\n", + " 9.77241892, 0. , 18.92545164, 19.36782081, 16.79226804,\n", + " 10.62459674, 32.13326598, 9.57807961, 10.77717215, 0. ,\n", + " 21.0389158 , 30.44473778, 0. , 50.41526533, 0. ,\n", + " 9.24508557, 22.26878408, 29.88592903, 0. , 18.96505713,\n", + " 10.28562132, 0. , 21.31843914, 9.0798792 , 21.74269618,\n", + " 10.64529248, 10.45420065, 7.9109517 , 0. , 9.09929944,\n", + " 29.70836013, 48.5004124 , 18.63789529, 9.89926012, 9.19757276,\n", + " 31.6617626 , 0. , 0. , 0. , 9.07660597])" ] }, "execution_count": 94,