+```
+
+In the above,
+
+1. `vector.register_awkward()` loads Vector's `vector.backends.awkward.behavior` dict of functionality into the global `ak.behavior`
+2. the Awkward Array contains records (inside variable-length lists) with field names `"x"` and `"y"`
+3. those records are labeled with type name `"Vector2D"`
+
+and thus the `abs` function computes the magnitude of each record as `sqrt(x**2 + y**2)`, through the variable-length lists.
+
+It is not necessary to install Vector's behaviors globally. They could be installed in the `vec` array only by passing `behavior=vector.backends.awkward.behavior` to the [ak.Array](https://awkward-array.org/doc/main/reference/generated/ak.Array.html) constructor.
+
+The records can contain more fields than those that specify coordinates, which can be useful for specifying properties of a particle other than its momentum. Only the coordinate names are considered when performing vector calculations. Coordinates must be numbers (not, for instance, lists of numbers). Be careful about field names that coincide with coordinates, such as `rho` (azimuthal magnitude) and `tau` (proper time).
+
+The `vector.Array` function (`vector.awk` is a synonym) is an alternative to the [ak.Array](https://awkward-array.org/doc/main/reference/generated/ak.Array.html) constructor, which installs Vector's behavior in the new array (not globally in `ak.behavior`).
+
+The `vector.zip` function is an alternative to the [ak.zip](https://awkward-array.org/doc/main/reference/generated/ak.zip.html) function, which installs Vector's behavior in the new array (not globally in `ak.behavior`).
+
+Awkward Arrays can be used in [Numba-compiled functions](https://numba.pydata.org/), including those that contain vectors.
+
+```{eval-rst}
+.. autofunction:: vector.register_awkward
+```
+
+```{eval-rst}
+.. autofunction:: vector.Array
+```
+
+```{eval-rst}
+.. autofunction:: vector.zip
+```
diff --git a/docs/src/make_numpy.md b/docs/src/make_numpy.md
new file mode 100644
index 00000000..57cd325d
--- /dev/null
+++ b/docs/src/make_numpy.md
@@ -0,0 +1,47 @@
+# Making NumPy arrays of vectors
+
+A NumPy array of vectors is a subclass of [np.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) with vector properties and methods. The [dtype](https://numpy.org/doc/stable/reference/arrays.dtypes.html) of this array is [structured](https://numpy.org/doc/stable/user/basics.rec.html) to specify the coordinate names; an array with fields `x` and `y` (Cartesian) performs computations differently from an array with fields `rho` and `phi` (polar).
+
+To create a NumPy array of vectors,
+
+1. use the `vector.array` function (`vector.arr` is a synonym)
+2. use the `vector.VectorNumpy` class constructor
+3. or cast a structured NumPy array as the appropriate class, which can avoid copying data.
+
+## General constructor
+
+```{eval-rst}
+.. autofunction:: vector.array
+```
+
+```{eval-rst}
+.. autoclass:: vector.VectorNumpy
+```
+
+## Casting structured arrays
+
+[NumPy structured arrays](https://numpy.org/doc/stable/user/basics.rec.html) with appropriately named fields (see above) can be _cast_ as arrays of vectors using [np.ndarray.view](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.view.html). Use the NumPy array subclass with the appropriate dimension below.
+
+```{eval-rst}
+.. autoclass:: vector.VectorNumpy2D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumNumpy2D
+```
+
+```{eval-rst}
+.. autoclass:: vector.VectorNumpy3D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumNumpy3D
+```
+
+```{eval-rst}
+.. autoclass:: vector.VectorNumpy4D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumNumpy4D
+```
diff --git a/docs/src/make_object.md b/docs/src/make_object.md
new file mode 100644
index 00000000..ab6c7bd0
--- /dev/null
+++ b/docs/src/make_object.md
@@ -0,0 +1,47 @@
+# Making vector objects
+
+A vector object represents a single vector, rather than an array of vectors. Lists of vector objects are slower to compute and have more memory overhead than arrays of vectors, _unless_ those computations are performed in [Numba-compiled functions](https://numba.pydata.org/).
+
+To create a vector object, use the `vector.obj` function with appropriate arguments for 2D/3D/4D and geometric versus momentum.
+
+## General constructor
+
+```{eval-rst}
+.. autofunction:: vector.obj
+```
+
+## 2D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorObject2D
+ :members: from_rhophi,from_xy
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumObject2D
+ :members: from_rhophi,from_xy
+```
+
+## 3D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorObject3D
+ :members: from_rhophieta,from_rhophitheta,from_rhophiz,from_xyeta,from_xytheta,from_xyz
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumObject3D
+ :members: from_rhophieta,from_rhophitheta,from_rhophiz,from_xyeta,from_xytheta,from_xyz
+```
+
+## 4D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorObject4D
+ :members: from_rhophietat,from_rhophietatau,from_rhophithetat,from_rhophithetatau,from_rhophizt,from_rhophiztau,from_xyetat,from_xyetatau,from_xythetat,from_xythetatau,from_xyzt,from_xyztau
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumObject4D
+ :members: from_rhophietat,from_rhophietatau,from_rhophithetat,from_rhophithetatau,from_rhophizt,from_rhophiztau,from_xyetat,from_xyetatau,from_xythetat,from_xythetatau,from_xyzt,from_xyztau
+```
diff --git a/docs/src/make_sympy.md b/docs/src/make_sympy.md
new file mode 100644
index 00000000..47ca03f4
--- /dev/null
+++ b/docs/src/make_sympy.md
@@ -0,0 +1,57 @@
+# Making SymPy vector expressions
+
+SymPy expressions are not numerical, they're purely algebraic. However, the same Vector computations can be performed on them.
+
+To construct a symbolic vector, first create symbols for its components and ensure that they are real-valued (not complex),
+
+```python
+>>> import sympy
+>>> x, y, z, t, px, py, pz, eta, tau = sympy.symbols(
+... "x y z t px py pz eta tau", real=True
+... )
+```
+
+then use one of Vector's SymPy constructors (geometric or momentum),
+
+```python
+>>> vector.VectorSympy2D(x=x, y=y)
+VectorSympy2D(x=x, y=y)
+>>>
+>>> vector.MomentumSympy3D(px=px, py=py, pz=pz)
+MomentumSympy3D(px=px, py=py, pz=pz)
+>>>
+>>> vector.VectorSympy4D(x=x, y=y, eta=eta, tau=tau)
+vector.VectorSympy4D(x=x, y=y, eta=eta, tau=tau)
+```
+
+which are documented below.
+
+## 2D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorSympy2D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumSympy2D
+```
+
+## 3D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorSympy3D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumSympy3D
+```
+
+## 4D constructors
+
+```{eval-rst}
+.. autoclass:: vector.VectorSympy4D
+```
+
+```{eval-rst}
+.. autoclass:: vector.MomentumSympy4D
+```
diff --git a/docs/src/momentum2d.md b/docs/src/momentum2d.md
new file mode 100644
index 00000000..a755037f
--- /dev/null
+++ b/docs/src/momentum2d.md
@@ -0,0 +1,12 @@
+# Interface for 2D momentum
+
+2D momentum vectors of all backends have the following attributes, properties, and methods.
+
+This includes momentum synonyms. For purely geometric vectors, see [Interface for 2D vectors](vector2d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.MomentumProtocolPlanar
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/src/momentum3d.md b/docs/src/momentum3d.md
new file mode 100644
index 00000000..9140f542
--- /dev/null
+++ b/docs/src/momentum3d.md
@@ -0,0 +1,12 @@
+# Interface for 3D momentum
+
+3D momentum vectors of all backends have the following attributes, properties, and methods.
+
+This includes momentum synonyms. For purely geometric vectors, see [Interface for 3D vectors](vector3d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.MomentumProtocolSpatial
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/src/momentum4d.md b/docs/src/momentum4d.md
new file mode 100644
index 00000000..9f7abf91
--- /dev/null
+++ b/docs/src/momentum4d.md
@@ -0,0 +1,12 @@
+# Interface for 4D momentum
+
+4D momentum vectors of all backends have the following attributes, properties, and methods.
+
+This includes momentum synonyms. For purely geometric vectors, see [Interface for 4D vectors](vector4d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.MomentumProtocolLorentz
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/src/numba.ipynb b/docs/src/numba.ipynb
new file mode 100644
index 00000000..444a9926
--- /dev/null
+++ b/docs/src/numba.ipynb
@@ -0,0 +1,221 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "1af51709-6860-4e5c-96c9-6a437eaed606",
+ "metadata": {},
+ "source": [
+ "# Compiling functions on vectors with Numba"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "03064225-ea6b-4f6b-a5bf-08a47b62350e",
+ "metadata": {},
+ "source": [
+ "First, [install](../index.md#installation) and import Vector and [Numba](https://numba.pydata.org/)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "df8bea35-cf3c-4f87-8e3d-8ffe06264811",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import vector\n",
+ "import numba as nb\n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7fff9620-227b-4e5e-a211-4daf1fb96298",
+ "metadata": {},
+ "source": [
+ "Numba is a just-in-time (JIT) compiler for a mathematically relevant subset of NumPy and Python. It allows you to write fast code without leaving the Python environment. The drawback of Numba is that it can only compile code blocks involving objects and functions that it recognizes.\n",
+ "\n",
+ "The Vector library includes extensions to inform Numba about [vector objects](object.md), ~~[arrays of vectors](numpy.md)~~, and [arrays of Awkward Arrays](awkward.md). At the time of writing, the implementation of vector NumPy arrays is incomplete (see issue [#43](https://github.com/scikit-hep/vector/issues/43)).\n",
+ "\n",
+ "Consider the following function:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "0e7f7c5c-2ce3-4f55-9159-363910fac6b9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "@nb.njit\n",
+ "def compute_mass(v1, v2):\n",
+ " return (v1 + v2).mass"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "16d0fe04-fc8d-4d1f-bb68-0f869c1d2bdb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "8.0"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "compute_mass(vector.obj(px=1, py=2, pz=3, E=4), vector.obj(px=-1, py=-2, pz=-3, E=4))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "69c36f6d-3b54-4db8-9890-9245d64fefe7",
+ "metadata": {},
+ "source": [
+ "When the two `MomentumObject4D` objects are passed as arguments, Numba recognizes them and replaces the Python objects with low-level structs. When it compiles the function, it recognizes `+` as the 4D `add` function and recognizes `.mass` as the `tau` component of the result.\n",
+ "\n",
+ "Although this demonstrates that Numba can manipulate vector objects, there is no performance advantage (and a likely disadvantage) to compiling a calculation on just a few vectors. The advantage comes when many vectors are involved, in arrays."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "63f614a2-969d-465d-8d74-a44f6f77eab4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "[[],\n",
+ " [{x: 1.96, y: -0.654, z: -0.443, t: 8.88}, ..., {x: -0.0976, y: 0.877, ...}],\n",
+ " [{x: -0.543, y: 1.82, z: 0.177, t: 10.1}],\n",
+ " [{x: 0.0705, y: 0.816, z: -0.607, t: 10.1}, ..., {x: -0.756, y: -2.23, ...}],\n",
+ " [{x: -1.61, y: -1.14, z: 0.312, t: 10.2}, ..., {x: -0.878, y: -0.803, ...}],\n",
+ " [{x: -1.4, y: -1.09, z: 1.13, t: 9.03}],\n",
+ " [{x: 0.634, y: -0.0388, z: -0.44, t: 10.5}],\n",
+ " [{x: -0.767, y: 0.0841, z: -0.344, t: 9.34}],\n",
+ " [{x: -1.89, y: 0.295, z: -1.95, t: 10.1}],\n",
+ " [{x: -1.85, y: -0.832, z: -0.816, t: 8.2}],\n",
+ " ...,\n",
+ " [{x: 0.496, y: 0.791, z: 1.67, t: 10.8}],\n",
+ " [{x: -1.09, y: 1.42, z: -0.299, t: 11.4}],\n",
+ " [{x: -0.885, y: -0.537, z: -0.0475, t: 9.95}, {x: -0.615, y: 1.19, ...}],\n",
+ " [{x: -0.503, y: -3.06, z: 0.893, t: 9.61}, ..., {x: 0.263, y: -0.493, ...}],\n",
+ " [{x: 2.16, y: -1.11, z: 0.696, t: 11.2}, {x: 0.824, y: 0.604, ...}],\n",
+ " [],\n",
+ " [{x: 1.55, y: 0.497, z: -0.764, t: 10.3}, {x: 0.311, y: 0.545, ...}],\n",
+ " [],\n",
+ " [{x: 0.0877, y: 0.334, z: -1.5, t: 10.5}, {x: 1.26, y: 1.94, ...}]]\n",
+ "---------------------------------------------------------------------------------------------\n",
+ "backend: cpu\n",
+ "nbytes: 3.0 kB\n",
+ "type: 50 * var * Momentum4D[\n",
+ " x: float64,\n",
+ " y: float64,\n",
+ " z: float64,\n",
+ " t: float64\n",
+ "]
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# This is still not a large number. You want millions.\n",
+ "array = vector.Array(\n",
+ " [\n",
+ " [\n",
+ " dict(\n",
+ " {x: np.random.normal(0, 1) for x in (\"px\", \"py\", \"pz\")},\n",
+ " E=np.random.normal(10, 1),\n",
+ " )\n",
+ " for inner in range(np.random.poisson(1.5))\n",
+ " ]\n",
+ " for outer in range(50)\n",
+ " ]\n",
+ ")\n",
+ "array"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "f6edd6c9-a423-4662-bcae-c685686633c8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "@nb.njit\n",
+ "def compute_masses(array):\n",
+ " out = np.empty(len(array), np.float64)\n",
+ " for i, event in enumerate(array):\n",
+ " total = vector.obj(px=0.0, py=0.0, pz=0.0, E=0.0)\n",
+ " for vec in event:\n",
+ " total = total + vec\n",
+ " out[i] = total.mass\n",
+ " return out"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "fa854373-aeba-4274-8ab8-c1c85d5a931b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([ 0. , 29.59334472, 9.96825092, 29.98088102, 30.022318 ,\n",
+ " 8.77904697, 10.52123699, 9.30633562, 9.69685471, 7.90724598,\n",
+ " 8.22083106, 12.10506017, 9.14678916, 42.27902654, 10.08573923,\n",
+ " 9.98477624, 0. , 22.79438116, 29.12919935, 32.07848403,\n",
+ " 29.6325778 , 0. , 8.11447927, 39.07959905, 30.54027295,\n",
+ " 18.39609413, 21.15982485, 18.62455179, 7.75621961, 19.52526457,\n",
+ " 19.52907948, 20.40038164, 8.84074954, 9.18655937, 30.22076618,\n",
+ " 8.47538375, 10.42253874, 17.84485932, 0. , 41.55064913,\n",
+ " 0. , 10.60246245, 11.24522316, 19.32603825, 31.28879051,\n",
+ " 20.49852241, 0. , 20.21304572, 0. , 20.76651039])"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "compute_masses(array)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/src/numpy.ipynb b/docs/src/numpy.ipynb
new file mode 100644
index 00000000..d830eb60
--- /dev/null
+++ b/docs/src/numpy.ipynb
@@ -0,0 +1,811 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "20258df9-4dbb-4457-945c-c9b6abe58cf9",
+ "metadata": {},
+ "source": [
+ "# NumPy arrays of vectors"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1144533f-0290-43f2-a9f2-adc9d042ed1a",
+ "metadata": {},
+ "source": [
+ "First, [install](../index.md#installation) and import Vector and [NumPy](https://numpy.org/). (Vector requires NumPy, so if you can use Vector, you've already installed NumPy.)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "04ce97c4-d7db-458a-9976-68af8eeb9b58",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import vector\n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c9492633-fa30-458d-ba40-3c1b12a067b6",
+ "metadata": {},
+ "source": [
+ "## Making an array of vectors"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f84dbc67-e195-4ee7-a11f-cd8040c09fa8",
+ "metadata": {},
+ "source": [
+ "If you want to do calculations with large numbers of vectors or performance is important, it's better to make arrays of vectors than lists of [vector objects](object.md).\n",
+ "\n",
+ "The [vector.array](make_numpy.md#general-constructor) function is a general-purpose constructor. It works like [np.array](https://numpy.org/doc/stable/reference/generated/numpy.array.html) and expects the [dtype](https://numpy.org/doc/stable/reference/arrays.dtypes.html) to correspond to a [structured array](https://numpy.org/doc/stable/user/basics.rec.html) in which the field names are recognized coordinate names:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "de83bfb0-37ec-4d1a-a6c4-31de7ee94998",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorNumpy2D([(1.1, 2.2), (3.3, 4.4), (5.5, 6.6)],\n",
+ " dtype=[('x', ' abs(b), a, b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "b1a1236b-81f2-40a4-b5c5-5c46a7cb5e57",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorNumpy3D((496.97860925, -22.8454872, -148.7924227),\n",
+ " dtype=[('x', '\n",
+ "\n",
+ "This one constructor, [vector.obj](make_object.md), can output a variety of data types. If you want to control the type more explicitly, you can use [vector.VectorObject2D](make_object.md#vector.VectorObject2D), [vector.MomentumObject2D](make_object.md#vector.MomentumObject2D), [vector.VectorObject3D](make_object.md#vector.VectorObject3D), [vector.MomentumObject3D](make_object.md#vector.MomentumObject3D), [vector.VectorObject4D](make_object.md#vector.VectorObject4D), and [vector.MomentumObject4D](make_object.md#vector.MomentumObject4D) to construct or check the type explicitly. These classes also have `from_*` methods to construct vectors from positional arguments, rather than keyword arguments."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d9a23b9b-a19f-49a9-b1ae-7b86c51a17f1",
+ "metadata": {},
+ "source": [
+ "## Using a vector"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "959d7c4e-f7a6-4220-877a-dfedc6a873b7",
+ "metadata": {},
+ "source": [
+ "Vector objects have a suite of properties and methods appropriate to their type (2D/3D/4D, geometric or momentum). For example, to compute the cross-product of two vectors, you would use [cross](vector3d.md#vector._methods.VectorProtocolSpatial.cross):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "51d9350f-66e7-447c-840c-ed6bd899bd37",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject3D(x=6, y=0, z=-3)"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a = vector.obj(x=2, y=3, z=4)\n",
+ "b = vector.obj(x=1, y=0, z=2)\n",
+ "\n",
+ "a.cross(b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "98530a7c-5413-4268-9312-91e1e8054c50",
+ "metadata": {},
+ "source": [
+ "or to compute the angle between them, you would use [deltaangle](vector3d.md#vector._methods.VectorProtocolSpatial.deltaangle):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "eee16a4d-b15b-434b-868b-ef7a11d8e101",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0.590872750145419"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.deltaangle(b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ac749138-ed71-4a07-92a8-af33785eb5ea",
+ "metadata": {},
+ "source": [
+ "or to compute their sum, you would use `+`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "5686fc89-5cb0-4a5f-b521-41dd7d0a3b10",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject3D(x=3, y=3, z=6)"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a + b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "eeaf4807-b338-4f17-ba35-a7a3f7f43d97",
+ "metadata": {},
+ "source": [
+ "In this last example, the `+` operator overloads the [add](common.md#vector._methods.VectorProtocol.add) method. Similarly, multiplication between a vector and a scalar number overloads [scale](common.md#vector._methods.VectorProtocol.scale), etc. Since they overload standard operators, vectors can be used in Python built-in functions like [sum](https://docs.python.org/3/library/functions.html#sum), as long as you provide a `start`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "10b5f3e3-db5d-421e-89a4-5929fe720af1",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject2D(x=45, y=4.5)"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vs = [vector.obj(x=x, y=x / 10) for x in range(10)]\n",
+ "\n",
+ "sum(vs, start=vector.obj(x=0, y=0))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "32c06273-06ae-4cfa-8e79-f55586148283",
+ "metadata": {},
+ "source": [
+ "The same applies to [abs](https://docs.python.org/3/library/functions.html#abs) for the vector's magnitude, but note that this depends on the number of dimensions:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "e821c6d7-db8c-47cd-93a0-5eb7bf3e023f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "5.0"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "abs(vector.obj(x=3, y=4)) # sqrt(3**2 + 4**2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "bf89db7e-6326-46e4-8add-fa5e7e7df799",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "3.0"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "abs(vector.obj(x=1, y=2, z=2)) # sqrt(1**2 + 2**2 + 2**2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "9f6d19e6-ca20-4f8b-a8d9-57950c24655b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "3.0"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "abs(vector.obj(x=3, y=3, z=3, t=6)) # sqrt(6**2 - 3**2 - 3**2 - 3**2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2d9407af-0641-403c-822c-d89344dd95db",
+ "metadata": {},
+ "source": [
+ "Equality ([equal](common.md#vector._methods.VectorProtocol.equal)) and inequality ([not_equal](common.md#vector._methods.VectorProtocol.not_equal)) are defined:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "41ca1487-4a33-493f-9d9b-dd452255ae73",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.obj(x=3, y=4) == vector.obj(x=3, y=4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bf85dc4f-88de-4e07-9303-c1f364a0a227",
+ "metadata": {},
+ "source": [
+ "But you'll probably want to use [isclose](common.md#vector._methods.VectorProtocol.isclose) (and possibly specify tolerances):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "7604a176-efd9-4cbd-947c-90c8bbb20685",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.obj(x=3, y=4) == vector.obj(rho=5, phi=0.9272952180016122)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "0a3d1aa1-eeda-486a-84b2-e9d43e102117",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.obj(x=3, y=4).isclose(vector.obj(rho=5, phi=0.9272952180016122))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "70a3c4b3-8a81-4bb2-b6f7-1ebb57889c0a",
+ "metadata": {},
+ "source": [
+ "The full set of properties and methods available to each type of vector (2D/3D/4D, geometric or momentum) is described in\n",
+ "\n",
+ "* [Interface for all vectors](common.md)\n",
+ "* [Interface for 2D vectors](vector2d.md)\n",
+ "* [Interface for 3D vectors](vector3d.md)\n",
+ "* [Interface for 4D vectors](vector4d.md)\n",
+ "* [Interface for 2D momentum](momentum2d.md)\n",
+ "* [Interface for 3D momentum](momentum3d.md)\n",
+ "* [Interface for 4D momentum](momentum4d.md)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6d1f1795-1051-4b32-b9b8-222a2f2228f9",
+ "metadata": {},
+ "source": [
+ "## Using coordinate systems"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0e80cf47-801f-421a-818a-e70db3356a5a",
+ "metadata": {},
+ "source": [
+ "A vector can be constructed using any combination of coordinate systems and computations will be performed using whatever coordinate system it has. Thus, after creating vectors, you can write code that does not depend on the coordinate system—it becomes a hidden implementation detail."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "a96ddaad-7c6b-487f-8d23-fdd2fde159bc",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject2D(x=5.0, y=1.0)"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a = vector.obj(x=2, y=1)\n",
+ "b = vector.obj(rho=3, phi=0)\n",
+ "\n",
+ "a + b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4f4552b3-bd21-4760-90fc-92002a2f14ad",
+ "metadata": {},
+ "source": [
+ "Some of the properties of a vector are coordinates, so you can use Vector to convert coordinates."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "d0ce4192-f634-40f3-900a-4d143b0050d6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(2.23606797749979, 0.4636476090008061)"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.rho, a.phi"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "633a6970-6986-40e3-a3aa-1fde0edc0a0a",
+ "metadata": {},
+ "source": [
+ "Since the way that you access the original coordinates is the same as the way that you access converted coordinates,"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "38006968-210d-4568-a94a-e13d31b048a7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(2, 1)"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.x, a.y"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "31f7e65a-ed4e-48a8-a761-4c70cf81eca4",
+ "metadata": {},
+ "source": [
+ "these conversions are part of the coordinate-abstraction.\n",
+ "\n",
+ "For reasons of numerical precision, you might want to open this black box and explicitly change the coordinate system. These methods start with `to_*`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "83c22d5b-a251-42c2-9527-87695c9d5dac",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject2D(rho=2.23606797749979, phi=0.4636476090008061)"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.to_rhophi()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "01754e13-3c0c-4b1e-be0e-0e0d01585b63",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject2D(x=3.0, y=0.0)"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b.to_xy()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3c4a7d35-74a6-4d90-b195-68fc6a77cbec",
+ "metadata": {},
+ "source": [
+ "## Geometric versus momentum vectors"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "459d089b-8569-4eff-a316-6ff40cc1b145",
+ "metadata": {},
+ "source": [
+ "Vectors come in two flavors:\n",
+ "\n",
+ "* geometric: only one name for each property or method\n",
+ "* momentum: same property or method can be accessed with several synonyms (which assume that the vector is a [momentum](https://en.wikipedia.org/wiki/Momentum) vector)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "e86873c1-f8aa-447d-b265-2a6b42b9e1ba",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorObject3D(x=1, y=2, z=3)"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "v = vector.obj(x=1, y=2, z=3)\n",
+ "v"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "0d4fab89-cf8c-43f9-a7d9-34083ac70eb7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "MomentumObject3D(px=1, py=2, pz=3)"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "p = vector.obj(px=1, py=2, pz=3)\n",
+ "p"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1f19524b-e98a-461e-a098-6d5b803dc693",
+ "metadata": {},
+ "source": [
+ "Calculations are the same in both cases:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "0eaf2b80-9e94-41bb-b251-1b713df0e829",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "3.7416573867739413"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "abs(v)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "f1c35d52-9e8d-44d1-b1e8-a4c0f3405370",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "3.7416573867739413"
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "abs(p)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dec60082-29ca-47b8-b9c4-3d68ff967a06",
+ "metadata": {},
+ "source": [
+ "but there are more ways to express some operations:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "1a3540ed-c4f1-4df0-af75-0a0c75b83c89",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2.23606797749979"
+ ]
+ },
+ "execution_count": 24,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "v.rho"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "061c00d9-2134-41bb-9275-a81eccb4a71c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2.23606797749979"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "p.rho"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "0fb9656b-97d7-49f0-b61e-c99bccf2e31d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2.23606797749979"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "p.pt"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "375ac938-9ef0-493b-b94a-52cab0c1b359",
+ "metadata": {},
+ "source": [
+ "The geometric vector satisfies the [Zen of Python](https://en.wikipedia.org/wiki/Zen_of_Python) stipulation that\n",
+ "\n",
+ "> There should be one-- and preferably only one --obvious way to do it.\n",
+ "\n",
+ "and code that uses, for example, \"`pt`\" to specify \"distance from the beamline\" is obfuscated code. However, the most common use for these vectors in High Energy Physics (HEP) is to represent the momentum of particles. For that purpose, using \"`rho`\" for $p_T$ is not self-documenting.\n",
+ "\n",
+ "Momentum vectors have all of the same properties and methods as geometric vectors _as well as_ momentum synonyms. In some cases, there are multiple momentum synonyms for adherence to different conventions. For example, energy and mass (the [temporal component of momentum](https://en.wikipedia.org/wiki/Four-momentum), as Cartesian and proper time, respectively) have four different spellings:\n",
+ "\n",
+ "| energy spelling | mass spelling | rationale |\n",
+ "|:--:|:--:|:--|\n",
+ "| `t` | `tau` | geometric coordinates; $\\tau$ for proper time is conventional |\n",
+ "| `energy` | `mass` | full names are more self-documenting in the code |\n",
+ "| `e` | `m` | all other coordinates are lower-case single letters (sometimes Greek letters) |\n",
+ "| `E` | `M` | capital E and M (only!) are used in other HEP vector libraries |\n",
+ "\n",
+ "If any momentum components are used to construct a vector (or if [vector.MomentumObject2D](make_object.md#vector.MomentumObject2D), [vector.MomentumObject3D](make_object.md#vector.MomentumObject3D), or [vector.MomentumObject4D](make_object.md#vector.MomentumObject4D) are used explicitly), then the vector is momentum and all synonyms become available."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0560e95f-48e9-454d-9db1-f85386d5e9ed",
+ "metadata": {},
+ "source": [
+ "## Numeric data types and numerical error"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c3ba958e-9c1b-4721-8f40-b1112ea6a068",
+ "metadata": {},
+ "source": [
+ "Vector does not require any specific numeric data type, such as `np.float32` or `np.float64`, it only requires that vector components are some kind of number, including integers."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "15ca1301-574c-43dd-bb83-f85c71a5f8dc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "v = vector.obj(x=1, y=2.2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "c1883cf8-231f-4996-840a-65c4f30eced4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "int"
+ ]
+ },
+ "execution_count": 28,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(v.x)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "18f515ee-1c9d-480f-b4c8-ba3033afcff0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "float"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(v.y)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "b1a2e4d9-8381-4bc2-9332-52fa475d6c4b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "e35f37d0-b6bd-45d0-ad78-7a17629a4e3a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "v = vector.obj(x=np.float32(1.1), y=np.float64(2.2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "6bd30abb-4566-4551-9fb7-c7bc8643d487",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "numpy.float32"
+ ]
+ },
+ "execution_count": 32,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(v.x)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "e4fabf24-2799-4b0a-9e29-c106986c3330",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "numpy.float64"
+ ]
+ },
+ "execution_count": 33,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "type(v.y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "11c3e336-4ced-4704-a1c8-54363687c20f",
+ "metadata": {},
+ "source": [
+ "The same formulas are applied, regardless of the numeric type, so if the numerical error is larger than you expect it to be, check your types (and coordinate systems)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0dab118c-e262-45ec-b121-4c0172603b4a",
+ "metadata": {},
+ "source": [
+ "## Application to other backends"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "75959cc7-a64b-48ac-9b48-1244887d7d9a",
+ "metadata": {},
+ "source": [
+ "Everything stated above about vector objects (except their methods of construction) apply equally to all other backends. Arrays of vectors and symbolic vector expressions in SymPy have the same properties and methods as vector objects, they can hide choice of coordinate system as an abstraction, and the set of synonyms can be minimal for geometric vectors and maximal for momentum vectors. Therefore, it can be convenient to use vector objects as a quick way to debug issues in large arrays. However, note that different backends can use different libraries for computations, and results might differ in numerical error.\n",
+ "\n",
+ "In particular, note that SymPy vector expressions have a different sign convention for operations on space-like and negative time-like 4D vectors. For all other backends, Vector's conventions were chosen to agree with popular HEP libraries, particularly [ROOT](https://root.cern), but for the SymPy backend, those conventions would insert piecewise if-then branches, which would complicate symbolic expressions."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/src/sympy.ipynb b/docs/src/sympy.ipynb
new file mode 100644
index 00000000..df5e10ac
--- /dev/null
+++ b/docs/src/sympy.ipynb
@@ -0,0 +1,440 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "dd79e619-a48d-415b-9d7a-7dd5b3970475",
+ "metadata": {},
+ "source": [
+ "# Vector expressions with SymPy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3f40d8aa-c1d4-4106-859a-04d8452673a0",
+ "metadata": {},
+ "source": [
+ "First, [install](../index.md#installation) and import Vector and [SymPy](https://www.sympy.org/)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "405dce26-762d-438b-8b8c-f693d0333a32",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import vector\n",
+ "import sympy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "00b96b54-33e4-459b-8fa6-bbebf1df0319",
+ "metadata": {},
+ "source": [
+ "## How the SymPy backend differs from the others"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "07e49af1-a2e4-43e9-b265-38d917456ce0",
+ "metadata": {},
+ "source": [
+ "SymPy is a computer algebra system like Mathematica and Maple. It primarily deals with algebraic expressions, rather than concrete numbers. However, all of the coordinate transformations and vector manipulations can be applied symbolically through Vector's SymPy backend.\n",
+ "\n",
+ "When comparing SymPy to the other backends, note that SymPy vector expressions have a different sign convention for operations on space-like and negative time-like 4D vectors. For all other backends, Vector's conventions were chosen to agree with popular HEP libraries, particularly [ROOT](https://root.cern), but for the SymPy backend, those conventions would insert piecewise if-then branches, which would complicate symbolic expressions.\n",
+ "\n",
+ "When vector expressions are evaluated numerically, you can expect agreement in 2D and 3D vector operations, as well as 4D vector operations if all of the vectors have a positive time-like part (which is [necessary for real momentum vectors and causal relationships between events](https://en.wikipedia.org/wiki/Light_cone))."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "afce6222-03bb-40b7-8789-4e98782ebede",
+ "metadata": {},
+ "source": [
+ "## Making a vector expression"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10257bc9-a064-4ede-bcdb-d906a25598e2",
+ "metadata": {},
+ "source": [
+ "Before making a vector expression, we need symbols for each of the components, so use the [sympy.symbols](https://docs.sympy.org/latest/modules/core.html#sympy.core.symbol.symbols) function. Be sure to [tell SymPy to assume](https://docs.sympy.org/latest/guides/assumptions.html) that they are all real-valued, not complex numbers."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "e74eaaea-c607-47c0-a228-9b3530863bf7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x, y, z, t, px, py, pz, eta, tau = sympy.symbols(\"x y z t px py pz eta tau\", real=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8216735e-eb82-4ba9-92c3-12f45a9400a8",
+ "metadata": {},
+ "source": [
+ "Now we can make vectors [just as we did with objects](object.md), though these lack concrete numerical values."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "0beb59b0-7cea-4d06-b437-da0597ba027e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorSympy2D(x=x, y=y)"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.VectorSympy2D(x=x, y=y)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "8dc8eb68-89e3-4794-b533-e9f5d521770b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "MomentumSympy3D(px=px, py=py, pz=pz)"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.MomentumSympy3D(px=px, py=py, pz=pz)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "921724ac-2d20-4a82-8e0b-3cc571d7d909",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorSympy4D(x=x, y=y, eta=eta, tau=tau)"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vector.VectorSympy4D(x=x, y=y, eta=eta, tau=tau)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6ac26f0b-8fb6-410c-865f-6fefaeb2302b",
+ "metadata": {},
+ "source": [
+ "## Using a vector expression"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "59c644ed-32af-42f1-bac7-a27c7ec55035",
+ "metadata": {},
+ "source": [
+ "All of the vector operations performed on these expressions return symbolic results."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "9dd7d004-9635-427c-8394-f0e65906f564",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "v = vector.VectorSympy2D(x=x, y=y)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "3b3af4ee-b0a7-4379-ab8e-ac674037db18",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\sqrt{x^{2} + y^{2}}$"
+ ],
+ "text/plain": [
+ "sqrt(x**2 + y**2)"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "v.rho"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "9430dd6e-ceef-4977-ab1f-5d78ff7d6d83",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\text{True}$"
+ ],
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "sympy.Eq(v.rho, abs(v))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "7c674475-b882-44fc-b01a-f04800eb0205",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "v = vector.VectorSympy4D(x=x, y=y, z=z, t=t)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "c25ea976-b913-4717-9858-3e2c926a99c2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\sqrt{\\left|{- t^{2} + x^{2} + y^{2} + z^{2}}\\right|}$"
+ ],
+ "text/plain": [
+ "sqrt(Abs(-t**2 + x**2 + y**2 + z**2))"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "v.tau"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "3d258221-4cd4-43fb-8710-d9bc96827132",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle t^{2} - x^{2} - y^{2} - z^{2} > 0$"
+ ],
+ "text/plain": [
+ "t**2 - x**2 - y**2 - z**2 > 0"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "v.is_timelike()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "86dcae0d-22ba-4621-82b8-397a94fecfc6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "VectorSympy4D(x=x*(1 + x**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + x/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x*y**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + x*z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), y=y*(1 + y**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + y/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2*y/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y*z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), z=z*(1 + z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + z/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2*z/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y**2*z/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), t=t/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + z**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)))"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "boosted = v.boost(v.to_beta3())\n",
+ "boosted"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "1e5a3bf0-1784-4d29-8b7c-1b8904de8a20",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\frac{t}{\\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{x^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{y^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{z^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}}$"
+ ],
+ "text/plain": [
+ "t/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + z**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "boosted.t"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d7e6de0b-917e-4d87-bade-74bd62db93f2",
+ "metadata": {},
+ "source": [
+ "They can be [simplified](https://docs.sympy.org/latest/modules/simplify/simplify.html):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "7bcac010-14a5-4d81-9e8a-c4cc9d84067a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\frac{t \\sqrt{\\frac{t^{2} - x^{2} - y^{2} - z^{2}}{t^{2}}} \\left(t^{2} + x^{2} + y^{2} + z^{2}\\right)}{t^{2} - x^{2} - y^{2} - z^{2}}$"
+ ],
+ "text/plain": [
+ "t*sqrt((t**2 - x**2 - y**2 - z**2)/t**2)*(t**2 + x**2 + y**2 + z**2)/(t**2 - x**2 - y**2 - z**2)"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "boosted.t.simplify()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8e29d643-52e8-4b7d-bbd3-2b864d5efdb6",
+ "metadata": {},
+ "source": [
+ "And the symbols can be [replaced with numerical values](https://docs.sympy.org/latest/modules/core.html#sympy.core.basic.Basic.subs):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "0b9b401d-43a1-411f-9d88-f7c91fa6c5e7",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/latex": [
+ "$\\displaystyle \\frac{57 \\sqrt{86}}{43}$"
+ ],
+ "text/plain": [
+ "57*sqrt(86)/43"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "boosted.t.subs({x: 3, y: 2, z: 1, t: 10})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "55befc25-e5a1-465c-9dfa-850f0dc06cf5",
+ "metadata": {},
+ "source": [
+ "Or [converted into code](https://docs.sympy.org/latest/modules/printing.html#prettyprinter-class) for a programming language:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "57fa1123-2d1a-47ac-ad8e-31a0ceee8747",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " t*sqrt((t**2 - x**2 - y**2 - z**2)/t**2)*(t**2 + x**2 + y**2 + z**\n",
+ " @ 2)/(t**2 - x**2 - y**2 - z**2)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sympy.printing.fortran\n",
+ "\n",
+ "print(sympy.printing.fortran.fcode(boosted.t.simplify()))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/src/talks.md b/docs/src/talks.md
new file mode 100644
index 00000000..00fd2737
--- /dev/null
+++ b/docs/src/talks.md
@@ -0,0 +1,9 @@
+# Presentations about Vector
+
+- [CHEP 2024](https://indico.cern.ch/event/1338689) (2024-10-21): [A new SymPy backend for vector: uniting experimental and theoretical physicists](https://indi.to/zTs5b)
+- [PyHEP 2024](https://indico.cern.ch/event/1384010) (2024-07-03): [🎥](https://www.youtube.com/watch?v=aVPhP_APhqw) [A new SymPy backend for vector: uniting experimental and theoretical physicists](https://indi.to/pfTC6)
+- [PyHEP 2023](https://indico.cern.ch/event/1252095) (2023-10-09): [🎥](https://www.youtube.com/watch?v=JHEAb2R3xzE&list=PLKZ9c4ONm-VlAorAG8kR09ZqhMfHiH2LJ&index=10) [What’s new with Vector? First major release is out!](https://indi.to/35ym5)
+- [PyHEP 2022](https://indico.cern.ch/event/1150631) (2022-09-13): [🎥](https://www.youtube.com/watch?v=4iveMzrbe7s&list=PLKZ9c4ONm-VkohKG-skzEG_gklMaSgaO7&index=15) [Constructing HEP vectors and analyzing HEP data using Vector](https://indi.to/bPmMc)
+- [DANCE/CoDaS@Snowmass 2022](https://indico.cern.ch/event/1151329) (2022-07-20): [Analysis Grand Challenge / HEP Scientific Python Ecosystem](https://indico.cern.ch/event/1151329/timetable/#3-analysis-grand-challenge-hep)
+- [IRIS-HEP AGC Tools 2022](https://indico.cern.ch/event/1126109) (2022-04-25): [🎥](https://www.youtube.com/watch?v=O9KvsDMKOmY) [Foundation libraries (Uproot, Awkward, hist, mplhep)](https://indico.cern.ch/event/1126109/contributions/4780138)
+- [IRIS-HEP AGC Tools 2021](https://indico.cern.ch/event/1076231) (2021-11-03): [🎥](https://indico.cern.ch/event/1076231/contributions/4560398/attachments/2338579/4017718/agc_uproot_awk.mp4) [Data handling: Uproot, Awkward & Vector](https://indico.cern.ch/event/1076231/contributions/4560398)
diff --git a/docs/src/vector2d.md b/docs/src/vector2d.md
new file mode 100644
index 00000000..6dc2208d
--- /dev/null
+++ b/docs/src/vector2d.md
@@ -0,0 +1,12 @@
+# Interface for 2D vectors
+
+2D vectors of all backends have the following attributes, properties, and methods.
+
+For the momentum synonyms, see [Interface for 2D momentum](momentum2d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.VectorProtocolPlanar
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/src/vector3d.md b/docs/src/vector3d.md
new file mode 100644
index 00000000..31ece24c
--- /dev/null
+++ b/docs/src/vector3d.md
@@ -0,0 +1,12 @@
+# Interface for 3D vectors
+
+3D vectors of all backends have the following attributes, properties, and methods.
+
+For the momentum synonyms, see [Interface for 3D momentum](momentum3d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.VectorProtocolSpatial
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/src/vector4d.md b/docs/src/vector4d.md
new file mode 100644
index 00000000..837246ba
--- /dev/null
+++ b/docs/src/vector4d.md
@@ -0,0 +1,12 @@
+# Interface for 4D vectors
+
+4D vectors of all backends have the following attributes, properties, and methods.
+
+For the momentum synonyms, see [Interface for 4D momentum](momentum4d.md).
+
+```{eval-rst}
+.. autoclass:: vector._methods.VectorProtocolLorentz
+ :members:
+ :inherited-members:
+ :member-order: bysource
+```
diff --git a/docs/usage/intro.ipynb b/docs/usage/intro.ipynb
deleted file mode 100644
index 8d22682d..00000000
--- a/docs/usage/intro.ipynb
+++ /dev/null
@@ -1,4084 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "auburn-verification",
- "metadata": {},
- "source": [
- "# Introduction to Vector\n",
- "\n",
- "Vector is a Python 3.8+ library (Python 3.6 and 3.7 supported till `v0.9.0` and `v1.0.0`, respectively) for 2D, 3D, and [Lorentz vectors](https://en.wikipedia.org/wiki/Special_relativity#Physics_in_spacetime), especially _arrays of vectors_, to solve common physics problems in a NumPy-like way.\n",
- "\n",
- "Main features of Vector:\n",
- "\n",
- " * Pure Python with NumPy as its only dependency. This makes it easier to install.\n",
- " * Vectors may be represented in a variety of coordinate systems: Cartesian, cylindrical, spherical, and any combination of these with time or proper time for Lorentz vectors. In all, there are 12 coordinate systems: {$x$-$y$ vs $\\rho$-$\\phi$ in the azimuthal plane} × {$z$ vs $\\theta$ vs $\\eta$ longitudinally} × {$t$ vs $\\tau$ temporally}.\n",
- " * Uses names and conventions set by [ROOT](https://root.cern/)'s [TLorentzVector](https://root.cern.ch/doc/master/classTLorentzVector.html) and [Math::LorentzVector](https://root.cern.ch/doc/master/classROOT_1_1Math_1_1LorentzVector.html), as well as [scikit-hep/math](https://github.com/scikit-hep/scikit-hep/tree/master/skhep/math), [uproot-methods TLorentzVector](https://github.com/scikit-hep/uproot3-methods/blob/master/uproot3_methods/classes/TLorentzVector.py), [henryiii/hepvector](https://github.com/henryiii/hepvector), and [coffea.nanoevents.methods.vector](https://coffeateam.github.io/coffea/modules/coffea.nanoevents.methods.vector.html).\n",
- " * Implemented on a variety of backends:\n",
- " - pure Python objects\n",
- " - [SymPy](https://www.sympy.org/en/index.html) vectors\n",
- " - NumPy arrays of vectors (as a [structured array](https://numpy.org/doc/stable/user/basics.rec.html) subclass)\n",
- " - [Awkward Arrays](https://awkward-array.org/) of vectors\n",
- " - potential for more: CuPy, TensorFlow, Torch...\n",
- " * Awkward backend also implemented in [Numba](https://numba.pydata.org/) for JIT-compiled calculations on vectors.\n",
- " * [JAX](https://awkward-array.org/doc/main/user-guide/how-to-specialize-differentiate-jax.html) and [Dask](https://dask-awkward.readthedocs.io/en/stable/) support through Awkward Arrays.\n",
- " * Distinction between geometrical vectors, which have a minimum of attribute and method names, and vectors representing momentum, which have synonyms like `pt` = `rho`, `energy` = `t`, `mass` = `tau`.\n",
- "\n",
- "This notebook requires Vector, NumPy, Awkward Array, SymPy, and Numba to run."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "careful-mandate",
- "metadata": {},
- "outputs": [],
- "source": [
- "from __future__ import annotations\n",
- "\n",
- "import numbers\n",
- "\n",
- "import awkward as ak # at least v2.0.0 (vector v1.4.* supports awkward v1 and v2 both)\n",
- "import numba as nb\n",
- "import numpy as np\n",
- "import sympy\n",
- "\n",
- "import vector"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "supposed-outreach",
- "metadata": {},
- "source": [
- "## Constructing a vector or an array of vectors\n",
- "\n",
- "The easiest way to create one or many vectors is with a helper function:\n",
- "\n",
- " * `vector.obj` to make a pure Python vector object,\n",
- " * `vector.arr` to make a NumPy array of vectors (lowercase, like `np.array`),\n",
- " * `vector.awk` to make an Awkward Array of vectors (uppercase, like `ak.Array`).\n",
- " * `vector.zip` to make an Awkward Array of vectors (similar to `ak.zip`)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "instant-phoenix",
- "metadata": {},
- "source": [
- "### Pure Python vectors\n",
- "\n",
- "You can directly use the `VectorObject` classes to construct object type vectors:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "c133d634",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=1.1, y=2.2)"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorObject2D(x=1.1, y=2.2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "2e48bfd8",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumObject3D(px=1.1, py=2.2, pz=3.3)"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.MomentumObject3D(px=1.1, py=2.2, pz=3.3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "73748719",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject4D(x=1.1, y=2.2, eta=3.3, tau=4.4)"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorObject4D(x=1.1, y=2.2, eta=3.3, tau=4.4)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "3dbe90b0",
- "metadata": {},
- "source": [
- "and so on for every class.\n",
- "\n",
- "Or, you can use a single wrapper function to construct all possible combinations of\n",
- "object type vectors:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "divided-control",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=3, y=4)"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4) # Cartesian 2D vector"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "touched-reader",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(rho=5, phi=0.9273)"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273) # same in polar coordinates"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "coordinated-banner",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4).isclose(\n",
- " vector.obj(rho=5, phi=0.9273)\n",
- ") # use \"isclose\" unless they are exactly equal"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "worse-depression",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject3D(x=3, y=4, z=-2)"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4, z=-2) # Cartesian 3D vector"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "copyrighted-answer",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject4D(x=3, y=4, z=-2, t=10)"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4, z=-2, t=10) # Cartesian 4D vector"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "recovered-platinum",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject4D(rho=5, phi=0.9273, eta=-0.39, t=10)"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(\n",
- " rho=5, phi=0.9273, eta=-0.39, t=10\n",
- ") # in rho-phi-eta-t cylindrical coordinates"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "exempt-palestine",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumObject4D(pt=5, phi=0.9273, eta=-0.39, E=10)"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(\n",
- " pt=5, phi=0.9273, eta=-0.39, E=10\n",
- ") # use momentum-synonyms to get a momentum vector"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "better-responsibility",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273, eta=-0.39, t=10) == vector.obj(\n",
- " pt=5, phi=0.9273, eta=-0.390035, E=10\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "adverse-lighting",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "8.426194916448265"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(\n",
- " rho=5, phi=0.9273, eta=-0.39, t=10\n",
- ").tau # geometrical vectors have to use geometrical names (\"tau\", not \"mass\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "id": "broadband-budget",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "8.426194916448265"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(\n",
- " pt=5, phi=0.9273, eta=-0.39, E=10\n",
- ").mass # momentum vectors can use momentum names (as well as geometrical ones)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "id": "prompt-archive",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumObject4D(pt=5, phi=0.9273, theta=1.9513, mass=8.4262)"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(\n",
- " pt=5, phi=0.9273, theta=1.9513, mass=8.4262\n",
- ") # any combination of azimuthal, longitudinal, and temporal coordinates is allowed"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "id": "southern-register",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4, z=-2, t=10).isclose(\n",
- " vector.obj(pt=5, phi=0.9273, theta=1.9513, mass=8.4262)\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "id": "utility-cartridge",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(True, True, True, True, True, True, True, True, True, True)"
- ]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Test instance type for any level of granularity.\n",
- "(\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2), vector.Vector\n",
- " ), # is a vector or array of vectors\n",
- " isinstance(vector.obj(x=1.1, y=2.2), vector.Vector2D), # is 2D (not 3D or 4D)\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2), vector.VectorObject\n",
- " ), # is a vector object (not an array)\n",
- " isinstance(vector.obj(px=1.1, py=2.2), vector.Momentum), # has momentum synonyms\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4), vector.Planar\n",
- " ), # has transverse plane (2D, 3D, or 4D)\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4), vector.Spatial\n",
- " ), # has all spatial coordinates (3D or 4D)\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4), vector.Lorentz\n",
- " ), # has temporal coordinates (4D)\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4).azimuthal, vector.AzimuthalXY\n",
- " ), # azimuthal coordinate type\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4).longitudinal, vector.LongitudinalZ\n",
- " ), # longitudinal coordinate type\n",
- " isinstance(\n",
- " vector.obj(x=1.1, y=2.2, z=3.3, t=4.4).temporal, vector.TemporalT\n",
- " ), # temporal coordinate type\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "mature-facial",
- "metadata": {},
- "source": [
- "The allowed keyword arguments for 2D vectors are:\n",
- "\n",
- " * `x` and `y` for Cartesian azimuthal coordinates,\n",
- " * `px` and `py` for momentum,\n",
- " * `rho` and `phi` for polar azimuthal coordinates,\n",
- " * `pt` and `phi` for momentum.\n",
- "\n",
- "For 3D vectors, you need the above and:\n",
- "\n",
- " * `z` for the Cartesian longitudinal coordinate,\n",
- " * `pz` for momentum,\n",
- " * `theta` for the spherical polar angle (from $0$ to $\\pi$, inclusive),\n",
- " * `eta` for pseudorapidity, which is a kind of spherical polar angle.\n",
- "\n",
- "For 4D vectors, you need the above and:\n",
- "\n",
- " * `t` for the Cartesian temporal coordinate,\n",
- " * `E` or `energy` to get four-momentum,\n",
- " * `tau` for the \"proper time\" (temporal coordinate in the vector's rest coordinate system),\n",
- " * `M` or `mass` to get four-momentum.\n",
- "\n",
- "Since momentum vectors have momentum-synonyms _in addition_ to the geometrical names, any momentum-synonym will make the whole vector a momentum vector."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "handmade-tract",
- "metadata": {},
- "source": [
- "If you want to bypass the dimension and coordinate system inference through keyword arguments (e.g. for static typing), you can use specialized constructors:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "id": "center-beauty",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=1.1, y=2.2)"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorObject2D.from_xy(1.1, 2.2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "id": "indoor-playing",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumObject3D(pt=1.1, phi=2.2, pz=3.3)"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.MomentumObject3D.from_rhophiz(1.1, 2.2, 3.3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "id": "documented-lyric",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject4D(x=1.1, y=2.2, eta=3.3, tau=4.4)"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorObject4D.from_xyetatau(1.1, 2.2, 3.3, 4.4)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "improved-coach",
- "metadata": {},
- "source": [
- "and so on, for all combinations of azimuthal, longitudinal, and temporal coordinates, geometric and momentum-flavored."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "54ede1c4-249e-4218-8563-4f29e2748213",
- "metadata": {},
- "source": [
- "### SymPy vectors\n",
- "\n",
- "> **Note:** Operations on SymPy vectors are only 100% compatible with numeric vectors (Python, NumPy, and Awkward backends) if the vectors are positive time-like, that is, if `t**2 > x**2 + y**2 + z**2`. The space-like and negative time-like cases have different sign conventions.\n",
- "\n",
- "You can directly use the `VectorSympy` and `MomentumSympy` classes to construct object type vectors:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "id": "2e184679-4fd9-4a5b-9705-1f060977e970",
- "metadata": {},
- "outputs": [],
- "source": [
- "x, y, z, t, px, py, pz, eta, tau = sympy.symbols(\n",
- " \"x y z t px py pz eta tau\",\n",
- " real=True, # see sympy assumptions to add more restrictions on the symbols\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "id": "e4e385f0-6b9a-4395-974f-ddcdff7416af",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorSympy2D(x=x, y=y)"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorSympy2D(x=x, y=y)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "id": "a84770fa-8a8e-4e96-a95d-f4109f9ef876",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumSympy3D(px=px, py=py, pz=pz)"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.MomentumSympy3D(px=px, py=py, pz=pz)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "id": "a7c741e0-ae25-46a5-8a53-8a713a7b837f",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorSympy4D(x=x, y=y, eta=eta, tau=tau)"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.VectorSympy4D(x=x, y=y, eta=eta, tau=tau)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "fad8d0f2-04e4-47a2-978e-a146192bead2",
- "metadata": {},
- "source": [
- "and so on for every class."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "id": "bbb22de8-32ca-44f5-9e55-d03a49f5e2fe",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(True, True, True, True, True, True, True, True, True, True)"
- ]
- },
- "execution_count": 25,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Test instance type for any level of granularity.\n",
- "(\n",
- " # is a vector or array of vectors\n",
- " isinstance(vector.VectorSympy2D(x=x, y=y), vector.Vector),\n",
- " # is 2D (not 3D or 4D)\n",
- " isinstance(vector.VectorSympy2D(x=x, y=y), vector.Vector2D),\n",
- " # is a sympy vector (not an array)\n",
- " isinstance(vector.VectorSympy2D(x=x, y=y), vector.VectorSympy),\n",
- " # has momentum synonyms\n",
- " isinstance(vector.MomentumSympy2D(px=px, py=py), vector.Momentum),\n",
- " # has transverse plane (2D, 3D, or 4D)\n",
- " isinstance(vector.VectorSympy4D(x=x, y=y, z=z, t=t), vector.Planar),\n",
- " # has all spatial coordinates (3D or 4D)\n",
- " isinstance(vector.VectorSympy4D(x=x, y=y, z=z, t=t), vector.Spatial),\n",
- " # has temporal coordinates (4D)\n",
- " isinstance(vector.VectorSympy4D(x=x, y=y, z=z, t=t), vector.Lorentz),\n",
- " # azimuthal coordinate type\n",
- " isinstance(vector.VectorSympy4D(x=x, y=y, z=z, t=t).azimuthal, vector.AzimuthalXY),\n",
- " # longitudinal coordinate type\n",
- " isinstance(\n",
- " vector.VectorSympy4D(x=x, y=y, z=z, t=t).longitudinal, vector.LongitudinalZ\n",
- " ),\n",
- " # temporal coordinate type\n",
- " isinstance(vector.VectorSympy4D(x=x, y=y, z=z, t=t).temporal, vector.TemporalT),\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e7887274-a456-473e-a848-88a38ea594aa",
- "metadata": {},
- "source": [
- "Since `VectorSympy2D`, `VectorSympy3D`, `VectorSympy4D`, and their momentum equivalents operate on SymPy expressions, all of the normal SymPy methods and functions work on the results, coordinates, and the vectors."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "id": "d1dfc115-ceee-4b47-a25d-5e57242aae23",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "IPython console for SymPy 1.13.0 (Python 3.11.5-64-bit) (ground types: python)\n",
- "\n",
- "These commands were executed:\n",
- ">>> from sympy import *\n",
- ">>> x, y, z, t = symbols('x y z t')\n",
- ">>> k, m, n = symbols('k m n', integer=True)\n",
- ">>> f, g, h = symbols('f g h', cls=Function)\n",
- ">>> init_printing()\n",
- "\n",
- "Documentation can be found at https://docs.sympy.org/1.13.0/\n",
- "\n"
- ]
- }
- ],
- "source": [
- "sympy.init_session() # latex printing"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "id": "25b81776-1240-4e86-8b16-c3590470e502",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAACoAAAAOCAYAAABZ/o57AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB0UlEQVRIDb2W7U0CQRCGD0IBqB1oBxAqEDuA2IF0oH/5Z6ADtAKFDqAEpAOxA0MH+Dzn7uVyhFNAb5JhZudj592vOWrb7TYZDodvSZI04Q38GWQLKWlbw/rPg1yTc4NeGTVCJUH1KT6LldHv0UfwAP0pZ++hP8dxVbIOCHdqlgdZVjzELcti/sNXZ1KPc37g5KuwwAPTjg8XqDvqHTyE3gl2gZVRg51ZHVHNhU3JvUQ+wo47cBfuwy7ee6x/QZy2BHmHGMBpHuOx9kiMtT/AbsQF3MRmfFL351Ai2eLtkHcV5ATpo+zi82rot4MIOiVsPsprOLN9e9JFmGv3GRE3hlPASG3HATUxkEAE5mN0V8+QWYdgvHOl8G9CblFMMbyGeVIfujveQvZieyom/XZs0QxMCYjS+chzNz32dPcKwV7NzqlAndNdPZUEKbUB7T3Ok1dq+RdA9x1lvthPejyVOUCzj04+qZ4fVKEDJO5eVg6bx+uCbzNjTsHfPRVok/nkfeSHpAjMFiYo20+e7AY+TP0ZMfYzvq75pyRSCLLn2cxNEISTLmDv4oQYW48++5vf/eh/wb5zbNi8Y5K90dhX+AOWlvizPzfoLsq2JMVeas31Fx2vogF49TMKAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle \\text{True}$"
- ],
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 27,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v1 = vector.VectorSympy2D(x=x, y=y)\n",
- "sympy.Eq(v1.rho, sympy.sqrt(x**2 + y**2))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "id": "405f6458-cc8c-4c15-ae82-264d133ca627",
- "metadata": {},
- "outputs": [],
- "source": [
- "v2 = vector.VectorSympy4D(x=x, y=y, z=z, t=t)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "id": "9e7a68d7-33b6-4654-b0f0-4dda87f0ce58",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle \\sqrt{\\left|{- t^{2} + x^{2} + y^{2} + z^{2}}\\right|}$"
- ],
- "text/plain": [
- " _______________________\n",
- " ╱ │ 2 2 2 2│ \n",
- "╲╱ │- t + x + y + z │ "
- ]
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.to_rhophithetatau().tau"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "id": "56ca9dc1-f8f7-4774-b80b-5fc8f2e1be88",
- "metadata": {},
- "outputs": [],
- "source": [
- "values = {x: 3, y: 2, z: 1, t: 10} # t**2 > x**2 + y**2 + z**2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "id": "e98893fa-511e-4380-8d1a-90aecf6a50c2",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMAAAAAXCAYAAABd50CQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFRUlEQVR4Ae2a3XEUORRG2y4HQC0ZQAZQRICdASwRgDOA8pP9RkEGQARbkAEmAgwZrDcCw2RgztFKKnXXMDP2aMbSrm+V5qrVavWnq/sn9excXl4Oi+jk5OQO949in3uRP6d9tui5Fu71ir1H3D1iVkf3VlDUN0zuMPWj/o76N8r91NYw7xV7j7h7xDzsrqC8L1D6/aLfG+r3aHtQtLVa7RV7j7h7xLySAej9z1rV8CW4esXeI+4eMQ87y/YAUwXD8xsBnsB7SIFG8HvF3iPuXjCvsgfISsSkTHueUB7mxk4qvWLvEXdrmMGj05YuKDpu9yvnNowiAI2e+LjBPUgd7CRx7QmQG+Cn1Js/ARJzol6x94i7NczgUZ9fwz+pD/CRjk8jgJtdFf2HnRPxkG2v4Ae2xWt5sKLUr0UesXaHvUfcrWEGzwt08g48KL/6SX0Wr3XmB1MDUMHP7WRniXry/CpROvlxw/MqdGj4p1fsPeJeBzPP6pW/UN5Rf19RpZ4y1vc5432l7aXvnRqAESBbS3zQEJLCRmwKhqERtE69Yu8R97Uxo4h65cco0xH8b7iG8LaCcqnP8wwqZS77O8fHx3ZSmVVy66cUI8DXSiAYqh6BSZyGNukR5TnFKPWMIol7asT/3rnB3wK3m7BvXOeFifc+wPVYzRG4jPwfIzD3gN8pynwfnudRCzhjvmQsddJ1NH9XH69EPKOe/KS8pz5y1lw7Hw32cJeLU4qCNycaqLsBdpI1LNAha5M7+LcRn6HsA8WFMCVz0mnHT7Up0rsp08+UKcY/afN0rTkCszJVxuqHCqn8xS+vrvyMOzCu66ujMBroLIwI4rgK/RE7zxY8NEqBzP/n5UsLnt/uLYSg5y+Vx8mpOEYByUmX90PjTf+AW4+jsUrKeXTIENuMvC2SMn3MHLIiUVfGSeYbw8x7NDA9uGv8BX4Gz0eYFV58d68YxPSnWuoAWC3WjY18VQrhdUHnM8ZN+Zvd/B5hOA6LA6+SQmwAuwcLybno7V8LviBlP20rbq9W3QDugTGzvOP4R2Klng1iNXTX78W71MtPcOX0ES6mZX/InDqZEkCKDhfBABhQJTWnMzxXIcZUQFU/mDFmUqKEcZ4ypXvX5rWxx/EGuAuorHPqQJvRwba1I0B8T1WZgysQY6sf/gOghdM/5bWQlAXFPvP6prbzYAB0cmEGHsiLQN3z05ntLRLYkjLlqCVmsTaM2wiVI1aUq/NwsabGHW/fPAObGP0DZN4XUt+afvAuUyAjj57fLCFHJa4Xkfqs4U4pRYDTvXhnlP/HF/qSZhZFgYPHkwhzQCfmzl7FKYXhRrMFDwW0ueRilHjtpOyz47GhJUKeYXMOz1Er4nNjXCXl/N18ead7PtdT+VxF8dOQQV/SRcFz6pwMQIsIC8NLVTStPXvW4sGbrOqFLH6QE+Mox6PNe2mjSbVJUsbJ+wwRs7hHx3StIAef6ZnYjFpyU+S7FI1iY8rPu8pj0Idcz3jflYnn3ECrL6ZuQZ/h6o6ps98dhj1/IK3Mo6Zwvg7PoS7cbeNHL6AXUmEGMB5SPlM8nvNM9wf11oxWqCUpZ8/7PUW5oHjUJ7UaAZ6B1Qg1wFV6vb5GrOyrZgeMp2Kqfxqauphkw+VapLc3a3gEV+ZyT7UC/tGf4bhxS1uUAIugIezDN7Jx3eJU1noV81f5dWIq6jTVWmvsZQ/fGsAyCVW6P1X2uOj/MLzHea1HrkpSaG+Y3fYg/WcRmUL8VczOdMIc9Vb5C6Fsu3obAbYkcRRdA3ADbLg3v/WDTqu5P/D+H/QLaapo0PNG2ZwAAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle t^{2} - x^{2} - y^{2} - z^{2} > 0$"
- ],
- "text/plain": [
- " 2 2 2 2 \n",
- "t - x - y - z > 0"
- ]
- },
- "execution_count": 31,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.is_timelike()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 32,
- "id": "da5af338-4554-4531-8db8-1f67be5be2b6",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAACoAAAAOCAYAAABZ/o57AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB0UlEQVRIDb2W7U0CQRCGD0IBqB1oBxAqEDuA2IF0oH/5Z6ADtAKFDqAEpAOxA0MH+Dzn7uVyhFNAb5JhZudj592vOWrb7TYZDodvSZI04Q38GWQLKWlbw/rPg1yTc4NeGTVCJUH1KT6LldHv0UfwAP0pZ++hP8dxVbIOCHdqlgdZVjzELcti/sNXZ1KPc37g5KuwwAPTjg8XqDvqHTyE3gl2gZVRg51ZHVHNhU3JvUQ+wo47cBfuwy7ee6x/QZy2BHmHGMBpHuOx9kiMtT/AbsQF3MRmfFL351Ai2eLtkHcV5ATpo+zi82rot4MIOiVsPsprOLN9e9JFmGv3GRE3hlPASG3HATUxkEAE5mN0V8+QWYdgvHOl8G9CblFMMbyGeVIfujveQvZieyom/XZs0QxMCYjS+chzNz32dPcKwV7NzqlAndNdPZUEKbUB7T3Ok1dq+RdA9x1lvthPejyVOUCzj04+qZ4fVKEDJO5eVg6bx+uCbzNjTsHfPRVok/nkfeSHpAjMFiYo20+e7AY+TP0ZMfYzvq75pyRSCLLn2cxNEISTLmDv4oQYW48++5vf/eh/wb5zbNi8Y5K90dhX+AOWlvizPzfoLsq2JMVeas31Fx2vogF49TMKAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle \\text{True}$"
- ],
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 32,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.is_timelike().subs(values)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 33,
- "id": "0be2000d-4386-4ee0-8b78-1207045cc4c2",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle 9.2736184954957$"
- ],
- "text/plain": [
- "9.27361849549570"
- ]
- },
- "execution_count": 33,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.to_rhophithetatau().tau.subs(values).evalf()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 34,
- "id": "d764bbca-2a30-4249-9caa-52642cb47e5d",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorSympy4D(x=x*(1 + x**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + x/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x*y**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + x*z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), y=y*(1 + y**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + y/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2*y/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y*z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), z=z*(1 + z**2/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))) + z/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2*z/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y**2*z/(t**2*(1 + 1/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2))*(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)), t=t/sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2) + x**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + y**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)) + z**2/(t*sqrt(1 - x**2/t**2 - y**2/t**2 - z**2/t**2)))"
- ]
- },
- "execution_count": 34,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.boost(v2.to_beta3())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 35,
- "id": "11f06041-3f8d-418f-a4c2-c3378d0b930f",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle \\frac{t}{\\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{x^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{y^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}} + \\frac{z^{2}}{t \\sqrt{1 - \\frac{x^{2}}{t^{2}} - \\frac{y^{2}}{t^{2}} - \\frac{z^{2}}{t^{2}}}}$"
- ],
- "text/plain": [
- " 2 2 ↪\n",
- " t x y ↪\n",
- "──────────────────────── + ────────────────────────── + ────────────────────── ↪\n",
- " __________________ __________________ ______________ ↪\n",
- " ╱ 2 2 2 ╱ 2 2 2 ╱ 2 2 ↪\n",
- " ╱ x y z ╱ x y z ╱ x y ↪\n",
- " ╱ 1 - ── - ── - ── t⋅ ╱ 1 - ── - ── - ── t⋅ ╱ 1 - ── - ── - ↪\n",
- " ╱ 2 2 2 ╱ 2 2 2 ╱ 2 2 ↪\n",
- "╲╱ t t t ╲╱ t t t ╲╱ t t ↪\n",
- "\n",
- "↪ 2 \n",
- "↪ z \n",
- "↪ ──── + ──────────────────────────\n",
- "↪ ____ __________________\n",
- "↪ 2 ╱ 2 2 2 \n",
- "↪ z ╱ x y z \n",
- "↪ ── t⋅ ╱ 1 - ── - ── - ── \n",
- "↪ 2 ╱ 2 2 2 \n",
- "↪ t ╲╱ t t t "
- ]
- },
- "execution_count": 35,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.boost(v2.to_beta3()).t"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 36,
- "id": "bf3b60b5-59a2-4cc7-ac40-ef759c062932",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle \\frac{t \\sqrt{\\frac{t^{2} - x^{2} - y^{2} - z^{2}}{t^{2}}} \\left(t^{2} + x^{2} + y^{2} + z^{2}\\right)}{t^{2} - x^{2} - y^{2} - z^{2}}$"
- ],
- "text/plain": [
- " ___________________ \n",
- " ╱ 2 2 2 2 \n",
- " ╱ t - x - y - z ⎛ 2 2 2 2⎞\n",
- "t⋅ ╱ ───────────────── ⋅⎝t + x + y + z ⎠\n",
- " ╱ 2 \n",
- " ╲╱ t \n",
- "───────────────────────────────────────────────\n",
- " 2 2 2 2 \n",
- " t - x - y - z "
- ]
- },
- "execution_count": 36,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.boost(v2.to_beta3()).t.simplify()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 37,
- "id": "4cd7282c-f97d-45a0-bb03-acf5756cb383",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAADwAAAAuCAYAAAB04nriAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFe0lEQVRoBe2Z7ZHUOBCGPRQBwJEBlwG3G8FBBnAbAZDBUfza/UdBBkAEfGQARMBBBkcGd7cZLM+jcatkje0xi+1ji+0qjaRWS+q3u9Uey5uzs7PmR6KTk5Nb6HNE/Ygyu3JXfySwrS5PqR/ZBvCm5c1WXZltpRkWAqDeFejnGZbrXSIDjs1KKXjXKDeDZ5vyQH7wZq4fs54eXozKkP7QAgnrBqjfit31wHMLsgU7N0/hX8+9b2gwT8Nq0Pf1NHjqojGC7L/pk1UAfm20V/ASrhLwv+1qgvpCeUt5guBpy7c6pKiQ4zXdhpHOXj0wse/coflP0eNhuQ59ARuB6pmItkZ7QzHhJcNR27f8SmlKwJ8ZvCdzjJC5U4/DS2FPnTevZcb6zNNjB9QdUM6B94Dqk+2K7tP/QCn3FJjeLKPEtbODSsDw99LHAQk9sNdYA3NlG4JPBsb1jAZ9MTCe2Ox/l4bR+XspB7/joCvl4L42k0trJnF4Y8ruW7Jhvh643bd2O1kj32X8XSsba7qv+STI6DCHlEcwxnK9iT8eCBoO7ygqcIOiVT3DkcTodokxZUxgHSt2pcZ7zFXxv6kHPciYuulByXOu1zVAdgDt/+AZuob6EeUfinKd5FZ6WKCvmfiMEgnkE22T0RCprKWXmKtnxuY7T5lBsAow7nEJGfdzzdoR6i+ZC0xa4tDrAg5jNRkwzDuUHA60tZaHvwwbultiXO8aimWCiOEG/p90XlLGDKJM7/p5IRqspcLqpsfcz72NigSEOsDeoh2GQSTRa35fhkwG3A7WlaB9NrpBTVovZ79yEHmThxtbVMJ+Hz1k7FnfQPAYN0vrDL32heLxiQSZgbTyffqY4TXIgTIJMIt4HvpSvzJSWHDb2/5q3Xh2l/yGtXzE6ZHIvOWfhiTLuED2ehcZI6TzfGauZ1dvq5dR5l5S1Nte9zc5LQGGL3on1/SLDBbsnBf6yrrA2AbOc1wve07ThrSDBFGHX4ylut3HPxc7+8DTmwJPOlIb6uo1RMn7AfgFC2ixmkwOfWc0hQdjvR6uFokznL3EXkbH2z4g5dx23EdNbawQE2DoZ7T0yfnX2DWSXAD20dIJL/omFCnOy7a3/Q1L7li+FLLNOlrWzcqXDkM8wp3mKLl/+htZSrGuR8KjmDxHrbffU4eBG9rq+QfFR1Wi8jmsdcILhoneM1HsgIKnrGf+Pu38LKTfS8gYKT7jXV8FTUImvUmErElPI5UR1Xm+xkLICjgcIo7Of4kMOCYsVaOIBtJQAr5HP3lmqf2G1o2QHhqfk28Ia3kfLf8LWMGsBhiQhr7ZPo6N+69Oq4X06sgGNlzNwwP7r86+BLy6yVfe8Kfz8Ob4+Hj22/2VnTZ5O54Um8ssPdlcF1TwpzvDl4AvaKROVvvqZMnvFCRD+ornHVbntZD+Tfnt8r5c2PdiP17s26F5qtUAo653y748ZAKUAH3nDsANbW9DfLH3FXLvu3ZebGJjlTOM4nF7UqvlrYU3IYIMCs/6wj87LQ4YMIbyaVtqAHq8M4a8/cVojZA+AkQnbAMNfL3Z+Z4ML7zduWOLOd9bL+phlJ/0ZSFAIO/dl3dSJrfRK9yY8631Yh5GYbOt16N7r3OQMewFe0gxzP+iLEKLAUZbvTTpOgc5QaYMTtuQ9iPexcnSKDv1M8qOF5nro8jEtXMXvSN8DsbsZxiFDWU/j0wKZeQM55oipA3zWWmJkBbwIUD8o1GSwPwSKd+rWsM9fcCjfZ2y6OMoFJkdMIr7qIk/D7FPA98v9H4KKT/dCFJeDfagnbizTl7wnI3ZAY/ocY0xS0k7SQ3wJi3lTHq1Icq552ovfuOB0v6BMMzjPJqUPsJPH8Kp5ZdeV3axl4eviiMGEw28sb8AAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle \\frac{57 \\sqrt{86}}{43}$"
- ],
- "text/plain": [
- "57⋅√86\n",
- "──────\n",
- " 43 "
- ]
- },
- "execution_count": 37,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.boost(v2.to_beta3()).t.subs(values)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 38,
- "id": "a52b57a0-516f-4a14-b0dc-590c8d3b1017",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle 12.292936145192$"
- ],
- "text/plain": [
- "12.2929361451920"
- ]
- },
- "execution_count": 38,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v2.boost(v2.to_beta3()).t.subs(values).evalf()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0e7b9e31-5e43-4bf7-9de5-b8d3e95fd6d5",
- "metadata": {},
- "source": [
- "All of the keyword arguments and rules that apply to `vector.obj` construction apply to `vector.VectorSympyND` and `vector.MomentumObjectND` objects."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "sustained-object",
- "metadata": {},
- "source": [
- "### NumPy arrays of vectors\n",
- "\n",
- "You can directly use the `VectorNumpy` classes to construct object type vectors:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 39,
- "id": "c88d6a0c",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],\n",
- " dtype=[('x', '[[{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": 49,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.Array(\n",
- " [\n",
- " [{\"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",
- " [\n",
- " {\"x\": 4, \"y\": 4.4, \"z\": 0.4},\n",
- " {\"x\": 5, \"y\": 5.5, \"z\": 0.5},\n",
- " {\"x\": 6, \"y\": 6.6, \"z\": 0.6},\n",
- " ],\n",
- " ]\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "hybrid-powell",
- "metadata": {},
- "source": [
- "If you want _any_ records named \"`Vector2D`\", \"`Vector3D`\", \"`Vector4D`\", \"`Momentum2D`\", \"`Momentum3D`\", or \"`Momentum4D`\" to be interpreted as vectors, register the behaviors globally."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "id": "becoming-demand",
- "metadata": {},
- "outputs": [],
- "source": [
- "vector.register_awkward()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "id": "bored-ribbon",
- "metadata": {},
- "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": 51,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ak.Array(\n",
- " [\n",
- " [{\"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",
- " [\n",
- " {\"x\": 4, \"y\": 4.4, \"z\": 0.4},\n",
- " {\"x\": 5, \"y\": 5.5, \"z\": 0.5},\n",
- " {\"x\": 6, \"y\": 6.6, \"z\": 0.6},\n",
- " ],\n",
- " ],\n",
- " with_name=\"Vector3D\",\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "beginning-expert",
- "metadata": {},
- "source": [
- "All of the keyword arguments and rules that apply to `vector.obj` construction apply to `vector.Array` field names.\n",
- "\n",
- "Finally, the `VectorAwkward` mixins can be subclassed to create custom vector classes. The awkward behavior classes and projections must be named as `*Array`. For example, `coffea` uses the following names - `TwoVectorArray`, `ThreeVectorArray`, `PolarTwoVectorArray`, `SphericalThreeVectorArray`, ..."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "documentary-skill",
- "metadata": {},
- "source": [
- "## Vector properties\n",
- "\n",
- "Any geometrical coordinate can be computed from vectors in any coordinate system; they'll be provided or computed as needed."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 52,
- "id": "colored-directory",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABkAAAAPCAYAAAARZmTlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABjElEQVQ4Ea2U723CQAzFU9QBItgg3QDaDdIN2m5QukH5mHyrwgYwQmED0gkQbAAbgNgg/b3kjEKUP1VUSy/ne2efz/blvCzLvCiKxhrLgPNBUOb66vdeIT9xHPuoezeXLpkUQ/cX/8RZnRgfQAJ3FDfQBzmDCxgDBViDCUbiOgW7HUZbxhmYo8/ABj3InVUCyrLqWwp8p+BQ9YdLwEa8ZZIH7Pl5xc/KXN5iyyQkG/8/goRspnJXJe8HZGiN94g4hVA/RkC1/IKrOyFLhbAu+y4ZWiYy/sZpDtQ0YYeuU7bJ0C22XZCiXGz2DK6G6Eo1BYu2CH9cG1kmdfYKFBBQpWuSul6YrWV5GrCJ7rPueZM01h0/y77OxrijMnkERpQD5Sdho9bm46Cy1mVrmaQKsmQjPQNVUdO1QZesMNBBq6Inaa9sFWSBctNg5p/OQz9aLnA+yMBNaZkvMTgzvjhTD12VeQPv4u7020MqXV1bidJUQ/UOXUSYMD+gp4wfxmlkrk31QMpeD+QTuP5nv4JEA14+QuryAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 5.0$"
- ],
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 52,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4).rho"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "id": "passive-benchmark",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle 2.99998087197215$"
- ],
- "text/plain": [
- "2.9999808719721477"
- ]
- },
- "execution_count": 53,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273).x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 54,
- "id": "indoor-opportunity",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAAPCAYAAABjhcQWAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFQUlEQVRoBe2a600dMRCFL4gCbkgFkA4CdJB0kEcFhA5A+cc/BB1AKsijA0gFPDpIUkEIHdycz3fH8nrttc2NtFGUkXxtj8fH9vF41ruwtlgsZv/l72Hg+Pj4udJdOCPV56pvKv8e6v+F8kZuERChtgPlBzmbWC/b0073U/kzpdMUaVPZ2Xw1Pmv7rLSj8oPpc3lnP+BC+m31MX5wEuqs+SqHZfocptq/qg0sc0LKyM4y6//K9jzQbKq8L93omkbGnj0Gj/FzmNKPcpR1QGGyQUYCY4yKBrqVwYnyLxgqh7hb5S+V/MlVeSo75vNB6V5pVwliamXARbe+I+XmgDOVXwnwUvlrJcfDyAADzM6W+SEcEngDB157TqW641dt5yqfKZ8pp88P5RwszzltkQzGlv0qeMDnMEc5Wo8m5qqazGFKn9PJ/p3a5so96SpDGHV/QqeyY97MRwnHwGE+oqsR2ee4YM3v1I7TmVjke2+KVD6Cifmd2p8orSk9U2IDe87XYXKYeCw750OnMgHjRslzjj4U2eTW8yg8sEcwixwNHFBgnCIWnFo046XktZSpaHkt/QthzrtOU9ml5lzUFbhgvT2eZF/krIBZnFNggOOnohzzCjn3XQpjN+MBXMAscjRwQGG+FeiFn3Vd4YXM7hOmRhDtyFR2y9Hbf7NciKMrJSKVRb2ZyhYNsxFIU8hi1k5P49iBTnHO/RvZXWa93+TYK+ABnsSkQbhFjnp3QHUgPI+RB25Pgsn39FGFR4WRFjX1qn/crofeUGnlQvYcLl7CeFlJHuBaTNm5K42wniptK3EHJJo4UZnrBGVeOmKhD0I/L7LP7u1j8AAew/QDBwXZDzjyDqhGJszCLGoFXUeLRsLY4wfnm8pudPKpxhYuZMuVBWL3lHAS7mADacCEq0+yd3x2/b4p52XOR1vZcL9m3FiYDwKOkw6jtLfVeIBWYtr4WY7CR3D25DqU1X7sVJZQprKL51XNhTaCl4YzJe63vNzw5m+P4hC3ClN9cTTnfHRWmYCA48VPpv2u3TuhbNlo6xsGkpqxW/AYugYTO9aQ5cg5oAwI+fECXeeKn9Q9xLptdgXuJVPZ2Vyq8lW4UF+iCA7wWeUwAq3CL/PGmbaF6R+rKjPOlhJv9odKPP5p58UPcQ4ofdXYtXgA12JiG4v69jjakIJJz5WHJybul62rn91HPOGBsem+T2UXzKVYbOFCtu5Rp9zfzboBbpQTlUhfGjEv1Yd78I7ylBifrk12OKH/DolSOhwRgfOmvS3hAdqCKdsiRxvCZJJ7MuZDYih05tShZzFHYWNU5hEBTiwWAe3uMpVdPK9cvYULPqjPxAtvwjhCTloweXNNPSkcjxondvbUmOwbb58EBvBW3VuP1w3Wsp4iR0RAnMIcpBvDEfsLvdq525QEJ7WTF9pyknn+2wZNZRfOKVtu5II1uY2OAO3zh+O0EfNC9qmDTjTt7ZHsuGfy8XhLZcev8rnq2LoIqnr13tbgCXfWginzIkfrgGaExZC8aHAe1Qsl59nWoDqfHe6VQ4oTlen7RsldblFOZcfYkdjLjkXoqHlQHXAhCxyFR6aXbv3YckF/8A3pQgqTP6v17uKq218u4kBAJIqjJQecsUuRMjX2KnisMIVZ5Ggt/m+YjgAmw0lCuDReS29/b/ymOic/vnswAaLggxIvHXyWOInJUH0SO81lprHZIIS1MQ82irsvf78dfLuTDmcY4wKc0DGwHf1nhApMMCwKckBwsiP1g9eeSGdPHdaC8PLTi5RL9fK3YuwmPFArMEc5+g0NearHmXz/ygAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 4.00001434594943$"
- ],
- "text/plain": [
- "4.000014345949428"
- ]
- },
- "execution_count": 54,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273).y"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "id": "mature-clone",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAPCAYAAAB0p1TfAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHBUlEQVRoBeWa23EVRxBArygFIEQEQAZIisAiAzARABng8p/+VJCBIQIBGRhHgCEDcAQGZYDPmbs9mp2d3Tsr+KHcVbPz6nf39M5dae/bt2+bnxnOzs7u0T6WNjA/YH5I/7lc/z+O8cEd7D6lvWZ8+bP6YL9UHEOeD/N/6e/Snq8NdsEjWF+wNkqk2LBn7x7dU/qn5fqw16PPX9CamCHDsXC07a6e4Bm034aVY/ovzlkP2rS1Ei/0Vq789dm7xKjxYE9739COGE8Sp1d2yRqa8FMslz5X3h828GK/7C9ZvxkLjMUNOGTwmLWJnoEQPTjNOLLe5fPgE33NLycqGx9AOqd/KzK9jv9Af5+2szKBo0IGwMCnQNE7t5n0c+D+KFFEhLZXH5NN0FHqqf7aMXIuc/UzWPfpEzA2wGFj6NyLp3+0NRJ1w/gBa3/SP6QlPyqIsbivaOrqAVHGBMDrkh2EA/4un5+Ar22tGFpp08EddNTn+ugF/YZen/5D76Fq0YsWMIkjNKvsCUZDP+J3w0UYPqE7oC+da6CdlyeM6SzI2JNcVhMDNGsguM9a3Fbq8xH8m7Q92l2ayaPuNZiUOancFJdOXHUP6MXTZ0/gYXIGhO2/x4I9OFYtk1f5F+VeNe6VHWRdPkeuxSa9taKHgbLeMY+Ye5C8LqUkVQBjC8jftMUcAK8ZR+jW2gNJkjvhlxKVvYe0SVVj7T3tFEVMuFlg32B5+l6WSKzroFzBqj3xTZJWUn2XPqWcYmz1+NSwxeTykHr6hV48/TXSHx4tWxLTzkev7A2yen1uDFvgFaU8uPJrFRXtnM0BeCzFsdueUHCOXySqDL8EctGH4u4vgQZbNdYE6hH4o8QuBHyvPgWrPEyvvwUdDwbMLjz4WI2s5FFFN4yjui5WoKzRdNAleyDr8jk6RcXM0liz0p3HAvOwvZUD/l4Rjrfd5LkUxzX2BOMmv/1CyUBs9YetxWJNIz7Dy9P1iKZx3kvfsJYDyTwBa5b2ZjCvow806eoCz1s0K6N3VCtBBuZW6Rao8ybwe/FqRtB5uNKrjvHcAazJRvOVslf5PAQhQ//4pSR+VG4YW2REacVZnwrSjQCa2TiKyH6Xz4PpEr99kEK5pWoYJy541n3sHyOsdMBX5v5qzKeasQbrmKjWNa+1+ig7f3oZ+PuK99oxOSSlMPZNUvXJOpf7MV7CG/ZM0hOah8M73Q+DBdndPq+U8TDZajBG2lGDPhJCXpqg1644Jrz6MWfPLn43akYz8zhVk20EhAGe0rqSvIbgVYEjvZf6Gm/Cd8dC1gdeJuRl4DP2AJigzYodeEPvj5G30OQfENV+TGfxoPXH3Aua1eOC5leEuAIE/ff0E9nwX+vzJB86k8v7ZusAPxaJvZysjE3S8G1dWK4bx4k9ygUW+ZmorXtJouQR1S3uKbHe6mtDxPFzh05N9xsM9xW9K4F+hD7qcgd5BqYJ7KmH15W511Oi68UTGVyrkoH1yhPJ5Na1oEP2Tp9Xgr3XtmjUXb1v0/w68Yxm1dV/72lCpmOvJ45bquIJXdPnPfxugKSCQsuxsZaV3KJePQv64HO1eTWKpPHX9Swv0Qt+IfuKy5WOiQe4frP0MMxBi4cydLSfYppfJILZEh57vkHitRgk9vHqz5Wp3Owd75Advo6+xbZ1SK30s4UAmV7JrGy+IfzM58GLt1f4XL4741grBK+mz1nv4rc/MPRV0DIsKmrrVVHqMkcfOBop/xMUs/SXYLBNZNetcN4X5/jV+lipW45PePD6yP4IWDNYfm/NlZRxsp0+H6IOvHRAwPOX/1LCjOT3TDpky2bORyEi2+ICPD202jnxifsLYHz8whE2roljYrtkDwhd/CJRTZLWBfuIde9goWQS3HhY0usEFE16T2kkevTuJWDvKwMdkROHea8+L6Fr/RCymrVk6XQPS01j8uZ7M/s9ePqkDCDTBB4eYSJ/u7z87JQtk16fh8DQq3WwN8jVB370v804xZv+gLm+NI4JWNOuiW2st+K4YX3Rl+x7oHbyS4kKcgo4/QOa5X5Dr5K/0n5xLgxrKmTylsr7g8Sg+RE5JQF90KdLemLQfohnywBtlz4Q+Oc+m3evBIzjrxpl4m9Y9+R6ANTTIJdwylr82bALD+I62ZVhsLXF1+dlKaAY3xrGh/QjHGh6ZStrrc/DxyOZhV7KrpNYf2lLTxWWf8hIbNfYkwjGjxG/vfjvKZi6YVW9pPnj6YR2XivJ/BPrBjsnB/MErEkfyhqICf0WMyW9yaJzPLGCB+Q9PCJhevWRRySNMnW29yvtyMBcvcVtQT54vXgyAVfdywMhfw9rq0LEG0cabTP4VhPv2ama03fpCE0GaLp8Dp66eV0ZfS7MjBgMvFyKGDa/g1c0s3GE33XsafL7D2FZIoOqcgljAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 0.640522312679424$"
- ],
- "text/plain": [
- "0.6405223126794245"
- ]
- },
- "execution_count": 55,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).theta"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 56,
- "id": "peripheral-script",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle 1.10358684156015$"
- ],
- "text/plain": [
- "1.103586841560145"
- ]
- },
- "execution_count": 56,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).eta"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "caroline-capability",
- "metadata": {},
- "source": [
- "Some properties are not coordinates, but derived from them."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "id": "stretch-knife",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/latex": [
- "$\\displaystyle 0.801783725737273$"
- ],
- "text/plain": [
- "0.8017837257372732"
- ]
- },
- "execution_count": 57,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).costheta"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "id": "bearing-protein",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAAPCAYAAABjhcQWAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGj0lEQVRoBdWa7XEUORCGB5cDML4I4DIAk4HJAI4IgAyg+Od/LsgAiICPDIAI+MgALoI7nIHvebTTUxqtZrfH1FXddZVWUutVq7vV6tGMfe3y8nL4VTo7O7uJjFPKW9oXvyrv35qPbrco32r59I/oH1P/kE/9f7Elped/3Z7D2IxR0cdj303RwOfwPwZmR32LsZcW8D3YBfzrvQH4zn1MHWvPYOP4O5i3aS8GN2PPZxOH4Q28WbAx/gmetgXftnR7U5XftC3I0keh906fjes+q9YR/w5+17/w99mT1TOLG1gzbY92gHfPg45pPIR3EYxezbj6TPtdAhCmznhKHc4caN+D94H6PuV9T1jFu0NbR5YsUvFtmhmfNry6a3BFQBQ+66nPa8rflBOKjukSWMeUof5lM6ntW36n1KQ8SSeoq3adg6+dlrKFOWt95mGe/Mu6A30D8Igy+Zd21p6UniyTwqkH2FQMjNiv4E04L6gHan36J7WJohcHwqTZfkcGfMTAIyYacOGMOJme2uApoEvMu9sOwCuBU8mcQeA/mTHGDnwD4r7dEaNxS6RBZrvQV5zO7DnhG7giV9ASgcnYkvYZ8sS6YS09hPGJUvs3bU9SzyGJS9uDviYHry0l+Gi7hr79QtOsuOW/EbO13wcOQGYgN91SCGFTO3g76s8LY1unPnDIN6hma8ZYtkaGWVo5r+o58O9aat6KdtaWNT4zE+/VZ6U9WT2zuDX26PfuAYd/ih1Hrb/hdfc7HsFmj9kdbXSGcurnfCu39MHWJzh43mHOuxM2zAfMm6X8HdilIR9p3i/XHJYlWYWftQXcGp8ZBE+Y84HaK03oq49q/6btWaFnam+y9oCL4IrrTPHb+PPXWHttqp9Isrv7HY/gcd6mYhHvbTrHy+Isu8yACx3m+Oj1jbN794NvKq4dvyBpL1tDfyDP0/WAogPMNrsu9z5qdOJvFPX0Dujp7xJjO22JSeAWfcbYewtYM8dP2vpFPesrD91y311lj5MkZGb1zOK69rCOB94lj/1pSJ9KrjER+MX9PpxQNAC6kS7sxdVN8Zl+FTJ4LVvEGiqnEb0UvoXfw4jTeIK8Kdhpu8m+kbWnX/z0qYhxdflO7SO7PbGx9KItApiX8hk4M5+HzgOgTO1vfbTWHkRMtFPPCbVZs113Gk7ao1+Nk5b0hRR2DMjbud8HG/zmF7AXyRcUL+pvKF9pe2rTBN4FvQcsbeiVsmqrAPLDSDNtm6Xfgn9dYcp0+gbaRciibRCoZzcbM77PlgFMymfg9KNrm/lcU9kGf/Ev9Wp7mF+IuXv1FJjBgcnY48uT8qYgpG3whW/r5LJzvw8U1CMEGuUKLJ8KepgFnveYWoEJhkxPf3ezJ9D6Rm8t3zjd0JOEOOffRDc3saVFW1qg/SWfjXYb/N55fcT6QhJv4+1BuYo9WT2zuGIeenZjAL5xcUMbaHu3NaPqv3jhKTbA37vfJQABmkUifSJnoi9ja4r0aWS54YneuqAiXwX95tVz8LK0hRHkxGmLuoecggq8963ep5CYZ8C21LVFELLW+MwNmq4I43w312zouqfICzuiFtbSZE8zsKhnFrfSHu33GmV284npwdKeuAN6yFL7fTgqWDaGSdcpuxzQ2DPvMldnunDvUi//Dph381mDgW8Gkq/is41qsG03HmUtP/p1sJsNtw4GvGPBrDvTmf4uW5yS8tkox4O35Vd42uvGFR2o19ijDgPz9+mZxaXsKcKWf9zLj+hkcOrvvfsdAahzysRGtkIkHZOhwG9tNAopY0sO/J/yqeORlFknMD7O24B2zD+t6YR6vVf0e8Ftdq9xzpcWbdkMDymfsaZ6WDxk9YEYxZQMGOuvsSfm79Mzi0vZozDsuEflx+gbtJ0n74hKX+p7+9oUdskqBH+23wcj343xG9VEAF1EoabZaRHal5SlR5l4qeA3zb2/zol5PXCk9cgSEwY9zB4G7/RWR1tZf1DKRXkCc/dkbHb/pB9f5nvBHzpdVDLqZspn4wTlb92lWd87kleDuDOtsSd02adnFrfGHp9mbZIxERgrsydJLF7V6hs6D9fiv2GYaPTWG+Ei/iVjFsX0v8N3073QzgiecwzO3ieQFmswiHddSed/Rkb8bTEym+MqrGFulBs2e+ulbwCGUQbqObwtR8BzvciC4nSi95cL6hmN2J22gEn5TMFgfTw9o7hmUPd7JdiUPQoBm/J5BgdmjT1x6MPvXVvCUGR39/sfJSjLdCEK2OMAAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle 3.74165738677394$"
- ],
- "text/plain": [
- "3.7416573867739413"
- ]
- },
- "execution_count": 58,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).mag # spatial magnitude"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 59,
- "id": "green-crack",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAOCAYAAADNGCeJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA8klEQVQ4EaWT7Q2CQAyGxTAA0Q0YwY8NXMG4gWzgb9ZQR9ANZAMTR2AEZQN8XnJNPJBwaJOmvV7vufY+orquJyZ5ni/wL+gSv7J4n3X5GTZTToyTYM/oE12hKRoq2vhhyYKpgq0C+AeMqhsUl+vlTb1R4ACQNlQR3lH8BAOyA3hq7z0a5to7tkEaj4IBSllTYcu/YQD0DDrtGTi4MiB7Fn1tbxTMtZf0tWew2JwBq7NaA9Mj/RQ9kdTFyyAYyQWLpJ4QfxEosM2jb5/Z3GXPvFX9A31FaSORPjpkK39DVJP6b7r+G3Od2yOmi1Drypdc0fsbefVKjEhUk9oAAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle 14$"
- ],
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 59,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).mag2 # spatial magnitude squared"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "adjustable-serum",
- "metadata": {},
- "source": [
- "These properties are provided because they can be computed faster or with more numerical stability in different coordinate systems. For instance, the magnitude ignores `phi` in polar coordinates."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 60,
- "id": "amber-disco",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPCAYAAAAGRPQsAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABjUlEQVQ4EY2TMVICQRBFF/UAK56AJTVCzQnwBmpmqjeQMoLM0htAaCiGZmgViSHcAI5gkRniewMDy7JW0VV/u/t3T09vz0yyWCySfdHpdBrFXLgUZPJHCdLtdjNUWxs5Bz+gDT+RyMkXXIofeW3lzM8hsFCPpJtms/kB+qPR6BTuFf2NP8MOgn+HUQE18AvewS1r5+jQ2TP6XicKQbty4QAcRx49gb/O+VvmAV4LTEmKLceET4wU3s73Eou5aMai0GrJquImJSlLquIplAnFp/AZ2hkFwfa3h8ANToBdP8GHA7GzHSHYgDQxnnDMscgb8RdgTIyxHVVSese4N1MwKN6pMp+8ofnGdjpjlx57OMN/Ty10sfl4dRxHtlUMwutQRV9ucpcW3BCMi3zOT9fFSLwiUEevO8IOO64W+DLKTrZqnNxJKIbhwC/QxYG7gU9L6ROvL82tr8P3eiUVhpehPe5ASOakFQugzfNlrF8L9gPcI6hhzy0W7lOuQN70+YRHLIkdCq4S/D27doO53B+ljuuToylupQAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 25$"
- ],
- "text/plain": [
- "25"
- ]
- },
- "execution_count": 60,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=3, phi=0.123456789, z=4).mag2"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "interpreted-intensity",
- "metadata": {},
- "source": [
- "Momentum vectors have geometrical properties as well as their momentum-synonyms."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "id": "latest-thunder",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABkAAAAPCAYAAAARZmTlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABjElEQVQ4Ea2U723CQAzFU9QBItgg3QDaDdIN2m5QukH5mHyrwgYwQmED0gkQbAAbgNgg/b3kjEKUP1VUSy/ne2efz/blvCzLvCiKxhrLgPNBUOb66vdeIT9xHPuoezeXLpkUQ/cX/8RZnRgfQAJ3FDfQBzmDCxgDBViDCUbiOgW7HUZbxhmYo8/ABj3InVUCyrLqWwp8p+BQ9YdLwEa8ZZIH7Pl5xc/KXN5iyyQkG/8/goRspnJXJe8HZGiN94g4hVA/RkC1/IKrOyFLhbAu+y4ZWiYy/sZpDtQ0YYeuU7bJ0C22XZCiXGz2DK6G6Eo1BYu2CH9cG1kmdfYKFBBQpWuSul6YrWV5GrCJ7rPueZM01h0/y77OxrijMnkERpQD5Sdho9bm46Cy1mVrmaQKsmQjPQNVUdO1QZesMNBBq6Inaa9sFWSBctNg5p/OQz9aLnA+yMBNaZkvMTgzvjhTD12VeQPv4u7020MqXV1bidJUQ/UOXUSYMD+gp4wfxmlkrk31QMpeD+QTuP5nv4JEA14+QuryAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 5.0$"
- ],
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 61,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(px=3, py=4).rho"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 62,
- "id": "included-fireplace",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABkAAAAPCAYAAAARZmTlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABjElEQVQ4Ea2U723CQAzFU9QBItgg3QDaDdIN2m5QukH5mHyrwgYwQmED0gkQbAAbgNgg/b3kjEKUP1VUSy/ne2efz/blvCzLvCiKxhrLgPNBUOb66vdeIT9xHPuoezeXLpkUQ/cX/8RZnRgfQAJ3FDfQBzmDCxgDBViDCUbiOgW7HUZbxhmYo8/ABj3InVUCyrLqWwp8p+BQ9YdLwEa8ZZIH7Pl5xc/KXN5iyyQkG/8/goRspnJXJe8HZGiN94g4hVA/RkC1/IKrOyFLhbAu+y4ZWiYy/sZpDtQ0YYeuU7bJ0C22XZCiXGz2DK6G6Eo1BYu2CH9cG1kmdfYKFBBQpWuSul6YrWV5GrCJ7rPueZM01h0/y77OxrijMnkERpQD5Sdho9bm46Cy1mVrmaQKsmQjPQNVUdO1QZesMNBBq6Inaa9sFWSBctNg5p/OQz9aLnA+yMBNaZkvMTgzvjhTD12VeQPv4u7020MqXV1bidJUQ/UOXUSYMD+gp4wfxmlkrk31QMpeD+QTuP5nv4JEA14+QuryAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 5.0$"
- ],
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 62,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(px=3, py=4).pt"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 63,
- "id": "analyzed-andrews",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJQAAAAPCAYAAAACneZUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFbUlEQVRoBe2a35XVNhCHDWcLWEgH0AGwHWw6CKECoIPk5G3fONBBoAL+dJCkAgIdQAeB7WDzfbqWIsuyr2TvCS/MObqSR6PfjDSjkezdG1dXV8N36l+Bi4uLe5SP+UieT3m+Tf0553+rNnbcQfc55Q3ty//DjpNcCUrv8fyWcn+PASPOU+qnOX5s9+pZwoPvgv064j6g/uIz/Imjx/5QHdM9Yka7DRB1PIf/Z45D+y949kddtqX7h2r+i/zzgvsaXhw/0G6ezyh7zE79+bsF+UJ1eLyEf8tWI94EgzGzeDmB6UK8ougMneKk9pJBmRZKsJ16anja6UL9KL5EW4d9kEdJAUC7aY6jnAEZHTXQ/gnMP6gfUt6pZyTXS3JRzUj2PUPmknpC8LTVOYgd7KL22XKXMowyPfNpsfMMaPXVMqaZK2xGdLs+LXjaubqWBpQL8JCi8C9ULtBmGjFm47fqWcJDgcGTHK9CZF2UJzR1VNh5I791jo59AoYBFIMnBuZv9EWesB+RCevmwxHSHrNRxFJcx+SObp4P45rtRGfacCqV4IWkQR3n04O3upY3Dyqu5xcDDUYVWnbTETx32CdkdExOOu0Ufli0vKOhbVad2A/Orrkw3gznurzM9cM3i+bO7plPq53vc51Z2yM834yteBlEvXlSZ2/mPsLQSercjHQYuIZn4HgxXnJ4GWhHTQFLzJTZHADPgJC8i2whHeddZcnOiNk8n1Y7kYsZKOoY4JkJnyUGDXjXNu9rCyiM8rjcuuj5/EL7GB79S8dNOLLpd9ftIjDMGuEooj3JMALD86gwcH+gmBG9Q5V6vZd+hq9djyj/ULw3vYWnIwPR3jwfxq7amenQRjdhfJGJXZO6FW8yaHy4loDCAA11F+Z3gpq+Jt5WPMbpNG1ZXbBjRow4OumMYoD8XRljIKXX8dFmj+DJCwEyMVM+oC/ZRfsr5TFllkWiLvpW5zP2H7Mzwlm7OSxV2oA3w7k542xj+IlgtoO3QYVRW/G8/L7Dlhc7dA+M98L9gmLWeE3xzTEefQGaZwMnHWO03UxmnJSl4cVgMiuU6/MG2VeZTMAtflbnw9ijdkY8ZN1o59QpK8a+WPfgxTFlvTugMMK0nxaxVND7vBWPcdrg0bJ0dPSaEuTBM4MYOB5RMUCWsAyqO8jpvJxqmfsDAuJ5JM4IjK75NNjpXa5mx0y3jAa86rhdAYVSF843qmZDq1aMzK14jDOo/UKdvzWtqar2Md5MEu5ghUA88jxeBmT8rGBALFEIPGQMRCnWh6fpbxl84q/Oh/4mO6dqBjPsl4IXHjfi1aCGvXcoF+MMg0zNOYWzf+SbNdLdIReqtLvxwHah7lKnzEQ7OIm6N9BDkDDuFmUtCMwqNefcdk6MzS/mHjGzoFFupImNjG2ZT6udQQWYBrg25HaN6kPVhZcPLNu7AgpDXazZmQz/q3zq5ORSce25Fw95A9eALgNWp5R3lprKkmcQaXcZTAaQFOf6sqLTfjNYlPFZ8ugqN5x8/0Tji0ySp906n1Y71SNF+2ubwP5ePMdUqQwoX38ld9pkUZnsKTwDxYvg4t+r6JeUtSzRop6FATM8bHDH6SgDoLzDncNbupiv6S4DcwDH4FS/LwqX1JJ/IrGkj4O0/WwiTTYRfF8StNGPiQGfWryfKY8dIMHrmU+rnQfw/3wR7Y/8WPfixXGztbzhfxswmbiD3GFO1tRoKvaukHY67U/wXJy0kDwngq9jXRhxJC+07+EH51I36Qkj+VnDo09b1FWjWdC36kZO2/OgUIfBkDKJCnmWHx3hBnT3+1G36jT4vq67tpLyk29W9PfOp8lOlYGtrR5ri58pkOnBW/Tjv+UeF7RHL5lRAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 1.4142135623731$"
- ],
- "text/plain": [
- "1.4142135623730951"
- ]
- },
- "execution_count": 63,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3, E=4).tau"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 64,
- "id": "declared-yeast",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJQAAAAPCAYAAAACneZUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFbUlEQVRoBe2a35XVNhCHDWcLWEgH0AGwHWw6CKECoIPk5G3fONBBoAL+dJCkAgIdQAeB7WDzfbqWIsuyr2TvCS/MObqSR6PfjDSjkezdG1dXV8N36l+Bi4uLe5SP+UieT3m+Tf0553+rNnbcQfc55Q3ty//DjpNcCUrv8fyWcn+PASPOU+qnOX5s9+pZwoPvgv064j6g/uIz/Imjx/5QHdM9Yka7DRB1PIf/Z45D+y949kddtqX7h2r+i/zzgvsaXhw/0G6ezyh7zE79+bsF+UJ1eLyEf8tWI94EgzGzeDmB6UK8ougMneKk9pJBmRZKsJ16anja6UL9KL5EW4d9kEdJAUC7aY6jnAEZHTXQ/gnMP6gfUt6pZyTXS3JRzUj2PUPmknpC8LTVOYgd7KL22XKXMowyPfNpsfMMaPXVMqaZK2xGdLs+LXjaubqWBpQL8JCi8C9ULtBmGjFm47fqWcJDgcGTHK9CZF2UJzR1VNh5I791jo59AoYBFIMnBuZv9EWesB+RCevmwxHSHrNRxFJcx+SObp4P45rtRGfacCqV4IWkQR3n04O3upY3Dyqu5xcDDUYVWnbTETx32CdkdExOOu0Ufli0vKOhbVad2A/Orrkw3gznurzM9cM3i+bO7plPq53vc51Z2yM834yteBlEvXlSZ2/mPsLQSercjHQYuIZn4HgxXnJ4GWhHTQFLzJTZHADPgJC8i2whHeddZcnOiNk8n1Y7kYsZKOoY4JkJnyUGDXjXNu9rCyiM8rjcuuj5/EL7GB79S8dNOLLpd9ftIjDMGuEooj3JMALD86gwcH+gmBG9Q5V6vZd+hq9djyj/ULw3vYWnIwPR3jwfxq7amenQRjdhfJGJXZO6FW8yaHy4loDCAA11F+Z3gpq+Jt5WPMbpNG1ZXbBjRow4OumMYoD8XRljIKXX8dFmj+DJCwEyMVM+oC/ZRfsr5TFllkWiLvpW5zP2H7Mzwlm7OSxV2oA3w7k542xj+IlgtoO3QYVRW/G8/L7Dlhc7dA+M98L9gmLWeE3xzTEefQGaZwMnHWO03UxmnJSl4cVgMiuU6/MG2VeZTMAtflbnw9ijdkY8ZN1o59QpK8a+WPfgxTFlvTugMMK0nxaxVND7vBWPcdrg0bJ0dPSaEuTBM4MYOB5RMUCWsAyqO8jpvJxqmfsDAuJ5JM4IjK75NNjpXa5mx0y3jAa86rhdAYVSF843qmZDq1aMzK14jDOo/UKdvzWtqar2Md5MEu5ghUA88jxeBmT8rGBALFEIPGQMRCnWh6fpbxl84q/Oh/4mO6dqBjPsl4IXHjfi1aCGvXcoF+MMg0zNOYWzf+SbNdLdIReqtLvxwHah7lKnzEQ7OIm6N9BDkDDuFmUtCMwqNefcdk6MzS/mHjGzoFFupImNjG2ZT6udQQWYBrg25HaN6kPVhZcPLNu7AgpDXazZmQz/q3zq5ORSce25Fw95A9eALgNWp5R3lprKkmcQaXcZTAaQFOf6sqLTfjNYlPFZ8ugqN5x8/0Tji0ySp906n1Y71SNF+2ubwP5ePMdUqQwoX38ld9pkUZnsKTwDxYvg4t+r6JeUtSzRop6FATM8bHDH6SgDoLzDncNbupiv6S4DcwDH4FS/LwqX1JJ/IrGkj4O0/WwiTTYRfF8StNGPiQGfWryfKY8dIMHrmU+rnQfw/3wR7Y/8WPfixXGztbzhfxswmbiD3GFO1tRoKvaukHY67U/wXJy0kDwngq9jXRhxJC+07+EH51I36Qkj+VnDo09b1FWjWdC36kZO2/OgUIfBkDKJCnmWHx3hBnT3+1G36jT4vq67tpLyk29W9PfOp8lOlYGtrR5ri58pkOnBW/Tjv+UeF7RHL5lRAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 1.4142135623731$"
- ],
- "text/plain": [
- "1.4142135623730951"
- ]
- },
- "execution_count": 64,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3, E=4).mass"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "alpine-investor",
- "metadata": {},
- "source": [
- "Here's the key thing: _arrays of vectors return arrays of coordinates_."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 65,
- "id": "attempted-country",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "array([1.50363023, 1.50363023, 1.50363023, 1.50363023, 1.50363023])"
- ]
- },
- "execution_count": 65,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.array(\n",
- " {\n",
- " \"x\": [1.0, 2.0, 3.0, 4.0, 5.0],\n",
- " \"y\": [1.1, 2.2, 3.3, 4.4, 5.5],\n",
- " \"z\": [0.1, 0.2, 0.3, 0.4, 0.5],\n",
- " }\n",
- ").theta"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 66,
- "id": "consecutive-attempt",
- "metadata": {},
- "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": [
- ""
- ]
- },
- "execution_count": 66,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.Array(\n",
- " [\n",
- " [{\"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, \"z\": 0.5}],\n",
- " ]\n",
- ").theta"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 67,
- "id": "latin-channels",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "MomentumNumpy3D([[[( 0.13260391, 0.2601781 , 1.04694552),\n",
- " (-0.26319529, -0.77320792, -0.99130649)],\n",
- " [( 0.01667648, 0.29866905, 0.18466902),\n",
- " ( 1.34383037, -0.10881989, -0.49760439)],\n",
- " [( 2.03530493, 0.11366079, -0.82173533),\n",
- " (-0.31129007, -1.84168638, -0.16826771)],\n",
- " [( 1.58952081, 0.67672986, 0.39419798),\n",
- " (-0.34309328, 1.22834158, -0.45125405)],\n",
- " [(-0.39677479, 0.89203262, 0.62427518),\n",
- " (-0.51305815, -1.06523853, 0.51476415)]],\n",
- "\n",
- " [[( 0.62534261, 2.19809954, -1.74075339),\n",
- " (-0.5823244 , -0.29312602, -0.43676964)],\n",
- " [(-3.15626856, 0.11091443, 1.59055725),\n",
- " (-1.51497505, 0.73573103, 0.11611239)],\n",
- " [(-1.10585758, -1.3744337 , -0.45652228),\n",
- " ( 0.74772884, 0.33616902, 0.16559539)],\n",
- " [( 1.68097067, -1.74999875, -0.09875288),\n",
- " (-1.4415149 , 0.19554285, -0.41443723)],\n",
- " [(-0.88453411, -0.43962161, -1.144978 ),\n",
- " (-0.70646718, 1.0279956 , 0.15112694)]],\n",
- "\n",
- " [[(-0.167228 , -1.14624761, 0.37325173),\n",
- " ( 0.03890062, -0.25074582, 0.75658396)],\n",
- " [( 1.24646773, 0.84040834, 0.70366236),\n",
- " (-0.93898028, -1.63633977, -0.82303599)],\n",
- " [( 0.59744465, -0.56592375, 1.73794445),\n",
- " ( 0.09641971, -0.58255055, 1.62074543)],\n",
- " [(-0.28663052, 0.3644517 , 1.246621 ),\n",
- " (-0.04809795, -0.50406828, 1.47166047)],\n",
- " [(-0.34240645, 0.47174417, 0.87089676),\n",
- " ( 1.66574864, 0.18921741, 0.39070562)]],\n",
- "\n",
- " [[( 0.00878644, -1.62536013, -0.42163486),\n",
- " ( 0.46505462, 0.02231124, 1.01025727)],\n",
- " [( 0.40799765, 1.03055286, -1.67387635),\n",
- " (-0.6960781 , 1.34294937, -0.05646045)],\n",
- " [( 0.7966022 , 0.8646252 , -0.37478019),\n",
- " (-1.59930401, 0.34685381, -0.89294171)],\n",
- " [( 0.59402505, 0.98172123, 0.78361029),\n",
- " ( 0.8967682 , 0.75803473, -1.61971293)],\n",
- " [(-0.00343387, 0.91582888, 1.00745774),\n",
- " ( 0.38013935, 0.37748105, 0.61506312)]],\n",
- "\n",
- " [[( 0.86241151, -0.79418385, -1.46392439),\n",
- " ( 0.12601623, -1.75780638, -0.53983752)],\n",
- " [(-0.82900978, -1.19255499, -1.09695779),\n",
- " ( 0.31537637, -0.78298955, 0.13288536)],\n",
- " [( 1.51532109, -1.17606172, -1.21292931),\n",
- " (-0.23002288, -0.20392714, -0.13550909)],\n",
- " [(-1.41126192, 1.00526992, 1.16169235),\n",
- " (-3.41913823, 0.75890305, -2.06607514)],\n",
- " [(-1.09784888, 0.53826587, -1.09363904),\n",
- " ( 0.47498744, 0.27155865, 0.87275119)]]],\n",
- " dtype=[('x', '[[{x: 0.0952, y: 2.35, z: -0.225}, {x: 1.12, y: -0.0102, z: 0.648}],\n",
- " [{x: 0.626, y: -0.231, z: -1.15}, {...}, {x: 0.232, y: 0.773, z: 0.321}],\n",
- " [{x: 0.153, y: 0.854, z: 1.62}, {...}, ..., {x: -1.03, y: -0.0817, z: 1.32}],\n",
- " [{x: -0.0757, y: -0.717, z: 0.0196}],\n",
- " [{x: -0.0664, y: -0.5, z: -0.732}, ..., {x: -0.682, y: 0.555, z: -1.15}],\n",
- " [{x: 0.231, y: -0.166, z: -0.19}],\n",
- " [{x: -0.26, y: 0.0152, z: -0.469}, {x: -0.807, y: 1.39, z: 0.51}],\n",
- " [{x: -0.982, y: 2.04, z: -0.788}],\n",
- " [{x: -0.601, y: -1.39, z: -0.962}],\n",
- " [{x: 0.365, y: -0.684, z: 0.384}],\n",
- " ...,\n",
- " [{x: 1.09, y: -0.864, z: 0.556}, {x: 0.166, y: -0.0708, z: 0.728}],\n",
- " [{x: 1.47, y: 1.26, z: -2.5}, {x: 1.17, y: 0.418, z: 0.31}],\n",
- " [],\n",
- " [{x: 0.681, y: 0.755, z: 0.631}],\n",
- " [{x: -0.795, y: -0.883, z: -0.861}, {x: 0.418, y: 1.04, z: 0.172}],\n",
- " [{x: -0.176, y: 0.133, z: -0.34}],\n",
- " [{x: -0.307, y: 0.661, z: 0.976}, {x: 0.911, y: -1.2, z: 1.2}],\n",
- " [{x: 1.76, y: 0.317, z: -0.544}, {x: -0.691, y: -0.761, z: -0.992}],\n",
- " [{x: -0.71, y: 0.624, z: -0.0189}, {...}, ..., {x: -1.11, y: 0.629, z: 1.26}]]\n",
- "-------------------------------------------------------------------------------\n",
- "type: 50 * var * Momentum3D[\n",
- " x: float64,\n",
- " y: float64,\n",
- " z: float64\n",
- "]"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 71,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Make a large, random Awkward Array of 3D momentum vectors.\n",
- "array = vector.Array(\n",
- " [\n",
- " [\n",
- " {x: np.random.normal(0, 1) for x in (\"px\", \"py\", \"pz\")}\n",
- " for inner in range(np.random.poisson(1.5))\n",
- " ]\n",
- " for outer in range(50)\n",
- " ]\n",
- ")\n",
- "array"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 72,
- "id": "conditional-modeling",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[2.35, 1.12],\n",
- " [0.668, 0.985, 0.807],\n",
- " [0.868, 0.321, 0.209, 1.04],\n",
- " [0.721],\n",
- " [0.505, 0.661, 0.426, 0.879],\n",
- " [0.285],\n",
- " [0.26, 1.61],\n",
- " [2.26],\n",
- " [1.52],\n",
- " [0.775],\n",
- " ...,\n",
- " [1.39, 0.181],\n",
- " [1.94, 1.24],\n",
- " [],\n",
- " [1.02],\n",
- " [1.19, 1.12],\n",
- " [0.22],\n",
- " [0.729, 1.51],\n",
- " [1.78, 1.03],\n",
- " [0.945, 0.514, 2.46, 1.27]]\n",
- "------------------------------\n",
- "type: 50 * var * float64
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 72,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Get the transverse momentum of each one, in the same nested structure.\n",
- "array.pt"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 73,
- "id": "general-october",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[2,\n",
- " 3,\n",
- " 4,\n",
- " 1,\n",
- " 4,\n",
- " 1,\n",
- " 2,\n",
- " 1,\n",
- " 1,\n",
- " 1,\n",
- " ...,\n",
- " 2,\n",
- " 2,\n",
- " 0,\n",
- " 1,\n",
- " 2,\n",
- " 1,\n",
- " 2,\n",
- " 2,\n",
- " 4]\n",
- "----------------\n",
- "type: 50 * int64
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 73,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# The array and its components have the same list lengths (and can therefore be used together in subsequent calculations).\n",
- "ak.num(array)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 74,
- "id": "ongoing-rally",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[2,\n",
- " 3,\n",
- " 4,\n",
- " 1,\n",
- " 4,\n",
- " 1,\n",
- " 2,\n",
- " 1,\n",
- " 1,\n",
- " 1,\n",
- " ...,\n",
- " 2,\n",
- " 2,\n",
- " 0,\n",
- " 1,\n",
- " 2,\n",
- " 1,\n",
- " 2,\n",
- " 2,\n",
- " 4]\n",
- "----------------\n",
- "type: 50 * int64
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 74,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ak.num(array.pt)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "brown-blood",
- "metadata": {},
- "source": [
- "## Vector methods\n",
- "\n",
- "Vector methods require arguments (in parentheses), which may be scalars or other vectors, depending on the calculation."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 75,
- "id": "unique-trance",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=2.585678829246765, y=4.279516911052588)"
- ]
- },
- "execution_count": 75,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4).rotateZ(0.1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 76,
- "id": "pharmaceutical-notebook",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(rho=5, phi=0.5)"
- ]
- },
- "execution_count": 76,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.4).rotateZ(0.1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 77,
- "id": "approved-ancient",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[(1., 0.6) (2., 0.7) (3., 0.8) (4., 0.9) (5., 1. )]\n"
- ]
- }
- ],
- "source": [
- "# Broadcasts a scalar rotation angle of 0.5 to all elements of the NumPy array.\n",
- "print(\n",
- " vector.array({\"rho\": [1, 2, 3, 4, 5], \"phi\": [0.1, 0.2, 0.3, 0.4, 0.5]}).rotateZ(\n",
- " 0.5\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 78,
- "id": "derived-lincoln",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[(1., 0.2) (2., 0.4) (3., 0.6) (4., 0.8) (5., 1. )]\n"
- ]
- }
- ],
- "source": [
- "# Matches each rotation angle to an element of the NumPy array.\n",
- "print(\n",
- " vector.array({\"rho\": [1, 2, 3, 4, 5], \"phi\": [0.1, 0.2, 0.3, 0.4, 0.5]}).rotateZ(\n",
- " np.array([0.1, 0.2, 0.3, 0.4, 0.5])\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 79,
- "id": "dangerous-effect",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[[{rho: 1, phi: 0.6}, {rho: 2, phi: 0.7}], [], [{rho: 3, phi: 0.8}]]\n"
- ]
- }
- ],
- "source": [
- "# Broadcasts a scalar rotation angle of 0.5 to all elements of the Awkward Array.\n",
- "print(\n",
- " vector.Array(\n",
- " [[{\"rho\": 1, \"phi\": 0.1}, {\"rho\": 2, \"phi\": 0.2}], [], [{\"rho\": 3, \"phi\": 0.3}]]\n",
- " ).rotateZ(0.5)\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 80,
- "id": "weird-insert",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[[{rho: 1, phi: 0.2}, {rho: 2, phi: 0.3}], [], [{rho: 3, phi: 0.6}]]\n"
- ]
- }
- ],
- "source": [
- "# Broadcasts a rotation angle of 0.1 to both elements of the first list, 0.2 to the empty list, and 0.3 to the only element of the last list.\n",
- "print(\n",
- " vector.Array(\n",
- " [[{\"rho\": 1, \"phi\": 0.1}, {\"rho\": 2, \"phi\": 0.2}], [], [{\"rho\": 3, \"phi\": 0.3}]]\n",
- " ).rotateZ([0.1, 0.2, 0.3])\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 81,
- "id": "satellite-southeast",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[[{rho: 1, phi: 0.2}, {rho: 2, phi: 0.4}], [], [{rho: 3, phi: 0.6}]]\n"
- ]
- }
- ],
- "source": [
- "# Matches each rotation angle to an element of the Awkward Array.\n",
- "print(\n",
- " vector.Array(\n",
- " [[{\"rho\": 1, \"phi\": 0.1}, {\"rho\": 2, \"phi\": 0.2}], [], [{\"rho\": 3, \"phi\": 0.3}]]\n",
- " ).rotateZ([[0.1, 0.2], [], [0.3]])\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "animal-specific",
- "metadata": {},
- "source": [
- "Some methods are equivalent to binary operators."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 82,
- "id": "statutory-bathroom",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=30, y=40)"
- ]
- },
- "execution_count": 82,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4).scale(10)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 83,
- "id": "foreign-celebration",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=30, y=40)"
- ]
- },
- "execution_count": 83,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4) * 10"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 84,
- "id": "solved-resident",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=30, y=40)"
- ]
- },
- "execution_count": 84,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "10 * vector.obj(x=3, y=4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 85,
- "id": "comic-threshold",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(rho=50, phi=0.5)"
- ]
- },
- "execution_count": 85,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.5) * 10"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "novel-fancy",
- "metadata": {},
- "source": [
- "Some methods involve more than one vector."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 86,
- "id": "prescription-arkansas",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=6, y=7)"
- ]
- },
- "execution_count": 86,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2).add(vector.obj(x=5, y=5))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 87,
- "id": "sought-allah",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject2D(x=6, y=7)"
- ]
- },
- "execution_count": 87,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2) + vector.obj(x=5, y=5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 88,
- "id": "egyptian-nursing",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPCAYAAAAGRPQsAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABIUlEQVQ4Ea2T0W3CMBRFTcUAEd3AbAAdgY7QFToCfCZ/SGwA3QC6QdsRyAgdAXWD9BxDEIQgJVWvdOPnm+fr5D07VFUVujLP80kzFy2DUX0YLlAUxYTpDk6Jfy5e1eEXesakPAnGYupjeHr5RnyATzDCezBHuOk3fIfLemPN/IIXGIjnDCbeQ0lOym1LeGgT/6r9q9lVA7p8Eb/5Sp6Ff4TW15qlhvT9Mk22LF7BBbHcE88YQy8zFj1DG5ZAbEc/4Vqhl5kLWqBhxDh2NiP5A+5bzGop62zGCg+0NWtipMBGZR+zDQvGTSfmFt+63dTMdou02zE8P9eYpULXCnNvjEi3YuBtR/RyC3fxVzw3FtY6bRgTiCOBx0G4oXd1gZ46/AvpNYSy4bXeMQAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 15$"
- ],
- "text/plain": [
- "15"
- ]
- },
- "execution_count": 88,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2).dot(vector.obj(x=5, y=5))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 89,
- "id": "hourly-section",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPCAYAAAAGRPQsAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABIUlEQVQ4Ea2T0W3CMBRFTcUAEd3AbAAdgY7QFToCfCZ/SGwA3QC6QdsRyAgdAXWD9BxDEIQgJVWvdOPnm+fr5D07VFUVujLP80kzFy2DUX0YLlAUxYTpDk6Jfy5e1eEXesakPAnGYupjeHr5RnyATzDCezBHuOk3fIfLemPN/IIXGIjnDCbeQ0lOym1LeGgT/6r9q9lVA7p8Eb/5Sp6Ff4TW15qlhvT9Mk22LF7BBbHcE88YQy8zFj1DG5ZAbEc/4Vqhl5kLWqBhxDh2NiP5A+5bzGop62zGCg+0NWtipMBGZR+zDQvGTSfmFt+63dTMdou02zE8P9eYpULXCnNvjEi3YuBtR/RyC3fxVzw3FtY6bRgTiCOBx0G4oXd1gZ46/AvpNYSy4bXeMQAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 15$"
- ],
- "text/plain": [
- "15"
- ]
- },
- "execution_count": 89,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2) @ vector.obj(x=5, y=5)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "earned-precipitation",
- "metadata": {},
- "source": [
- "The vectors can use different coordinate systems. Conversions are necessary, but minimized for speed and numeric stability."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 90,
- "id": "unlike-melissa",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPCAYAAAAGRPQsAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABa0lEQVQ4EZWT0VHCUBBFI2MBGegAOwDtADtQO5AS5BP+HOgAShA7ACtgoAPpAIYO8JwkizHAZNyZm913s7u5b/Necjwek+Fw2NGXAZeCdpmri2+T3L5Go1FKuCnWxlo3d79P8sbFaoe/A2O4rVzDB7YHB9ABNvoEXZLkTsZ6zWKFH4AJ8QAsiNtZktLZzrxuC+T0wXc1D24MFvKhLGtc83jmfYyhnLpi0UNd+p9mPYocR9WyeUH24gckdO5DOK8WcAbvcJkSvHydNUOZyR8UTYBDFWti1WjN3GU/qQjPXL5Nih7B6c8RK30Jpmcl14lWKLuUYsM2jd3ypVlFTajeNUj2nHh+rlnK+1B9aXbBbVV2D4IoN8y+SKM4Dm5blVULZUubzSjwWlTN4dsgbE7gh6vmlduo3mZTgj+DZv1WVHhQM4ObEezxTwWVELujF/Aqd+M1gFS+x0FTtgP3/h0kwopiL7q8F/0BnM7jD7/71BequctZAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 50$"
- ],
- "text/plain": [
- "50"
- ]
- },
- "execution_count": 90,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4) @ vector.obj(x=6, y=8) # both are Cartesian, dot product is exact"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 91,
- "id": "seasonal-section",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAAOCAYAAACo2RezAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE3ElEQVRoBd2a3XEUORSFB8oBgDcCIIO1iWBNBlAbAZABlN/8ChnARuDCGWAi4CcDyGDNZOD9Pk1Lpe7WjG9XqV/2VsmSro6O1Oj0ldTDvdvb203LLi4u/sT/mvz1tB3fh8p3TPklvm3lO1iM9u+Nc1K9OaN8a4y9hFNsNubcXFv8j8G8HXCn5DfW8f8YfCXD94DKeXFsNtY/4b+ufBvqcmYNibH+LuPuHRDgT4A/AL4gT0ZZgu+kD5Tf6yT3Yb6QTij/0rfPaA/1741zPr05o3xrjL2EU+zUmHtrbRWG6/os4ym/o/yG9IzyVFhis7BSF+qfKFySX+kgd70VW8FRfo5P3AvKV/cpzIwGB23ZPziPaU/iE0DZt+MbqY6KNrUs2r83zrn05ozyrTH2Ek6xxQ6srWIrQrEDWKPhlqRgiuF/RcVANLWXOOqoKO4VeEWXLQs54WYCBGxEc1DT1CRqRTlFeEZfFX/Iov1745xTb84o3xpjL+EUm+yOtT0D9LOxhgrmAX4jZLYnFEqkzM5Gri5GWoJnpKuZAOnwN6CPU7JqYjfTNur/Dr7TRltyRfv3xjl4b84o3xpjL+EUO7Hm2g4YhfaLZxsJpOpfB5ev+J+D/Vz9Wwg1ipadkLZr0kNzGzXKvrhawo0ESKNbbyFIsOEPbXliXjqm9sfgqN+SESbavzfOSfTmjPKtMfYSTrHZmPPetRVDu2cyI9vU3BFtN5olo+wZz2TU/E39DUndKMhZ8MKfjDbxaavPuCJAHIpnS97aYncMu0FbIkuTBFS/JblPnTvpSP/eOOfQmzPKt8bYSzg3wbWVc2T0c11dr3wzLu20eTnNYlNUiquItAApyEPyBfCMKeYbKdn9XCD3k0smrNyjoodMCR0sGWUnmaPjIfGKj/bvjfu/jb3kecRG1lbc1Lx8XLHG5dKZAfjcSl13o6ZbrEL1DJm3WKo7w+fXlPckRXtJ+p5x6TMMFW8r7tdFQJS95XgmKJ9hqG+oG+VUvFd5t17PAw6uz08xzbeAtmTR/r1xDt6bM8q3xthRTuYYXls5s9HPLfUx+eyyMXC61uXWTFnhKVhF+Yh6DkpUx0bbbzzq6OERFcXjLaeIbwwf1wbiMrCt+BSfdidHtH9vnJPrzRnlW2PsCCfzW7S2cmr0U7R+bpuJLwF2webRUE4ZWCOl0dDA5A5pfXZ+TODdFizm7Ig/TvIpYNVbW9r/B7+RcHYOqMBijaB7VV9hW8Vo/94459KbM8q3xtgjTtbjFMeitaWPkewJedn5KKuRDbk6MHIZsGZrPbR7Nj4Wj6Vvhfi9Cc/wAo5ocP8u12SdGn7DpKKqJ+Lk/ABbQiztTkg1n5AOGthQ/944J9WbM8q3xthRTuYYXtuB05dHwU6DjeuW7ge0eVE1uT23djz1kPWk6FqB6RS/dm0E3GcSmWrzTbipHZSNnB5yy9mPsv0UsIfPWpih/vTrjYOyO2d0jmuMvYRT7NRma8s6+TyupYKZfoo7w1dfRAxK/u77F2mbySm7dfspJgtzKuQNbYrZ8dXMdvZbMM50+ARgVNMMqV/x599+83lPEm32A7RO8J4FfJh958W7+kfHCeGGOYWwzLkrbo2xl3CK1XiuvWtLm+ulCFs2DSRyGS3PSXVAmmkBnDoquyhlxyj/GeE/jw1TQEn/J88AAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle 49.9999999994283$"
- ],
- "text/plain": [
- "49.99999999942831"
- ]
- },
- "execution_count": 91,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273) @ vector.obj(\n",
- " x=6, y=8\n",
- ") # one is polar, dot product is approximate"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 92,
- "id": "second-joseph",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAAOCAYAAACo2RezAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE3ElEQVRoBd2a3XEUORSFB8oBgDcCIIO1iWBNBlAbAZABlN/8ChnARuDCGWAi4CcDyGDNZOD9Pk1Lpe7WjG9XqV/2VsmSro6O1Oj0ldTDvdvb203LLi4u/sT/mvz1tB3fh8p3TPklvm3lO1iM9u+Nc1K9OaN8a4y9hFNsNubcXFv8j8G8HXCn5DfW8f8YfCXD94DKeXFsNtY/4b+ufBvqcmYNibH+LuPuHRDgT4A/AL4gT0ZZgu+kD5Tf6yT3Yb6QTij/0rfPaA/1741zPr05o3xrjL2EU+zUmHtrbRWG6/os4ym/o/yG9IzyVFhis7BSF+qfKFySX+kgd70VW8FRfo5P3AvKV/cpzIwGB23ZPziPaU/iE0DZt+MbqY6KNrUs2r83zrn05ozyrTH2Ek6xxQ6srWIrQrEDWKPhlqRgiuF/RcVANLWXOOqoKO4VeEWXLQs54WYCBGxEc1DT1CRqRTlFeEZfFX/Iov1745xTb84o3xpjL+EUm+yOtT0D9LOxhgrmAX4jZLYnFEqkzM5Gri5GWoJnpKuZAOnwN6CPU7JqYjfTNur/Dr7TRltyRfv3xjl4b84o3xpjL+EUO7Hm2g4YhfaLZxsJpOpfB5ev+J+D/Vz9Wwg1ipadkLZr0kNzGzXKvrhawo0ESKNbbyFIsOEPbXliXjqm9sfgqN+SESbavzfOSfTmjPKtMfYSTrHZmPPetRVDu2cyI9vU3BFtN5olo+wZz2TU/E39DUndKMhZ8MKfjDbxaavPuCJAHIpnS97aYncMu0FbIkuTBFS/JblPnTvpSP/eOOfQmzPKt8bYSzg3wbWVc2T0c11dr3wzLu20eTnNYlNUiquItAApyEPyBfCMKeYbKdn9XCD3k0smrNyjoodMCR0sGWUnmaPjIfGKj/bvjfu/jb3kecRG1lbc1Lx8XLHG5dKZAfjcSl13o6ZbrEL1DJm3WKo7w+fXlPckRXtJ+p5x6TMMFW8r7tdFQJS95XgmKJ9hqG+oG+VUvFd5t17PAw6uz08xzbeAtmTR/r1xDt6bM8q3xthRTuYYXls5s9HPLfUx+eyyMXC61uXWTFnhKVhF+Yh6DkpUx0bbbzzq6OERFcXjLaeIbwwf1wbiMrCt+BSfdidHtH9vnJPrzRnlW2PsCCfzW7S2cmr0U7R+bpuJLwF2webRUE4ZWCOl0dDA5A5pfXZ+TODdFizm7Ig/TvIpYNVbW9r/B7+RcHYOqMBijaB7VV9hW8Vo/94459KbM8q3xtgjTtbjFMeitaWPkewJedn5KKuRDbk6MHIZsGZrPbR7Nj4Wj6Vvhfi9Cc/wAo5ocP8u12SdGn7DpKKqJ+Lk/ABbQiztTkg1n5AOGthQ/944J9WbM8q3xthRTuYYXtuB05dHwU6DjeuW7ge0eVE1uT23djz1kPWk6FqB6RS/dm0E3GcSmWrzTbipHZSNnB5yy9mPsv0UsIfPWpih/vTrjYOyO2d0jmuMvYRT7NRma8s6+TyupYKZfoo7w1dfRAxK/u77F2mbySm7dfspJgtzKuQNbYrZ8dXMdvZbMM50+ARgVNMMqV/x599+83lPEm32A7RO8J4FfJh958W7+kfHCeGGOYWwzLkrbo2xl3CK1XiuvWtLm+ulCFs2DSRyGS3PSXVAmmkBnDoquyhlxyj/GeE/jw1TQEn/J88AAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle 49.9999999994283$"
- ],
- "text/plain": [
- "49.99999999942831"
- ]
- },
- "execution_count": 92,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=3, y=4) @ vector.obj(\n",
- " rho=10, phi=0.9273\n",
- ") # one is polar, dot product is approximate"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 93,
- "id": "material-technician",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAACMAAAAPCAYAAABut3YUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAByElEQVRIDbWV7VHCQBCGI2MBjHSAHYB2gB2oHYgdyE/yzwkdQAliB2AFDHSAHcjQQXzekA3HGe7iOO7My+3u3X7c7nJJ8jxPxuNxT6sLdG3QdXX/zV8mB/pI07QNuyll8aL+YTn+ci4rpS/Wa5Ch+zyeCHMh+1ZpumPdgx5QIu+gj6F0FSGvEVasIzCBH4EFfLc6FGCi9io97ZjHWsCZIdj659BlYOHrfbmJvVUmcJ9q6wHO2lgpYVZgwK2tte6ey0ftf5PMAM9qp082L9oPUdTeBjjhZkM86XYdoBl4RVdUosGtOZ5c6aeOmtpbZZTEG0YToKEU1vB2Wwt0MtBe4FCbGtkXyRD0DlSB4FX6JZh6AUOiKvoX6lhl6pwooS6JqWV1s2I2dmu9O+eokX2LYHon9H6cozb7VrW6VpjOBvmHn6b2qswNMIeuo+LGOCqGmA21TVXyySqj/RBF7ZXMjIB61n3S8LoB5shK3Cd9MjbO7f19k6P2SmaKo5NBRX4pPeihKgjdDGbHel+qEnhV9BE8uTr0OThpPXLU/kLPNgdVfv2dRSq7Bk7fn70URsgKrg+l9BrYW1C9R/AFcW4Ls2R9LlWmD9p/AykpbfH0zMymAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 50.0$"
- ],
- "text/plain": [
- "50.0"
- ]
- },
- "execution_count": 93,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=5, phi=0.9273) @ vector.obj(\n",
- " rho=10, phi=0.9273\n",
- ") # both are polar, a formula that depends on phi differences is used"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "attractive-ebony",
- "metadata": {},
- "source": [
- "In Python, some \"operators\" are actually built-in functions, such as `abs`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 94,
- "id": "focal-tactics",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABkAAAAPCAYAAAARZmTlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABjElEQVQ4Ea2U723CQAzFU9QBItgg3QDaDdIN2m5QukH5mHyrwgYwQmED0gkQbAAbgNgg/b3kjEKUP1VUSy/ne2efz/blvCzLvCiKxhrLgPNBUOb66vdeIT9xHPuoezeXLpkUQ/cX/8RZnRgfQAJ3FDfQBzmDCxgDBViDCUbiOgW7HUZbxhmYo8/ABj3InVUCyrLqWwp8p+BQ9YdLwEa8ZZIH7Pl5xc/KXN5iyyQkG/8/goRspnJXJe8HZGiN94g4hVA/RkC1/IKrOyFLhbAu+y4ZWiYy/sZpDtQ0YYeuU7bJ0C22XZCiXGz2DK6G6Eo1BYu2CH9cG1kmdfYKFBBQpWuSul6YrWV5GrCJ7rPueZM01h0/y77OxrijMnkERpQD5Sdho9bm46Cy1mVrmaQKsmQjPQNVUdO1QZesMNBBq6Inaa9sFWSBctNg5p/OQz9aLnA+yMBNaZkvMTgzvjhTD12VeQPv4u7020MqXV1bidJUQ/UOXUSYMD+gp4wfxmlkrk31QMpeD+QTuP5nv4JEA14+QuryAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 5.0$"
- ],
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 94,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "abs(vector.obj(x=3, y=4))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "stone-resource",
- "metadata": {},
- "source": [
- "Note that `abs` returns\n",
- "\n",
- " * `rho` for 2D vectors\n",
- " * `mag` for 3D vectors\n",
- " * `tau` (`mass`) for 4D vectors\n",
- "\n",
- "Use the named properties when you want magnitude in a specific number of dimensions; use `abs` when you want the magnitude for any number of dimensions."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "shared-resolution",
- "metadata": {},
- "source": [
- "The vectors can be from different backends. Normal rules for broadcasting Python numbers, NumPy arrays, and Awkward Arrays apply."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 95,
- "id": "purple-disco",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorNumpy2D([(11., 5.1), (12., 5.2), (13., 5.3), (14., 5.4), (15., 5.5)],\n",
- " dtype=[('x', '[[{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": 96,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "(\n",
- " vector.Array(\n",
- " [ # an Awkward Array of vectors\n",
- " [{\"x\": 1, \"y\": 1.1}, {\"x\": 2, \"y\": 2.2}],\n",
- " [],\n",
- " [{\"x\": 3, \"y\": 3.3}],\n",
- " [{\"x\": 4, \"y\": 4.4}, {\"x\": 5, \"y\": 5.5}],\n",
- " ]\n",
- " )\n",
- " + vector.obj(x=10, y=5) # and a single vector object\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 97,
- "id": "empirical-starter",
- "metadata": {},
- "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": 97,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "(\n",
- " vector.Array(\n",
- " [ # an Awkward Array of vectors\n",
- " [{\"x\": 1, \"y\": 1.1}, {\"x\": 2, \"y\": 2.2}],\n",
- " [],\n",
- " [{\"x\": 3, \"y\": 3.3}],\n",
- " [{\"x\": 4, \"y\": 4.4}, {\"x\": 5, \"y\": 5.5}],\n",
- " ]\n",
- " )\n",
- " + vector.array(\n",
- " {\"x\": [4, 3, 2, 1], \"y\": [0.1, 0.1, 0.1, 0.1]}\n",
- " ) # and a NumPy array of vectors\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "pregnant-chest",
- "metadata": {},
- "source": [
- "Some operations are defined for 2D or 3D vectors, but are usable on higher-dimensional vectors because the additional components can be ignored or are passed through unaffected."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 98,
- "id": "blocked-keyboard",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOCAYAAAAxDQxDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABkElEQVQ4EY2U7U0CQRCGgVAAwQ6ODlQqEDrQFrQD/cs/gx1Qg3QgHah0AFYg0gE+z+bmclzWO99kM7PvzM7szH70T6dTL7BYLJal/o2cMJZw+7C3SfwK7E+lzzXy4Bx+K9ePRBCfzJ+Raw3IEUJujt6aDLtJVsg5MgHdTT8yXL8ZyKLcI0bIlKTkjkjnK+cdMOhD3YdYVmeMV/mUCHnHSCVK1vCOPmOR1bVhhnGX8dvAW0ARiXS0p01Ey7S3wYB7AlpBDqNhZhc5x3GODI4YdiSHS0nsWyuKIH/tRt+u1ulzBoKbpGCkmxitO3PKTC4yXBflJViT8EVHE+XORpuIan1X/wbBvameWdXSAZNoWa49wcWl6ExGPJ/KGFm9KRcNy5XeGvvZRFSkvRMEv8VpgqwqQU9x44zsp99GE1cQW5yj6qa9muPj4U+R8Q2FzeSH+he0g/Bvqn9BX3A3cOkxI23lD8PkbiIB3V2/MXKV++An0ToXuNBPdIr08JVVEvQetiPD8/pwXoNJTOb5NJE2+QsqvZDE0rxQTwAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 0.2$"
- ],
- "text/plain": [
- "0.20000000000000018"
- ]
- },
- "execution_count": 98,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=1, phi=0.5).deltaphi(\n",
- " vector.obj(rho=2, phi=0.3)\n",
- ") # deltaphi is a planar operation (defined on the transverse plane)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 99,
- "id": "exposed-pendant",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOCAYAAAAxDQxDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABkElEQVQ4EY2U7U0CQRCGgVAAwQ6ODlQqEDrQFrQD/cs/gx1Qg3QgHah0AFYg0gE+z+bmclzWO99kM7PvzM7szH70T6dTL7BYLJal/o2cMJZw+7C3SfwK7E+lzzXy4Bx+K9ePRBCfzJ+Raw3IEUJujt6aDLtJVsg5MgHdTT8yXL8ZyKLcI0bIlKTkjkjnK+cdMOhD3YdYVmeMV/mUCHnHSCVK1vCOPmOR1bVhhnGX8dvAW0ARiXS0p01Ey7S3wYB7AlpBDqNhZhc5x3GODI4YdiSHS0nsWyuKIH/tRt+u1ulzBoKbpGCkmxitO3PKTC4yXBflJViT8EVHE+XORpuIan1X/wbBvameWdXSAZNoWa49wcWl6ExGPJ/KGFm9KRcNy5XeGvvZRFSkvRMEv8VpgqwqQU9x44zsp99GE1cQW5yj6qa9muPj4U+R8Q2FzeSH+he0g/Bvqn9BX3A3cOkxI23lD8PkbiIB3V2/MXKV++An0ToXuNBPdIr08JVVEvQetiPD8/pwXoNJTOb5NJE2+QsqvZDE0rxQTwAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 0.2$"
- ],
- "text/plain": [
- "0.20000000000000018"
- ]
- },
- "execution_count": 99,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=1, phi=0.5, z=10).deltaphi(\n",
- " vector.obj(rho=2, phi=0.3, theta=1.4)\n",
- ") # but we can use it on 3D vectors"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 100,
- "id": "liked-depression",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOCAYAAAAxDQxDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABkElEQVQ4EY2U7U0CQRCGgVAAwQ6ODlQqEDrQFrQD/cs/gx1Qg3QgHah0AFYg0gE+z+bmclzWO99kM7PvzM7szH70T6dTL7BYLJal/o2cMJZw+7C3SfwK7E+lzzXy4Bx+K9ePRBCfzJ+Raw3IEUJujt6aDLtJVsg5MgHdTT8yXL8ZyKLcI0bIlKTkjkjnK+cdMOhD3YdYVmeMV/mUCHnHSCVK1vCOPmOR1bVhhnGX8dvAW0ARiXS0p01Ey7S3wYB7AlpBDqNhZhc5x3GODI4YdiSHS0nsWyuKIH/tRt+u1ulzBoKbpGCkmxitO3PKTC4yXBflJViT8EVHE+XORpuIan1X/wbBvameWdXSAZNoWa49wcWl6ExGPJ/KGFm9KRcNy5XeGvvZRFSkvRMEv8VpgqwqQU9x44zsp99GE1cQW5yj6qa9muPj4U+R8Q2FzeSH+he0g/Bvqn9BX3A3cOkxI23lD8PkbiIB3V2/MXKV++An0ToXuNBPdIr08JVVEvQetiPD8/pwXoNJTOb5NJE2+QsqvZDE0rxQTwAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 0.2$"
- ],
- "text/plain": [
- "0.20000000000000018"
- ]
- },
- "execution_count": 100,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=1, phi=0.5, z=10, t=100).deltaphi(\n",
- " vector.obj(rho=2, phi=0.3, theta=1.4, tau=1000)\n",
- ") # and 4D vectors"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 101,
- "id": "several-senator",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOCAYAAAAxDQxDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABkElEQVQ4EY2U7U0CQRCGgVAAwQ6ODlQqEDrQFrQD/cs/gx1Qg3QgHah0AFYg0gE+z+bmclzWO99kM7PvzM7szH70T6dTL7BYLJal/o2cMJZw+7C3SfwK7E+lzzXy4Bx+K9ePRBCfzJ+Raw3IEUJujt6aDLtJVsg5MgHdTT8yXL8ZyKLcI0bIlKTkjkjnK+cdMOhD3YdYVmeMV/mUCHnHSCVK1vCOPmOR1bVhhnGX8dvAW0ARiXS0p01Ey7S3wYB7AlpBDqNhZhc5x3GODI4YdiSHS0nsWyuKIH/tRt+u1ulzBoKbpGCkmxitO3PKTC4yXBflJViT8EVHE+XORpuIan1X/wbBvameWdXSAZNoWa49wcWl6ExGPJ/KGFm9KRcNy5XeGvvZRFSkvRMEv8VpgqwqQU9x44zsp99GE1cQW5yj6qa9muPj4U+R8Q2FzeSH+he0g/Bvqn9BX3A3cOkxI23lD8PkbiIB3V2/MXKV++An0ToXuNBPdIr08JVVEvQetiPD8/pwXoNJTOb5NJE2+QsqvZDE0rxQTwAAAABJRU5ErkJggg==",
- "text/latex": [
- "$\\displaystyle 0.2$"
- ],
- "text/plain": [
- "0.20000000000000018"
- ]
- },
- "execution_count": 101,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(rho=1, phi=0.5).deltaphi(\n",
- " vector.obj(rho=2, phi=0.3, theta=1.4, tau=1000)\n",
- ") # and mixed dimensionality"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "breathing-helicopter",
- "metadata": {},
- "source": [
- "This is especially useful for giving 4D vectors all the capabilities of 3D vectors."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 102,
- "id": "considerable-general",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject3D(x=1, y=-0.7071067811865472, z=3.5355339059327378)"
- ]
- },
- "execution_count": 102,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3).rotateX(np.pi / 4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 103,
- "id": "formed-fisher",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject4D(x=1, y=-0.7071067811865472, z=3.5355339059327378, tau=10)"
- ]
- },
- "execution_count": 103,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=1, y=2, z=3, tau=10).rotateX(np.pi / 4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 104,
- "id": "tribal-danger",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJQAAAAPCAYAAAACneZUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFbUlEQVRoBe2a35XVNhCHDWcLWEgH0AGwHWw6CKECoIPk5G3fONBBoAL+dJCkAgIdQAeB7WDzfbqWIsuyr2TvCS/MObqSR6PfjDSjkezdG1dXV8N36l+Bi4uLe5SP+UieT3m+Tf0553+rNnbcQfc55Q3ty//DjpNcCUrv8fyWcn+PASPOU+qnOX5s9+pZwoPvgv064j6g/uIz/Imjx/5QHdM9Yka7DRB1PIf/Z45D+y949kddtqX7h2r+i/zzgvsaXhw/0G6ezyh7zE79+bsF+UJ1eLyEf8tWI94EgzGzeDmB6UK8ougMneKk9pJBmRZKsJ16anja6UL9KL5EW4d9kEdJAUC7aY6jnAEZHTXQ/gnMP6gfUt6pZyTXS3JRzUj2PUPmknpC8LTVOYgd7KL22XKXMowyPfNpsfMMaPXVMqaZK2xGdLs+LXjaubqWBpQL8JCi8C9ULtBmGjFm47fqWcJDgcGTHK9CZF2UJzR1VNh5I791jo59AoYBFIMnBuZv9EWesB+RCevmwxHSHrNRxFJcx+SObp4P45rtRGfacCqV4IWkQR3n04O3upY3Dyqu5xcDDUYVWnbTETx32CdkdExOOu0Ufli0vKOhbVad2A/Orrkw3gznurzM9cM3i+bO7plPq53vc51Z2yM834yteBlEvXlSZ2/mPsLQSercjHQYuIZn4HgxXnJ4GWhHTQFLzJTZHADPgJC8i2whHeddZcnOiNk8n1Y7kYsZKOoY4JkJnyUGDXjXNu9rCyiM8rjcuuj5/EL7GB79S8dNOLLpd9ftIjDMGuEooj3JMALD86gwcH+gmBG9Q5V6vZd+hq9djyj/ULw3vYWnIwPR3jwfxq7amenQRjdhfJGJXZO6FW8yaHy4loDCAA11F+Z3gpq+Jt5WPMbpNG1ZXbBjRow4OumMYoD8XRljIKXX8dFmj+DJCwEyMVM+oC/ZRfsr5TFllkWiLvpW5zP2H7Mzwlm7OSxV2oA3w7k542xj+IlgtoO3QYVRW/G8/L7Dlhc7dA+M98L9gmLWeE3xzTEefQGaZwMnHWO03UxmnJSl4cVgMiuU6/MG2VeZTMAtflbnw9ijdkY8ZN1o59QpK8a+WPfgxTFlvTugMMK0nxaxVND7vBWPcdrg0bJ0dPSaEuTBM4MYOB5RMUCWsAyqO8jpvJxqmfsDAuJ5JM4IjK75NNjpXa5mx0y3jAa86rhdAYVSF843qmZDq1aMzK14jDOo/UKdvzWtqar2Md5MEu5ghUA88jxeBmT8rGBALFEIPGQMRCnWh6fpbxl84q/Oh/4mO6dqBjPsl4IXHjfi1aCGvXcoF+MMg0zNOYWzf+SbNdLdIReqtLvxwHah7lKnzEQ7OIm6N9BDkDDuFmUtCMwqNefcdk6MzS/mHjGzoFFupImNjG2ZT6udQQWYBrg25HaN6kPVhZcPLNu7AgpDXazZmQz/q3zq5ORSce25Fw95A9eALgNWp5R3lprKkmcQaXcZTAaQFOf6sqLTfjNYlPFZ8ugqN5x8/0Tji0ySp906n1Y71SNF+2ubwP5ePMdUqQwoX38ld9pkUZnsKTwDxYvg4t+r6JeUtSzRop6FATM8bHDH6SgDoLzDncNbupiv6S4DcwDH4FS/LwqX1JJ/IrGkj4O0/WwiTTYRfF8StNGPiQGfWryfKY8dIMHrmU+rnQfw/3wR7Y/8WPfixXGztbzhfxswmbiD3GFO1tRoKvaukHY67U/wXJy0kDwngq9jXRhxJC+07+EH51I36Qkj+VnDo09b1FWjWdC36kZO2/OgUIfBkDKJCnmWHx3hBnT3+1G36jT4vq67tpLyk29W9PfOp8lOlYGtrR5ri58pkOnBW/Tjv+UeF7RHL5lRAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 1.4142135623731$"
- ],
- "text/plain": [
- "1.4142135623730951"
- ]
- },
- "execution_count": 104,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(pt=1, phi=1.3, eta=2).deltaR(vector.obj(pt=2, phi=0.3, eta=1))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 105,
- "id": "strategic-hypothesis",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJQAAAAPCAYAAAACneZUAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFbUlEQVRoBe2a35XVNhCHDWcLWEgH0AGwHWw6CKECoIPk5G3fONBBoAL+dJCkAgIdQAeB7WDzfbqWIsuyr2TvCS/MObqSR6PfjDSjkezdG1dXV8N36l+Bi4uLe5SP+UieT3m+Tf0553+rNnbcQfc55Q3ty//DjpNcCUrv8fyWcn+PASPOU+qnOX5s9+pZwoPvgv064j6g/uIz/Imjx/5QHdM9Yka7DRB1PIf/Z45D+y949kddtqX7h2r+i/zzgvsaXhw/0G6ezyh7zE79+bsF+UJ1eLyEf8tWI94EgzGzeDmB6UK8ougMneKk9pJBmRZKsJ16anja6UL9KL5EW4d9kEdJAUC7aY6jnAEZHTXQ/gnMP6gfUt6pZyTXS3JRzUj2PUPmknpC8LTVOYgd7KL22XKXMowyPfNpsfMMaPXVMqaZK2xGdLs+LXjaubqWBpQL8JCi8C9ULtBmGjFm47fqWcJDgcGTHK9CZF2UJzR1VNh5I791jo59AoYBFIMnBuZv9EWesB+RCevmwxHSHrNRxFJcx+SObp4P45rtRGfacCqV4IWkQR3n04O3upY3Dyqu5xcDDUYVWnbTETx32CdkdExOOu0Ufli0vKOhbVad2A/Orrkw3gznurzM9cM3i+bO7plPq53vc51Z2yM834yteBlEvXlSZ2/mPsLQSercjHQYuIZn4HgxXnJ4GWhHTQFLzJTZHADPgJC8i2whHeddZcnOiNk8n1Y7kYsZKOoY4JkJnyUGDXjXNu9rCyiM8rjcuuj5/EL7GB79S8dNOLLpd9ftIjDMGuEooj3JMALD86gwcH+gmBG9Q5V6vZd+hq9djyj/ULw3vYWnIwPR3jwfxq7amenQRjdhfJGJXZO6FW8yaHy4loDCAA11F+Z3gpq+Jt5WPMbpNG1ZXbBjRow4OumMYoD8XRljIKXX8dFmj+DJCwEyMVM+oC/ZRfsr5TFllkWiLvpW5zP2H7Mzwlm7OSxV2oA3w7k542xj+IlgtoO3QYVRW/G8/L7Dlhc7dA+M98L9gmLWeE3xzTEefQGaZwMnHWO03UxmnJSl4cVgMiuU6/MG2VeZTMAtflbnw9ijdkY8ZN1o59QpK8a+WPfgxTFlvTugMMK0nxaxVND7vBWPcdrg0bJ0dPSaEuTBM4MYOB5RMUCWsAyqO8jpvJxqmfsDAuJ5JM4IjK75NNjpXa5mx0y3jAa86rhdAYVSF843qmZDq1aMzK14jDOo/UKdvzWtqar2Md5MEu5ghUA88jxeBmT8rGBALFEIPGQMRCnWh6fpbxl84q/Oh/4mO6dqBjPsl4IXHjfi1aCGvXcoF+MMg0zNOYWzf+SbNdLdIReqtLvxwHah7lKnzEQ7OIm6N9BDkDDuFmUtCMwqNefcdk6MzS/mHjGzoFFupImNjG2ZT6udQQWYBrg25HaN6kPVhZcPLNu7AgpDXazZmQz/q3zq5ORSce25Fw95A9eALgNWp5R3lprKkmcQaXcZTAaQFOf6sqLTfjNYlPFZ8ugqN5x8/0Tji0ySp906n1Y71SNF+2ubwP5ePMdUqQwoX38ld9pkUZnsKTwDxYvg4t+r6JeUtSzRop6FATM8bHDH6SgDoLzDncNbupiv6S4DcwDH4FS/LwqX1JJ/IrGkj4O0/WwiTTYRfF8StNGPiQGfWryfKY8dIMHrmU+rnQfw/3wR7Y/8WPfixXGztbzhfxswmbiD3GFO1tRoKvaukHY67U/wXJy0kDwngq9jXRhxJC+07+EH51I36Qkj+VnDo09b1FWjWdC36kZO2/OgUIfBkDKJCnmWHx3hBnT3+1G36jT4vq67tpLyk29W9PfOp8lOlYGtrR5ri58pkOnBW/Tjv+UeF7RHL5lRAAAAAElFTkSuQmCC",
- "text/latex": [
- "$\\displaystyle 1.4142135623731$"
- ],
- "text/plain": [
- "1.4142135623730951"
- ]
- },
- "execution_count": 105,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(pt=1, phi=1.3, eta=2, mass=5).deltaR(\n",
- " vector.obj(pt=2, phi=0.3, eta=1, mass=10)\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "sensitive-booking",
- "metadata": {},
- "source": [
- "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."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 106,
- "id": "loaded-kidney",
- "metadata": {},
- "outputs": [
- {
- "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.0)\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",
- "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)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "willing-detail",
- "metadata": {},
- "source": [
- "Similarly, for a few vector methods, the dimension of the input vectors are type checked strictly.\n",
- "\n",
- "For instance, a cross-product is only defined for 3D and 7D vectors; hence, running the method on a 4D vector will error out."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 107,
- "id": "preceding-possibility",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "VectorObject3D(x=-0.03, y=0.06, z=-0.030000000000000013)"
- ]
- },
- "execution_count": 107,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vector.obj(x=0.1, y=0.2, z=0.3).cross(vector.obj(x=0.4, y=0.5, z=0.6))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "operational-accused",
- "metadata": {},
- "source": [
- "The (current) list of properties and methods is:\n",
- "\n",
- "**Planar (2D, 3D, 4D):**\n",
- "\n",
- " * `x` (`px`)\n",
- " * `y` (`py`)\n",
- " * `rho` (`pt`): two-dimensional magnitude\n",
- " * `rho2` (`pt2`): two-dimensional magnitude squared\n",
- " * `phi`\n",
- " * `deltaphi(vector)`: difference in `phi` (signed and rectified to $-\\pi$ through $\\pi$)\n",
- " * `rotateZ(angle)`\n",
- " * `transform2D(obj)`: the `obj` must supply components through `obj[\"xx\"]`, `obj[\"xy\"]`, `obj[\"yx\"]`, `obj[\"yy\"]`\n",
- " * `is_parallel(vector, tolerance=1e-5)`: only true _if they're pointing in the same direction_\n",
- " * `is_antiparallel(vector, tolerance=1e-5)`: only true _if they're pointing in opposite directions_\n",
- " * `is_perpendicular(vector, tolerance=1e-5)`\n",
- "\n",
- "**Spatial (3D, 4D):**\n",
- "\n",
- " * `z` (`pz`)\n",
- " * `theta`\n",
- " * `eta`\n",
- " * `costheta`\n",
- " * `cottheta`\n",
- " * `mag` (`p`): three-dimensional magnitude, does not include temporal component\n",
- " * `mag2` (`p2`): three-dimensional magnitude squared\n",
- " * `cross`: cross-product (strictly 3D)\n",
- " * `deltaangle(vector)`: difference in angle (always non-negative)\n",
- " * `deltaeta(vector)`: difference in `eta` (signed)\n",
- " * `deltaR(vector)`: $\\Delta R = \\sqrt{\\Delta\\phi^2 + \\Delta\\eta^2}$\n",
- " * `deltaR2(vector)`: the above, squared\n",
- " * `rotateX(angle)`\n",
- " * `rotateY(angle)`\n",
- " * `rotate_axis(axis, angle)`: the magnitude of `axis` is ignored, but it must be at least 3D\n",
- " * `rotate_euler(phi, theta, psi, order=\"zxz\")`: the arguments are in the same order as [ROOT::Math::EulerAngles](https://root.cern.ch/doc/master/classROOT_1_1Math_1_1EulerAngles.html), and `order=\"zxz\"` agrees with ROOT's choice of conventions\n",
- " * `rotate_nautical(yaw, pitch, roll)`\n",
- " * `rotate_quaternion(u, i, j, k)`: again, the conventions match [ROOT::Math::Quaternion](https://root.cern.ch/doc/master/classROOT_1_1Math_1_1Quaternion.html).\n",
- " * `transform3D(obj)`: the `obj` must supply components through `obj[\"xx\"]`, `obj[\"xy\"]`, etc.\n",
- " * `is_parallel(vector, tolerance=1e-5)`: only true _if they're pointing in the same direction_\n",
- " * `is_antiparallel(vector, tolerance=1e-5)`: only true _if they're pointing in opposite directions_\n",
- " * `is_perpendicular(vector, tolerance=1e-5)`\n",
- "\n",
- "**Lorentz (4D only):**\n",
- "\n",
- " * `t` (`E`, `energy`): follows the [ROOT::Math::LorentzVector](https://root.cern/doc/master/LorentzVectorPage.html) behavior of treating spacelike vectors as negative `t` and negative `tau` and truncating wrong-direction timelike vectors\n",
- " * `t2` (`E2`, `energy2`)\n",
- " * `tau` (`M`, `mass`): see note above\n",
- " * `tau2` (`M2`, `mass2`)\n",
- " * `beta`: scalar(s) between $0$ (inclusive) and $1$ (exclusive, unless the vector components are infinite)\n",
- " * `deltaRapidityPhi`: $\\Delta R_{\\mbox{rapidity}} = \\Delta\\phi^2 + \\Delta \\mbox{rapidity}^2$\n",
- " * `deltaRapidityPhi2`: the above, squared\n",
- " * `gamma`: scalar(s) between $1$ (inclusive) and $\\infty$\n",
- " * `rapidity`: scalar(s) between $0$ (inclusive) and $\\infty$\n",
- " * `boost_p4(four_vector)`: change coordinate system using another 4D vector as the difference\n",
- " * `boost_beta(three_vector)`: change coordinate system using a 3D beta vector (all components between $-1$ and $+1$)\n",
- " * `boost(vector)`: uses the dimension of the given `vector` to determine behavior\n",
- " * `boostX(beta=None, gamma=None)`: supply `beta` xor `gamma`, but not both\n",
- " * `boostY(beta=None, gamma=None)`: supply `beta` xor `gamma`, but not both\n",
- " * `boostZ(beta=None, gamma=None)`: supply `beta` xor `gamma`, but not both\n",
- " * `transform4D(obj)`: the `obj` must supply components through `obj[\"xx\"]`, `obj[\"xy\"]`, etc.\n",
- " * `to_beta3()`: turns a `four_vector` (for `boost_p4`) into a `three_vector` (for `boost_beta3`)\n",
- " * `is_timelike(tolerance=0)`\n",
- " * `is_spacelike(tolerance=0)`\n",
- " * `is_lightlike(tolerance=1e-5)`: note the different tolerance\n",
- "\n",
- "**All numbers of dimensions:**\n",
- "\n",
- " * `unit()`: note the parentheses\n",
- " * `dot(vector)`: can also use the `@` operator\n",
- " * `add(vector)`: can also use the `+` operator\n",
- " * `subtract(vector)`: can also use the `-` operator\n",
- " * `scale(factor)`: can also use the `*` operator\n",
- " * `equal(vector)`: can also use the `==` operator, but consider `isclose` instead\n",
- " * `not_equal(vector)`: can also use the `!=` operator, but consider `isclose` instead\n",
- " * `sum()`: can also use the `numpy.sum` or `awkward.sum`, only for NumPy and Awkward vectors\n",
- " * `count_nonzero()`: can also use `numpy.count_nonzero` or `awkward.count_nonzero`, only for NumPy and Awkward vectors\n",
- " * `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_VectorND(coordinates)`/`to_ND(coordinates)`: replace `N` with the required vector dimension\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"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dedicated-exemption",
- "metadata": {},
- "source": [
- "## Compiling your Python with Numba\n",
- "\n",
- "[Numba](https://numba.pydata.org/) is a just-in-time (JIT) compiler for a mathematically relevant subset of NumPy and Python. It allows you to write fast code without leaving the Python environment. The drawback of Numba is that it can only compile code blocks involving objects and functions that it recognizes.\n",
- "\n",
- "The Vector library includes extensions to inform Numba about vector objects, vector NumPy arrays, and vector Awkward Arrays. At the time of writing, the implementation of vector NumPy arrays is incomplete due to [numba/numba#6148](https://github.com/numba/numba/pull/6148).\n",
- "\n",
- "For instance, consider the following function:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 108,
- "id": "sporting-champion",
- "metadata": {},
- "outputs": [],
- "source": [
- "@nb.njit\n",
- "def compute_mass(v1, v2):\n",
- " return (v1 + v2).mass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 109,
- "id": "blocked-attribute",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOCAYAAAAxDQxDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABr0lEQVQ4EaWU7VECQQyGD8YCGOwAO/CjA+gA7UAtgfEX/HMoAS0BOpAOHOgAOgDp4HyeZffmgBVnNDO5JO8mm02yt42yLAtpNBq1EC/B2H+0p+DzGnZWxXccHTbIK3gMtg6YieThcDhJepJgU7if7HMSv0XdF70Fr+COcU2zkfUJsQiZDz+PmPUqD1ejFeNbyFlyQN+ha0/EQiKkZfYE/kj3xC0zsZ9gXZK2UiKBPsCHYC3AnocT1bCc2gXcZhb28yHZhYtsPpNR+/AX+gBplSau2oF9QqzXD3ayHoF2qqggwPLf4oKVeMpcO6JLJdpRcyY/UdU6E1mNzlbile7Aq4ij/osuQ0Vs5q3rIQfwGvZiWKH0jn2uPbnZ7COLIlW7Sa2zVc6lIjZ3NlZnEtuYJfxSy3KHSdi6GU/rP5ACqg3BvDUmTCer1o6U1OojuIqbm8gEO6QzyZGn+u0ZmuJzmwm+AVuaI7XOefiupVJDDLaz84qH/8F1uIQPXhFsb+sW6YUKhO5eD7CvS9HwHZJYuEb43NSHe/Ko4rfCZ458RlaE7cbOegf7qN7Br+DhF/kGiTPUL2upEhgAAAAASUVORK5CYII=",
- "text/latex": [
- "$\\displaystyle 8.0$"
- ],
- "text/plain": [
- "8.0"
- ]
- },
- "execution_count": 109,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "compute_mass(vector.obj(px=1, py=2, pz=3, E=4), vector.obj(px=-1, py=-2, pz=-3, E=4))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "significant-sweden",
- "metadata": {},
- "source": [
- "When the two `MomentumObject4D` objects are passed as arguments, Numba recognizes them and replaces the Python objects with low-level structs. When it compiles the function, it recognizes `+` as the 4D `add` function and recognizes `.mass` as the `tau` component of the result.\n",
- "\n",
- "Although this demonstrates that Numba can manipulate vector objects, there is no performance advantage (and a likely disadvantage) to compiling a calculation on just a few vectors. The advantage comes when many vectors are involved, in arrays."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 110,
- "id": "round-supplier",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[],\n",
- " [{x: 0.68, y: 0.799, z: -0.423, t: 10.4}, ..., {x: -0.17, y: 1.11, ...}],\n",
- " [{x: -1.23, y: 0.529, z: -0.974, t: 11.5}, {x: -1.95, y: 0.159, ...}],\n",
- " [{x: 0.232, y: -1.05, z: 0.134, t: 8.56}],\n",
- " [{x: 1.55, y: 0.503, z: 0.609, t: 7.54}],\n",
- " [{x: -0.181, y: 0.579, z: 0.774, t: 8.93}, {x: -0.361, y: -0.517, ...}],\n",
- " [{x: 0.746, y: -1.49, z: 0.096, t: 10.2}, ..., {x: -0.274, y: -0.0958, ...}],\n",
- " [{x: 0.215, y: 1.29, z: -0.908, t: 11.8}],\n",
- " [{x: -0.621, y: 0.148, z: 0.128, t: 10.6}],\n",
- " [],\n",
- " ...,\n",
- " [],\n",
- " [{x: 1.38, y: -0.677, z: 1.71, t: 11.9}],\n",
- " [],\n",
- " [{x: 0.0776, y: -0.233, z: 0.738, t: 11.6}, {x: -0.242, y: 2.69, ...}],\n",
- " [],\n",
- " [{x: 2.12, y: -0.294, z: 0.0647, t: 10}],\n",
- " [{x: 0.431, y: 0.33, z: -0.372, t: 9.36}],\n",
- " [{x: -0.144, y: 0.304, z: -0.333, t: 9.21}, {x: -1.65, y: -0.12, ...}],\n",
- " [{x: 2.4, y: 0.994, z: 1.88, t: 8.42}, {x: 0.418, y: -1.66, z: ..., ...}]]\n",
- "------------------------------------------------------------------------------\n",
- "type: 50 * var * Momentum4D[\n",
- " x: float64,\n",
- " y: float64,\n",
- " z: float64,\n",
- " t: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 110,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# This is still not a large number. You want millions.\n",
- "array = vector.Array(\n",
- " [\n",
- " [\n",
- " dict(\n",
- " {x: np.random.normal(0, 1) for x in (\"px\", \"py\", \"pz\")},\n",
- " E=np.random.normal(10, 1),\n",
- " )\n",
- " for inner in range(np.random.poisson(1.5))\n",
- " ]\n",
- " for outer in range(50)\n",
- " ]\n",
- ")\n",
- "array"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 111,
- "id": "emotional-headquarters",
- "metadata": {},
- "outputs": [],
- "source": [
- "@nb.njit\n",
- "def compute_masses(array):\n",
- " out = np.empty(len(array), np.float64)\n",
- " for i, event in enumerate(array):\n",
- " total = vector.obj(px=0.0, py=0.0, pz=0.0, E=0.0)\n",
- " for vec in event:\n",
- " total = total + vec\n",
- " out[i] = total.mass\n",
- " return out"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 112,
- "id": "recorded-grass",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "array([ 0. , 29.75052555, 20.62838909, 8.48660722, 7.33516837,\n",
- " 18.70338324, 29.7146754 , 11.65299876, 10.59925 , 0. ,\n",
- " 0. , 21.27961128, 0. , 29.59277853, 27.32368944,\n",
- " 0. , 0. , 10.59714826, 0. , 34.36150967,\n",
- " 27.76305288, 10.42185596, 8.59241845, 0. , 19.31564032,\n",
- " 9.3728877 , 20.05084709, 9.29945943, 10.5533362 , 28.56379761,\n",
- " 10.27649379, 41.35441725, 0. , 10.73854109, 0. ,\n",
- " 19.35692625, 28.85293189, 32.14146007, 21.7278048 , 10.27831307,\n",
- " 39.11007941, 0. , 11.63961915, 0. , 20.42034302,\n",
- " 0. , 9.78956764, 9.33434012, 20.00141989, 18.47871584])"
- ]
- },
- "execution_count": 112,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "compute_masses(array)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f9f99531-245a-4a24-b717-42839ff542c0",
- "metadata": {},
- "source": [
- "## Sub-classing Awkward mixins\n",
- "\n",
- "At the moment, it is possible to sub-class vector awkward mixins to extend the vector functionalities. Although the mechanism in place works well, it is still being improved.\n",
- "\n",
- "For instance, the `MomentumAwkward` classes can be extended in the following way:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 113,
- "id": "eabb3cc3-3df3-4052-a64d-84499866fdc9",
- "metadata": {},
- "outputs": [],
- "source": [
- "behavior = vector.backends.awkward.behavior\n",
- "\n",
- "\n",
- "@ak.mixin_class(behavior)\n",
- "class TwoVector(vector.backends.awkward.MomentumAwkward2D):\n",
- " pass\n",
- "\n",
- "\n",
- "@ak.mixin_class(behavior)\n",
- "class ThreeVector(vector.backends.awkward.MomentumAwkward3D):\n",
- " pass\n",
- "\n",
- "\n",
- "# required for transforming vectors\n",
- "# the class names must always end with \"Array\"\n",
- "TwoVectorArray.ProjectionClass2D = TwoVectorArray # noqa: F821\n",
- "TwoVectorArray.ProjectionClass3D = ThreeVectorArray # noqa: F821\n",
- "TwoVectorArray.MomentumClass = TwoVectorArray # noqa: F821\n",
- "\n",
- "ThreeVectorArray.ProjectionClass2D = TwoVectorArray # noqa: F821\n",
- "ThreeVectorArray.ProjectionClass3D = ThreeVectorArray # noqa: F821\n",
- "ThreeVectorArray.MomentumClass = ThreeVectorArray # noqa: F821"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 114,
- "id": "09fb1708-0205-409d-b348-e2d1611227f3",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{pt: 1, phi: 1.2}, {pt: 2, phi: 1.4}],\n",
- " [],\n",
- " [{pt: 3, phi: 1.6}],\n",
- " [{pt: 4, phi: 3.4}]]\n",
- "----------------------------------------\n",
- "type: 4 * var * TwoVector[\n",
- " pt: int64,\n",
- " phi: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 114,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec = ak.zip(\n",
- " {\n",
- " \"pt\": [[1, 2], [], [3], [4]],\n",
- " \"phi\": [[1.2, 1.4], [], [1.6], [3.4]],\n",
- " },\n",
- " with_name=\"TwoVector\",\n",
- " behavior=behavior,\n",
- ")\n",
- "vec"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7c2d0b74-0f87-417c-8e0c-5420408f3dff",
- "metadata": {},
- "source": [
- "The binary operators are not automatically registered by awkward, but vector methods can be used to perform operations on sub-classed vectors."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 115,
- "id": "a63c205e-4b80-4e78-a3c3-fda3be083085",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 2, phi: 1.2}, {rho: 4, phi: 1.4}],\n",
- " [],\n",
- " [{rho: 6, phi: 1.6}],\n",
- " [{rho: 8, phi: -2.88}]]\n",
- "------------------------------------------\n",
- "type: 4 * var * TwoVector[\n",
- " rho: float64,\n",
- " phi: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 115,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec.add(vec)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a51204fc-e1e5-4bdc-a3a0-d51dbc786457",
- "metadata": {},
- "source": [
- "Similarly, other vector methods can be used by the new methods internally."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 116,
- "id": "f9feeec4-c730-4f7b-b5bd-05d401eb0ee1",
- "metadata": {},
- "outputs": [],
- "source": [
- "@ak.mixin_class(behavior)\n",
- "class LorentzVector(vector.backends.awkward.MomentumAwkward4D):\n",
- " @ak.mixin_class_method(np.divide, {numbers.Number})\n",
- " def divide(self, factor):\n",
- " return self.scale(1 / factor)\n",
- "\n",
- "\n",
- "# required for transforming vectors\n",
- "# the class names must always end with \"Array\"\n",
- "LorentzVectorArray.ProjectionClass2D = TwoVectorArray # noqa: F821\n",
- "LorentzVectorArray.ProjectionClass3D = ThreeVectorArray # noqa: F821\n",
- "LorentzVectorArray.ProjectionClass4D = LorentzVectorArray # noqa: F821\n",
- "LorentzVectorArray.MomentumClass = LorentzVectorArray # noqa: F821"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 117,
- "id": "d66c5f27-ae2e-4659-b96a-bd0493bda557",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{pt: 1, eta: 1.2, phi: 0.3, energy: 50}, {pt: 2, eta: 1.4, ...}],\n",
- " [],\n",
- " [{pt: 3, eta: 1.6, phi: 0.5, energy: 52}],\n",
- " [{pt: 4, eta: 3.4, phi: 0.6, energy: 60}]]\n",
- "-------------------------------------------------------------------\n",
- "type: 4 * var * LorentzVector[\n",
- " pt: int64,\n",
- " eta: float64,\n",
- " phi: float64,\n",
- " energy: int64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 117,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec = ak.zip(\n",
- " {\n",
- " \"pt\": [[1, 2], [], [3], [4]],\n",
- " \"eta\": [[1.2, 1.4], [], [1.6], [3.4]],\n",
- " \"phi\": [[0.3, 0.4], [], [0.5], [0.6]],\n",
- " \"energy\": [[50, 51], [], [52], [60]],\n",
- " },\n",
- " with_name=\"LorentzVector\",\n",
- " behavior=behavior,\n",
- ")\n",
- "vec"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 118,
- "id": "9841c7c5-745d-46bb-8d03-07d16f9bc2e1",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 0.5, phi: 0.3, eta: 1.2, t: 25}, {rho: 1, phi: 0.4, ...}],\n",
- " [],\n",
- " [{rho: 1.5, phi: 0.5, eta: 1.6, t: 26}],\n",
- " [{rho: 2, phi: 0.6, eta: 3.4, t: 30}]]\n",
- "------------------------------------------------------------------\n",
- "type: 4 * var * LorentzVector[\n",
- " rho: float64,\n",
- " phi: float64,\n",
- " eta: float64,\n",
- " t: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 118,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec / 2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 119,
- "id": "ce31f343-ced2-499a-8ae9-382ebe420351",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 1, phi: 0.3}, {rho: 2, phi: 0.4}],\n",
- " [],\n",
- " [{rho: 3, phi: 0.5}],\n",
- " [{rho: 4, phi: 0.6}]]\n",
- "------------------------------------------\n",
- "type: 4 * var * TwoVector[\n",
- " rho: int64,\n",
- " phi: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 119,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec.like(vector.obj(x=1, y=2))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 120,
- "id": "09a1492b-f3f3-4f24-965f-8973f98c6a2a",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 1, phi: 0.3, eta: 1.2}, {rho: 2, phi: 0.4, eta: 1.4}],\n",
- " [],\n",
- " [{rho: 3, phi: 0.5, eta: 1.6}],\n",
- " [{rho: 4, phi: 0.6, eta: 3.4}]]\n",
- "--------------------------------------------------------------\n",
- "type: 4 * var * ThreeVector[\n",
- " rho: int64,\n",
- " phi: float64,\n",
- " eta: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 120,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec.like(vector.obj(x=1, y=2, z=3))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "088b4d4a-882b-4082-bcef-04ea9c4e2a17",
- "metadata": {},
- "source": [
- "It is also possible to manually add binary operations in vector's behavior dict to enable binary operations."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 121,
- "id": "0b8e04b4-4117-4169-9d13-03dd0fea8161",
- "metadata": {},
- "outputs": [],
- "source": [
- "_binary_dispatch_cls = {\n",
- " \"TwoVector\": TwoVector,\n",
- " \"ThreeVector\": ThreeVector,\n",
- " \"LorentzVector\": LorentzVector,\n",
- "}\n",
- "_rank = [TwoVector, ThreeVector, LorentzVector]\n",
- "\n",
- "for lhs, lhs_to in _binary_dispatch_cls.items():\n",
- " for rhs, rhs_to in _binary_dispatch_cls.items():\n",
- " out_to = min(lhs_to, rhs_to, key=_rank.index)\n",
- " behavior[(np.add, lhs, rhs)] = out_to.add\n",
- " behavior[(np.subtract, lhs, rhs)] = out_to.subtract"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 122,
- "id": "09c03e49-8233-492c-8fa7-45029a774388",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 2, phi: 0.3, eta: 1.2, t: 100}, {rho: 4, phi: 0.4, eta: 1.4, ...}],\n",
- " [],\n",
- " [{rho: 6, phi: 0.5, eta: 1.6, t: 104}],\n",
- " [{rho: 8, phi: 0.6, eta: 3.4, t: 120}]]\n",
- "---------------------------------------------------------------------------\n",
- "type: 4 * var * LorentzVector[\n",
- " rho: float64,\n",
- " phi: float64,\n",
- " eta: float64,\n",
- " t: int64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 122,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec + vec"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 123,
- "id": "7c13bd26-95b5-4ae3-9f17-4818493f510a",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 2, phi: 0.3}, {rho: 4, phi: 0.4}],\n",
- " [],\n",
- " [{rho: 6, phi: 0.5}],\n",
- " [{rho: 8, phi: 0.6}]]\n",
- "------------------------------------------\n",
- "type: 4 * var * TwoVector[\n",
- " rho: float64,\n",
- " phi: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 123,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec.to_2D() + vec.to_2D()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "326f3e22-d58e-4e82-9f63-99eab307ac52",
- "metadata": {},
- "source": [
- "Finally, instead of manually registering the superclass ufuncs, one can use the utility `copy_behaviors` function to copy behavior items for a new subclass -"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 124,
- "id": "48629f7e-306e-438d-bb15-a66f0acbdfc5",
- "metadata": {},
- "outputs": [],
- "source": [
- "behavior.update(ak._util.copy_behaviors(\"Vector2D\", \"TwoVector\", behavior))\n",
- "behavior.update(ak._util.copy_behaviors(\"Vector3D\", \"ThreeVector\", behavior))\n",
- "behavior.update(ak._util.copy_behaviors(\"Momentum4D\", \"LorentzVector\", behavior))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 125,
- "id": "8874188b-778e-45af-8320-7f472f9794a2",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 2, phi: 0.3, eta: 1.2, t: 100}, {rho: 4, phi: 0.4, eta: 1.4, ...}],\n",
- " [],\n",
- " [{rho: 6, phi: 0.5, eta: 1.6, t: 104}],\n",
- " [{rho: 8, phi: 0.6, eta: 3.4, t: 120}]]\n",
- "---------------------------------------------------------------------------\n",
- "type: 4 * var * Momentum4D[\n",
- " rho: float64,\n",
- " phi: float64,\n",
- " eta: float64,\n",
- " t: int64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 125,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec + vec"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 126,
- "id": "051f94ac-b875-47f6-8b11-4725eeb6c2f3",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "[[{rho: 2, phi: 0.3}, {rho: 4, phi: 0.4}],\n",
- " [],\n",
- " [{rho: 6, phi: 0.5}],\n",
- " [{rho: 8, phi: 0.6}]]\n",
- "------------------------------------------\n",
- "type: 4 * var * Vector2D[\n",
- " rho: float64,\n",
- " phi: float64\n",
- "]
"
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 126,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vec.to_2D() + vec.to_2D()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bb6c289a",
- "metadata": {},
- "source": [
- "## Talks about vector\n",
- "\n",
- "- 3rd July 2024 - [A new SymPy backend for vector: uniting experimental and theoretical physicists](https://indi.to/pfTC6) - [PyHEP 2024 (virtual)](https://indico.cern.ch/event/1384010/)\n",
- "- 9th October 2023 - [What’s new with Vector? First major release is out!](https://indi.to/35ym5) - [PyHEP 2023 (virtual)](https://indico.cern.ch/event/1252095/) [🎥](https://www.youtube.com/watch?v=JHEAb2R3xzE&list=PLKZ9c4ONm-VlAorAG8kR09ZqhMfHiH2LJ&index=10)\n",
- "- 13th September 2022 - [Constructing HEP vectors and analyzing HEP data using Vector](https://indi.to/bPmMc) - [PyHEP 2022 (virtual)](https://indico.cern.ch/event/1150631/) [🎥](https://www.youtube.com/watch?v=4iveMzrbe7s&list=PLKZ9c4ONm-VkohKG-skzEG_gklMaSgaO7&index=15)\n",
- "- 20th July 2022 - [Analysis Grand Challenge / HEP Scientific Python Ecosystem](https://indico.cern.ch/event/1151329/timetable/#3-analysis-grand-challenge-hep) - [DANCE/CoDaS@Snowmass 2022 computational and data science software training](https://indico.cern.ch/event/1151329/)\n",
- "- 25th April 2022 - [Foundation libraries (uproot, awkward, hist, mplhep)](https://indico.cern.ch/event/1126109/contributions/4780138/) - [IRIS-HEP AGC Tools 2022 Workshop](https://indico.cern.ch/event/1126109/) [🎥](https://www.youtube.com/watch?v=O9KvsDMKOmY)\n",
- "- 3rd November 2021 - [Data handling: uproot, awkward & vector](https://indico.cern.ch/event/1076231/contributions/4560398/) - [IRIS-HEP AGC Tools 2021 Workshop](https://indico.cern.ch/event/1076231/) [🎥](https://indico.cern.ch/event/1076231/contributions/4560398/attachments/2338579/4017718/agc_uproot_awk.mp4)\n"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "particular-bangkok",
- "metadata": {},
- "source": [
- "### Status as of November 17, 2023\n",
- "\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": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.11.5"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/usage/structure.md b/docs/usage/structure.md
deleted file mode 100644
index 136bb8af..00000000
--- a/docs/usage/structure.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Structure of Vector
-
-
-
-
-
-
-
-
-
-
diff --git a/pyproject.toml b/pyproject.toml
index f0a59ddd..75070e31 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -52,6 +52,7 @@ optional-dependencies.awkward = [
optional-dependencies.dev = [
"awkward>=2",
"dask-awkward",
+ "sympy",
"nox",
"numba>=0.57; python_version<'3.13'",
"papermill>=2.4",
@@ -62,6 +63,7 @@ optional-dependencies.dev = [
]
optional-dependencies.docs = [
"awkward>=2",
+ "sympy",
"ipykernel",
"myst-parser>0.13",
"nbsphinx",
@@ -134,8 +136,8 @@ isort.required-imports = [
"tests/*" = [
"T20",
]
-"docs/usage/intro.ipynb" = [
- "T20",
+"docs/src/*.ipynb" = [
+ "T20", "I001", "I002"
]
"src/vector/backends/_numba_object.py" = [
"PGH003",
diff --git a/src/vector/backends/numpy.py b/src/vector/backends/numpy.py
index 98a6f6ca..056e22e4 100644
--- a/src/vector/backends/numpy.py
+++ b/src/vector/backends/numpy.py
@@ -1143,6 +1143,14 @@ class VectorNumpy2D(VectorNumpy, Planar, Vector2D, FloatArray): # type: ignore[
>>> vec
VectorNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
+ ... dtype=[('x', float), ('y', float)])
+ >>> arr.view(vector.VectorNumpy2D)
+ VectorNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
+ dtype=[('x', '>> vec
MomentumNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
+ ... dtype=[('px', float), ('py', float)])
+ >>> arr.view(vector.MomentumNumpy2D)
+ MomentumNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
+ dtype=[('x', '>> vec
VectorNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4),
(1.5, 2.5, 3.5)], dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4), (1.5, 2.5, 3.5)],
+ ... dtype=[('x', float), ('y', float), ('z', float)])
+ >>> arr.view(vector.VectorNumpy3D)
+ VectorNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4),
+ (1.5, 2.5, 3.5)], dtype=[('x', '>> vec
MomentumNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4),
(1.5, 2.5, 3.5)], dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4), (1.5, 2.5, 3.5)],
+ ... dtype=[('px', float), ('py', float), ('pz', float)])
+ >>> arr.view(vector.MomentumNumpy3D)
+ MomentumNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4),
+ (1.5, 2.5, 3.5)], dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3), (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)],
+ ... dtype=[('x', float), ('y', float), ('z', float), ('t', float)])
+ >>> arr.view(vector.VectorNumpy4D)
+ VectorNumpy4D([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3),
+ (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)],
+ dtype=[('x', '>> import numpy as np
+ >>> import vector
+ >>> arr = np.array([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3), (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)],
+ ... dtype=[('px', float), ('py', float), ('pz', float), ('t', float)])
+ >>> arr.view(vector.MomentumNumpy4D)
+ MomentumNumpy4D([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3),
+ (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)],
+ dtype=[('x', ' VectorObject:
to make the vector a momentum vector.
- Alternatively, the :class:`vector.backends.object.VectorObject2D`,
- :class:`vector.backends.object.VectorObject3D`, and
- :class:`vector.backends.object.VectorObject4D` classes (with momentum
+ Alternatively, the :class:`vector.VectorObject2D`,
+ :class:`vector.VectorObject3D`, and
+ :class:`vector.VectorObject4D` classes (with momentum
subclasses) have explicit constructors:
- - :meth:`vector.backends.object.VectorObject2D.from_xy`
- - :meth:`vector.backends.object.VectorObject2D.from_rhophi`
-
- - :meth:`vector.backends.object.VectorObject3D.from_xyz`
- - :meth:`vector.backends.object.VectorObject3D.from_xytheta`
- - :meth:`vector.backends.object.VectorObject3D.from_xyeta`
- - :meth:`vector.backends.object.VectorObject3D.from_rhophiz`
- - :meth:`vector.backends.object.VectorObject3D.from_rhophitheta`
- - :meth:`vector.backends.object.VectorObject3D.from_rhophieta`
-
- - :meth:`vector.backends.object.VectorObject4D.from_xyzt`
- - :meth:`vector.backends.object.VectorObject4D.from_xyztau`
- - :meth:`vector.backends.object.VectorObject4D.from_xythetat`
- - :meth:`vector.backends.object.VectorObject4D.from_xythetatau`
- - :meth:`vector.backends.object.VectorObject4D.from_xyetat`
- - :meth:`vector.backends.object.VectorObject4D.from_xyetatau`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophizt`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophiztau`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophithetat`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophithetatau`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophietat`
- - :meth:`vector.backends.object.VectorObject4D.from_rhophietatau`
+ - :meth:`vector.VectorObject2D.from_xy`
+ - :meth:`vector.VectorObject2D.from_rhophi`
+
+ - :meth:`vector.VectorObject3D.from_xyz`
+ - :meth:`vector.VectorObject3D.from_xytheta`
+ - :meth:`vector.VectorObject3D.from_xyeta`
+ - :meth:`vector.VectorObject3D.from_rhophiz`
+ - :meth:`vector.VectorObject3D.from_rhophitheta`
+ - :meth:`vector.VectorObject3D.from_rhophieta`
+
+ - :meth:`vector.VectorObject4D.from_xyzt`
+ - :meth:`vector.VectorObject4D.from_xyztau`
+ - :meth:`vector.VectorObject4D.from_xythetat`
+ - :meth:`vector.VectorObject4D.from_xythetatau`
+ - :meth:`vector.VectorObject4D.from_xyetat`
+ - :meth:`vector.VectorObject4D.from_xyetatau`
+ - :meth:`vector.VectorObject4D.from_rhophizt`
+ - :meth:`vector.VectorObject4D.from_rhophiztau`
+ - :meth:`vector.VectorObject4D.from_rhophithetat`
+ - :meth:`vector.VectorObject4D.from_rhophithetatau`
+ - :meth:`vector.VectorObject4D.from_rhophietat`
+ - :meth:`vector.VectorObject4D.from_rhophietatau`
"""
is_momentum = False
generic_coordinates = {}
diff --git a/src/vector/backends/sympy.py b/src/vector/backends/sympy.py
index 19a0acfc..be253766 100644
--- a/src/vector/backends/sympy.py
+++ b/src/vector/backends/sympy.py
@@ -615,9 +615,6 @@ class VectorSympy2D(VectorSympy, Planar, Vector2D):
>>> vec = vector.VectorSympy2D(rho=sympy.Symbol("rho"), phi=sympy.Symbol("phi"))
>>> vec.rho, vec.phi
(rho, phi)
- >>> vec = vector.VectorObject2D(azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("x"), sympy.Symbol("y")))
- >>> vec.x, vec.y
- (x, y)
For two dimensional momentum SymPy vectors, see
:class:`vector.backends.sympy.MomentumSympy2D`.
@@ -759,9 +756,6 @@ class MomentumSympy2D(PlanarMomentum, VectorSympy2D):
>>> vec = vector.MomentumSympy2D(pt=sympy.Symbol("pt"), phi=sympy.Symbol("phi"))
>>> vec.pt, vec.phi
(pt, phi)
- >>> vec = vector.MomentumSympy2D(azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("px"), sympy.Symbol("py")))
- >>> vec.px, vec.py
- (px, py)
For two dimensional SymPy vectors, see
:class:`vector.backends.object.VectorSympy2D`.
@@ -812,12 +806,6 @@ class VectorSympy3D(VectorSympy, Spatial, Vector3D):
>>> vec = vector.VectorSympy3D(rho=sympy.Symbol("rho"), phi=sympy.Symbol("phi"), eta=sympy.Symbol("eta"))
>>> vec.rho, vec.phi, vec.eta
(rho, phi, eta)
- >>> vec = vector.VectorSympy3D(
- ... azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("x"), sympy.Symbol("y")),
- ... longitudinal=vector.backends.sympy.LongitudinalSympyTheta(sympy.Symbol("theta"))
- ... )
- >>> vec.x, vec.y, vec.theta
- (x, y, theta)
For three dimensional momentum SymPy vectors, see
:class:`vector.backends.object.MomentumSympy3D`.
@@ -1025,12 +1013,6 @@ class MomentumSympy3D(SpatialMomentum, VectorSympy3D):
>>> vec = vector.MomentumSympy3D(pt=sympy.Symbol("pt"), phi=sympy.Symbol("phi"), pz=sympy.Symbol("pz"))
>>> vec.pt, vec.phi, vec.pz
(pt, phi, pz)
- >>> vec = vector.MomentumSympy3D(
- ... azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("x"), sympy.Symbol("y")),
- ... longitudinal=vector.backends.sympy.LongitudinalSympyTheta(sympy.Symbol("theta"))
- ... )
- >>> vec.x, vec.y, vec.theta
- (x, y, theta)
For three dimensional SymPy vectors, see
:class:`vector.backends.sympy.VectorSympy3D`.
@@ -1093,13 +1075,6 @@ class VectorSympy4D(VectorSympy, Lorentz, Vector4D):
>>> vec = vector.VectorSympy4D(rho=sympy.Symbol("rho"), phi=sympy.Symbol("phi"), eta=sympy.Symbol("eta"), tau=sympy.Symbol("tau"))
>>> vec.rho, vec.phi, vec.eta, vec.tau
(rho, phi, eta, tau)
- >>> vec = vector.VectorSympy4D(
- ... azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("x"), sympy.Symbol("y")),
- ... longitudinal=vector.backends.sympy.LongitudinalSympyTheta(sympy.Symbol("theta")),
- ... temporal=vector.backends.sympy.TemporalSympyTau(sympy.Symbol("tau"))
- ... )
- >>> vec.x, vec.y, vec.theta, vec.tau
- (x, y, theta, tau)
For four dimensional momentum SymPy vectors, see
:class:`vector.backends.sympy.MomentumSympy4D`.
@@ -1386,13 +1361,6 @@ class MomentumSympy4D(LorentzMomentum, VectorSympy4D):
>>> vec = vector.MomentumSympy4D(pt=sympy.Symbol("pt"), phi=sympy.Symbol("phi"), pz=sympy.Symbol("pz"), M=sympy.Symbol("M"))
>>> vec.pt, vec.phi, vec.pz, vec.M
(pt, phi, pz, M)
- >>> vec = vector.MomentumSympy4D(
- ... azimuthal=vector.backends.sympy.AzimuthalSympyXY(sympy.Symbol("x"), sympy.Symbol("y")),
- ... longitudinal=vector.backends.sympy.LongitudinalSympyTheta(sympy.Symbol("theta")),
- ... temporal=vector.backends.sympy.TemporalSympyTau(sympy.Symbol("tau"))
- ... )
- >>> vec.x, vec.y, vec.theta, vec.tau
- (x, y, theta, tau)
For four dimensional SymPy vectors, see
:class:`vector.backends.sympy.VectorSympy4D`.
diff --git a/tests/test_notebooks.py b/tests/test_notebooks.py
index f06a4d42..b3c842e5 100644
--- a/tests/test_notebooks.py
+++ b/tests/test_notebooks.py
@@ -17,6 +17,26 @@ def common_kwargs(tmpdir):
}
-def test_intro(common_kwargs):
- execution_dir = Path.cwd() / "docs" / "usage"
- pm.execute_notebook(execution_dir / "intro.ipynb", **common_kwargs)
+def test_object(common_kwargs):
+ execution_dir = Path.cwd() / "docs" / "src"
+ pm.execute_notebook(execution_dir / "object.ipynb", **common_kwargs)
+
+
+def test_numpy(common_kwargs):
+ execution_dir = Path.cwd() / "docs" / "src"
+ pm.execute_notebook(execution_dir / "numpy.ipynb", **common_kwargs)
+
+
+def test_awkward(common_kwargs):
+ execution_dir = Path.cwd() / "docs" / "src"
+ pm.execute_notebook(execution_dir / "awkward.ipynb", **common_kwargs)
+
+
+def test_numba(common_kwargs):
+ execution_dir = Path.cwd() / "docs" / "src"
+ pm.execute_notebook(execution_dir / "numba.ipynb", **common_kwargs)
+
+
+def test_sympy(common_kwargs):
+ execution_dir = Path.cwd() / "docs" / "src"
+ pm.execute_notebook(execution_dir / "sympy.ipynb", **common_kwargs)