coordinax.ops

Contents

coordinax.ops#

Transformations of the coordinate reference frame.

E.g. a translation.

coordinax.ops.simplify_op(op: Any, /)#

Simplify an operator.

coordinax.ops.simplify_op(op: VelocityBoost, /, **kwargs: Any) VelocityBoost | Identity
Parameters:

op (Any)

Return type:

Any

Simplify a boost operator.

Examples

>>> import unxt as u
>>> import coordinax as cx

An operator with real effect cannot be simplified:

>>> op = cx.ops.VelocityBoost.from_([1, 0, 0], "m/s")
>>> cx.ops.simplify_op(op)
VelocityBoost(CartesianVel3D( ... ))

An operator with no effect can be simplified:

>>> op = cx.ops.VelocityBoost.from_([0, 0, 0], "m/s")
>>> cx.ops.simplify_op(op)
Identity()
coordinax.ops.simplify_op(op1: VelocityBoost, op2: VelocityBoost) VelocityBoost
Parameters:

op (Any)

Return type:

Any

Combine two boosts into a single boost.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op1 = cxo.VelocityBoost.from_([1, 0, 0], "m/s")
>>> op2 = cxo.VelocityBoost.from_([0, 1, 0], "m/s")
>>> op3 = cxo.simplify_op(op1, op2)
>>> op3
VelocityBoost(CartesianVel3D( ... ))
>>> op3.velocity == op1.velocity + op2.velocity
Array(True, dtype=bool)
coordinax.ops.simplify_op(op: GalileanBoost, /, **kwargs: Any) GalileanBoost | Identity
Parameters:

op (Any)

Return type:

Any

Simplify a boost operator.

Examples

>>> import unxt as u
>>> import coordinax as cx

An operator with real effect cannot be simplified:

>>> op = cx.ops.GalileanBoost.from_([1, 0, 0], "m/s")
>>> cx.ops.simplify_op(op)
GalileanBoost(CartesianVel3D( ... ))

An operator with no effect can be simplified:

>>> op = cx.ops.GalileanBoost.from_([0, 0, 0], "m/s")
>>> cx.ops.simplify_op(op)
Identity()
coordinax.ops.simplify_op(op1: GalileanBoost, op2: GalileanBoost) GalileanBoost
Parameters:

op (Any)

Return type:

Any

Combine two boosts into a single boost.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op1 = cxo.GalileanBoost.from_([1, 0, 0], "m/s")
>>> op2 = cxo.GalileanBoost.from_([0, 1, 0], "m/s")
>>> op3 = cxo.simplify_op(op1, op2)
>>> op3
GalileanBoost(CartesianVel3D( ... ))
>>> op3.velocity == op1.velocity + op2.velocity
Array(True, dtype=bool)
coordinax.ops.simplify_op(op: GalileanRotation, /, **kwargs: Any) AbstractOperator
Parameters:

op (Any)

Return type:

Any

Simplify the Galilean rotation operator.

Examples

>>> import quaxed.numpy as jnp
>>> import unxt as u
>>> import coordinax as cx

An operator with a non-identity rotation matrix is not simplified:

>>> Rz = jnp.asarray([[0, -1, 0], [1, 0,  0], [0, 0, 1]])
>>> op = cx.ops.GalileanRotation(Rz)
>>> cx.ops.simplify_op(op)
GalileanRotation(rotation=i32[3,3])

An operator with an identity rotation matrix is simplified:

>>> op = cx.ops.GalileanRotation(jnp.eye(3))
>>> cx.ops.simplify_op(op)
Identity()
coordinax.ops.simplify_op(op1: GalileanRotation, op2: GalileanRotation) GalileanRotation
Parameters:

op (Any)

Return type:

Any

Combine two Galilean rotations.

Examples

>>> import quaxed.numpy as jnp
>>> import unxt as u
>>> import coordinax as cx

Two rotations can be combined:

>>> theta1 = u.Quantity(45, "deg")
>>> Rz1 = jnp.asarray([[jnp.cos(theta1), -jnp.sin(theta1), 0],
...                   [jnp.sin(theta1), jnp.cos(theta1),  0],
...                   [0,             0,              1]])
>>> op1 = cx.ops.GalileanRotation(Rz1)
>>> theta2 = u.Quantity(60, "deg")
>>> Rz2 = jnp.asarray([[jnp.cos(theta2), -jnp.sin(theta2), 0],
...                   [jnp.sin(theta2), jnp.cos(theta2),  0],
...                   [0,             0,              1]])
>>> op2 = cx.ops.GalileanRotation(Rz2)
>>> op3 = cx.ops.simplify_op(op1, op2)
>>> op3
GalileanRotation(rotation=f32[3,3])
>>> jnp.allclose(op3.rotation, op1.rotation @ op2.rotation)
Array(True, dtype=bool)
coordinax.ops.simplify_op(op: GalileanSpatialTranslation, /, **kwargs: Any) GalileanSpatialTranslation | Identity
Parameters:

op (Any)

Return type:

Any

Simplify a Galilean spatial translation operator.

Examples

>>> import coordinax as cx

An operator with real effect cannot be simplified:

>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "m")
>>> cx.ops.simplify_op(op)
GalileanSpatialTranslation(CartesianPos3D( ... ))

An operator with no effect can be simplified:

>>> op = cx.ops.GalileanSpatialTranslation.from_([0, 0, 0], "m")
>>> cx.ops.simplify_op(op)
Identity()
coordinax.ops.simplify_op(op1: GalileanSpatialTranslation, op2: GalileanSpatialTranslation, /) GalileanSpatialTranslation
Parameters:

op (Any)

Return type:

Any

Combine two spatial translations into a single translation.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> op1 = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "km")
>>> op2 = cx.ops.GalileanSpatialTranslation.from_([0, 1, 0], "km")
>>> op3 = cx.ops.simplify_op(op1, op2)
>>> op3
GalileanSpatialTranslation(CartesianPos3D( ... ))
>>> op3.delta_q == op1.delta_q + op2.delta_q
Array(True, dtype=bool)
coordinax.ops.simplify_op(op: GalileanTranslation, /, **kwargs: Any) GalileanTranslation | Identity
Parameters:

op (Any)

Return type:

Any

Simplify a Galilean translation operator.

Examples

>>> import coordinax.ops as cxo

An operator with real effect cannot be simplified:

>>> op = cxo.GalileanTranslation.from_([3e8, 1, 0, 0], "m")
>>> cxo.simplify_op(op)
GalileanTranslation(
  delta_t=Quantity(f32[], unit='m s / km'),
  delta_q=CartesianPos3D( ... )
)

An operator with no effect can be simplified:

>>> op = cxo.GalileanTranslation.from_([0, 0, 0, 0], "m")
>>> cxo.simplify_op(op)
Identity()
coordinax.ops.simplify_op(op1: GalileanTranslation, op2: GalileanTranslation, /) GalileanTranslation
Parameters:

op (Any)

Return type:

Any

Combine two translations into a single translation.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> qshift = cx.CartesianPos3D.from_([1, 0, 0], "km")
>>> tshift = u.Quantity(1, "Gyr")
>>> op1 = cx.ops.GalileanTranslation(tshift, qshift)
>>> qshift = cx.CartesianPos3D.from_([0, 1, 0], "km")
>>> op2 = cx.ops.GalileanTranslation(tshift, qshift)
>>> op3 = cx.ops.simplify_op(op1, op2)
>>> op3
GalileanTranslation(
  delta_t=Quantity(weak_i32[], unit='Gyr'),
  delta_q=CartesianPos3D( ... )
)
coordinax.ops.simplify_op(op: GalileanOperator, /, **kwargs: Any) GalileanOperator | Pipe | GalileanBoost | GalileanRotation | GalileanTranslation | GalileanSpatialTranslation | Identity
Parameters:

op (Any)

Return type:

Any

Simplify a Galilean operator.

Examples

>>> import jax.numpy as jnp
>>> import unxt as u
>>> import coordinax.ops as cxo

This Galilean operator cannot be simplified:

>>> op = cxo.GalileanOperator(
...     translation=u.Quantity([0., 2., 3., 4.], "km"),
...     velocity=u.Quantity([1., 2., 3.], "km/s"),
...     rotation=jnp.eye(3).at[0, 2].set(1),
... )
>>> op
GalileanOperator(
  rotation=GalileanRotation(rotation=f32[3,3]),
  translation=GalileanTranslation( delta_t=..., delta_q=... ),
  velocity=GalileanBoost(CartesianVel3D( ... ))
)
>>> cxo.simplify_op(op) is op
True

This Galilean operator can be simplified in all its components except the translation:

>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> cxo.simplify_op(op)
GalileanTranslation( delta_t=..., delta_q=CartesianPos3D( ... ) )
coordinax.ops.simplify_op(op: AbstractOperator, /) AbstractOperator
Parameters:

op (Any)

Return type:

Any

Return the operator unchanged.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "m")
>>> cx.ops.simplify_op(op) is op
True
coordinax.ops.simplify_op(op: Identity, /) Identity
Parameters:

op (Any)

Return type:

Any

Return the operator unchanged.

Examples

>>> import coordinax as cx
>>> op = cx.ops.Identity()
>>> cx.ops.simplify_op(op) is op
True
coordinax.ops.simplify_op(seq: Pipe, /) AbstractOperator
Parameters:

op (Any)

Return type:

Any

Simplify a sequence of Operators.

This simplifies the sequence of operators by removing any that reduce to the Identity operator.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> shift = cx.ops.GalileanSpatialTranslation(u.Quantity([1, 2, 3], "km"))
>>> boost = cx.ops.GalileanBoost(u.Quantity([10, 20, 30], "km/s"))
>>> seq = shift | cx.ops.Identity() | boost
>>> seq
Pipe((
    GalileanSpatialTranslation(...), Identity(), GalileanBoost(...)
))
>>> cx.ops.simplify_op(seq)
Pipe(( GalileanSpatialTranslation(...), GalileanBoost(...) ))
coordinax.ops.simplify_op(op1: AbstractOperator, op2: AbstractOperator, /) Pipe
Parameters:

op (Any)

Return type:

Any

Simplify two operators into a sequence.

Examples

>>> import coordinax as cx
>>> op1 = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "m")
>>> op2 = cx.ops.GalileanBoost.from_([0, 1, 0], "m/s")
>>> cx.ops.simplify_op(op1, op2)
Pipe((
    GalileanSpatialTranslation(CartesianPos3D( ... )),
    GalileanBoost(CartesianVel3D( ... ))
))
coordinax.ops.simplify_op(op1: AbstractOperator, op2: AbstractOperator) AbstractOperator
Parameters:

op (Any)

Return type:

Any

Simplify an operator with the identity.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "m")
>>> cx.ops.simplify_op(op, cx.ops.Identity())
GalileanSpatialTranslation(...)
>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 0, 0], "m")
>>> cx.ops.simplify_op(cx.ops.Identity(), op)
GalileanSpatialTranslation(...)
coordinax.ops.simplify_op(op1: Pipe, op2: AbstractOperator) Pipe
Parameters:

op (Any)

Return type:

Any

Simplify two sequences of operators by concatenating them.

Examples

>>> import coordinax as cx
>>> sop1 = cx.ops.Pipe((cx.ops.Identity(), cx.ops.Identity()))
>>> sop2 = cx.ops.Pipe((cx.ops.Identity(),))
>>> cx.ops.simplify_op(sop1, sop2)
Pipe((Identity(), Identity(), Identity()))
coordinax.ops.simplify_op(op1: Pipe, op2: Pipe) Pipe
Parameters:

op (Any)

Return type:

Any

Simplify two sequences of operators by concatenating them.

Examples

>>> import coordinax as cx
>>> sop1 = cx.ops.Pipe((cx.ops.Identity(), cx.ops.Identity()))
>>> sop2 = cx.ops.Pipe((cx.ops.Identity(),))
>>> cx.ops.simplify_op(sop1, sop2)
Pipe((Identity(), Identity(), Identity()))
Parameters:

op (Any)

Return type:

Any

class coordinax.ops.AbstractOperator#

Bases: Module

Abstract base class for operators on coordinates and potentials.

An operator is an object that defines a transformation on coordinates. It can be applied to a set of coordinates to produce a new set of coordinates. Operators can be composed together to form a sequence of transformations.

When defining a new operator, it should be able to work on the following types with the following semantics:

  • coordinax.vecs.AbstractVector objects. No restrictions are placed on the these arguments, except that if the operator works on coordinax.vecs.AbstractPos and coordinax.vecs.AbstractVel objects, the former should precede the latter.

  • Time arguments come first, followed by spatial arguments.

  • It should work on a set of jax.Array objects. If the jax.Array is a coordinate vector then it is Cartesian and the last axis is the component axis and prior axes are the batch axes.

  • It should work on unxt.Quantity objects.

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

abstract property inverse: AbstractOperator#

The inverse of the operator.

abstract property is_inertial: bool#

Whether the operation maintains an inertial reference frame.

simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
class coordinax.ops.Identity#

Bases: AbstractOperator

Identity operation.

This is the identity operation, which does nothing to the input.

Examples

We will work through many of the registered call signatures for the Identity class. Note that more call signatures may be registered.

First, we make an instance of the operator:

>>> import unxt as u
>>> import coordinax as cx
>>> op = cx.ops.Identity()
>>> op
Identity()

And the common objects we will use:

>>> q = u.Quantity([1, 2, 3], "km")
>>> vec = cx.CartesianPos3D.from_(q)

The first call signature is for the case where the input is a vector:

>>> op(vec) is vec
True

The second call signature is for a Quantity:

>>> op(q) is q
True

Actually, the Identity operator works for any vector or quantity:

  • 1D:

>>> q = u.Quantity([1], "km")
>>> vec = cx.vecs.CartesianPos1D.from_(q)
>>> op(vec) is vec and op(q) is q
True
  • 2D:

>>> q = u.Quantity([1, 2], "km")
>>> vec = cx.vecs.CartesianPos2D.from_(q)
>>> op(vec) is vec and op(q) is q
True
  • 3D: (not using a ~coordinax.CartesianPos3D instance):

>>> q = u.Quantity([1, 2, 3], "km")
>>> vec = cx.CartesianPos3D.from_(q).vconvert(cx.SphericalPos)
>>> op(vec) is vec and op(q) is q
True
  • 4D:

>>> q = u.Quantity([1, 2, 3, 4], "km")  # 0th elt is ct
>>> vec4 = cx.FourVector.from_(q)
>>> op(vec4) is vec4 and op(q) is q
True

Lastly, many operators are time dependent and support a time argument. The` Identity operator will also pass through the time argument:

>>> t = u.Quantity(0, "Gyr")
>>> op(t, vec) == (t, vec)
True
>>> q = u.Quantity([1, 2, 3], "km")
>>> op(t, q) == (t, q)
True
classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: Identity#

The inverse of the operator.

Examples

>>> import coordinax as cx
>>> op = cx.ops.Identity()
>>> op.inverse
Identity()
>>> op.inverse is op
True
property is_inertial: Literal[True]#

Identity operation is an inertial-frame preserving transform.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> op = cx.ops.Identity()
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
class coordinax.ops.AbstractCompositeOperator#

Bases: AbstractOperator

Abstract Composite Operator.

This is the base class for all composite operations.

See also

None, None

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: Pipe#

The inverse of the operator.

This is the sequence of the inverse of each operator in reverse order.

Examples

>>> import coordinax as cx
>>> shift = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> boost = cx.ops.GalileanBoost.from_([1, 2, 3], "km/s")
>>> pipe = cx.ops.Pipe((shift, boost))
>>> pipe.inverse
Pipe(( GalileanBoost(...), GalileanSpatialTranslation(...) ))
:param self:
:type self: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~coordinax.\_src.operators.composite.AbstractCompositeOperator\``
property is_inertial: bool#

Whether the operations maintain an inertial reference frame. :param self: :type self: HasOperatorsAttr

simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
operators: AbstractVar[tuple[AbstractOperator, ...]]#
class coordinax.ops.Pipe(operators: Any)#

Bases: AbstractCompositeOperator

Operator Pipe.

Piping refers to a process in which the output of one operation is directly passed as the input to another. This is a composite operator that represents a sequence of operations to be applied in order.

Pipe operators can be created using the β€˜pipe’ syntax op1 | op2. A Pipe operator created as FG = F | G, when evaluated, is equivalent to evaluating $g circ f = g(f(x))$. Note the order of the operators!

:::{note}

The | operator works differently from the functional composition operator $circ$, which is sadly not supported in Python. The | operator is like the Unix Shell pipe operator, where output is passed left-to-right. This order can be seen in the indexing of the operators in the Pipe object.

::

:type operators: :sphinx_autodoc_typehints_type:`\:py\:data\:\`\~typing.Any\``
:param operators: The sequence of operators to apply.

Examples

>>> import coordinax as cx
>>> shift = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> boost = cx.ops.VelocityBoost.from_([1, 2, 3], "km/s")
>>> pipe = cx.ops.Pipe((shift, boost))
>>> pipe
Pipe(( GalileanSpatialTranslation(...), VelocityBoost(...) ))

A pipe can also be constructed by |:

>>> pipe2 = shift | boost
>>> pipe2
Pipe(( GalileanSpatialTranslation(...), VelocityBoost(...) ))

The pipe can be simplified. For this example, we add an identity operator to the sequence and simplify, which will remove the identity operator.

>>> pipe3 = pipe2 | cx.ops.Identity()
>>> pipe3
Pipe((
    GalileanSpatialTranslation(...), VelocityBoost(...), Identity()
))
>>> cx.ops.simplify_op(pipe3)
Pipe(( GalileanSpatialTranslation(...), VelocityBoost(...) ))

Now let’s call the operator on a position:

>>> pos = cx.CartesianPos3D.from_([1, 2, 3], "km")
>>> print(pipe(pos))
<CartesianPos3D: (x, y, z) [km]
    [2 4 6]>

The pipe will also work on a position + velocity:

>>> vel = cx.CartesianVel3D.from_([4, 5, 6], "km/s")
>>> print(*pipe(pos, vel), sep="\n")
<CartesianPos3D: (x, y, z) [km]
    [2 4 6]>
<CartesianVel3D: (x, y, z) [km / s]
    [5. 7. 9.]>
Parameters:

operators (tuple[AbstractOperator, ...])

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: Pipe#

The inverse of the operator.

This is the sequence of the inverse of each operator in reverse order.

Examples

>>> import coordinax as cx
>>> shift = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> boost = cx.ops.GalileanBoost.from_([1, 2, 3], "km/s")
>>> pipe = cx.ops.Pipe((shift, boost))
>>> pipe.inverse
Pipe(( GalileanBoost(...), GalileanSpatialTranslation(...) ))
:param self:
:type self: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~coordinax.\_src.operators.composite.AbstractCompositeOperator\``
property is_inertial: bool#

Whether the operations maintain an inertial reference frame. :param self: :type self: HasOperatorsAttr

simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
operators: tuple[AbstractOperator, ...]#
class coordinax.ops.AbstractGalileanOperator#

Bases: AbstractOperator

Abstract base class for Galilean operators on potentials.

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

abstract property inverse: AbstractOperator#

The inverse of the operator.

abstract property is_inertial: bool#

Whether the operation maintains an inertial reference frame.

simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
class coordinax.ops.GalileanBoost(velocity: ArgT | PassThroughTs)#

Bases: AbstractGalileanOperator

Operator for Galilean boosts.

The operation is given by:

\[(t,\mathbf{x}) \mapsto (t, \mathbf{x} + \mathbf{v} t)\]

where \(\mathbf{v}\) is the boost velocity.

Parameters:

velocity (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The boost velocity. This parameters uses coordinax.vecs.CartesianVel3D.from_() to enable a variety of more convenient input types.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanBoost.from_([1.0, 2.0, 3.0], "m/s")
>>> op
GalileanBoost(CartesianVel3D( ... ))
>>> vec = cx.CartesianPos3D.from_([0.0, 0.0, 0.0], "m")
>>> delta_t = u.Quantity(1.0, "s")
>>> _, newvec = op(delta_t, vec)
>>> print(newvec)
<CartesianPos3D: (x, y, z) [m]
    [1. 2. 3.]>

In the context of frame transformations, a Galilean boost is treated as the velocity of the new frame relative to the old frame. This means that the transformation is the same as the inverse of the boost velocity. In other words,

\[(t,\mathbf{x}) \mapsto (t, \mathbf{x} - \mathbf{v} t)\]

This can be applied using the .inverse property.

>>> _, vec_in_newframe = op.inverse(delta_t, vec)
>>> print(vec_in_newframe)
<CartesianPos3D: (x, y, z) [m]
    [-1. -2. -3.]>
classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: GalileanBoost#

The inverse of the operator.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanBoost.from_([1, 2, 3], "m/s")
>>> op.inverse
GalileanBoost(CartesianVel3D( ... ))
>>> print(op.inverse.velocity)
<CartesianVel3D: (x, y, z) [m / s]
    [-1 -2 -3]>
property is_inertial: Literal[True]#

Galilean boost is an inertial-frame preserving transform.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanBoost.from_([1, 2, 3], "m/s")
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
velocity: AbstractVel#

The boost velocity.

Unless given a coordinax.AbstractVel, this parameter uses coordinax.CartesianVel3D.from_() to enable a variety of more convenient input types. See coordinax.CartesianVel3D for details.

class coordinax.ops.GalileanOperator(rotation: ~dataclassish._src.converters.ArgT | ~dataclassish._src.converters.PassThroughTs = GalileanRotation(rotation=f32[3, 3]), translation: ~dataclassish._src.converters.ArgT | ~dataclassish._src.converters.PassThroughTs = GalileanTranslation(   delta_t=Quantity(weak_f32[], unit='s'), delta_q=CartesianPos3D(     x=Quantity(i32[], unit='km'), y=Quantity(i32[], unit='km'), z=Quantity(i32[], unit='km')   ) ), velocity: ~dataclassish._src.converters.ArgT | ~dataclassish._src.converters.PassThroughTs = GalileanBoost(CartesianVel3D(   x=Quantity(i32[], unit='km / s'), y=Quantity(i32[], unit='km / s'), z=Quantity(i32[], unit='km / s') )))#

Bases: AbstractCompositeOperator, AbstractGalileanOperator

Operator for general Galilean transformations.

In the transformed frame the coordinates are given by:

\[(t,\mathbf{x}) \mapsto (t+s, R \mathbf{x} + \mathbf{v} t + \mathbf{a})\]

where \(R\) is the rotation matrix, \(\mathbf{v}\) is the boost velocity, \(\mathbf{a}\) is the spatial translationl, and \(s\) is the time translation. This is equivalent to a sequential operation of 1. a rotation, 2. a translation, 3. a boost.

Parameters:
  • rotation (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The in-frame spatial rotation. This is a coordinax.ops.GalileanRotation

  • translation (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The spatial translation of the frame. See coordinax.ops.GalileanTranslation for alternative inputs to construct this parameter.

  • velocity (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The boost to the frame. See coordinax.ops.GalileanBoost for alternative inputs to construct this parameter.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> op = cx.ops.GalileanOperator(
...     translation=u.Quantity([0., 2., 3., 4.], "km"),
...     velocity=u.Quantity([1., 2., 3.], "km/s"))
>>> op
GalileanOperator(
  translation=GalileanTranslation( delta_t=..., delta_q=... ),
  velocity=GalileanBoost(CartesianVel3D( ... ))
)

Note that the translation is a coordinax.ops.GalileanTranslation with a coordinax.vecs.FourVector translation, and the velocity is a coordinax.ops.GalileanBoost with a coordinax.vecs.AbstractVel velocity. We can also construct them directly, which allows for other vector types.

>>> op = cx.ops.GalileanOperator(
...     translation=cx.ops.GalileanTranslation(
...         delta_t=u.Quantity(2.5, "Gyr"),
...         delta_q=cx.SphericalPos(r=u.Quantity(1, "km"),
...                                 theta=u.Quantity(90, "deg"),
...                                 phi=u.Quantity(0, "rad") ) ),
...     velocity=cx.ops.GalileanBoost(
...         cx.CartesianVel3D.from_([1, 2, 3], "km/s") )
... )
>>> op
GalileanOperator(
  translation=GalileanTranslation( delta_t=..., delta_q=SphericalPos( ... ) ),
  velocity=GalileanBoost(CartesianVel3D( ... ))
)

Galilean operators can be applied to coordinax.vecs.FourVector:

>>> w = cx.FourVector.from_([0, 0, 0, 0], "km")
>>> new = op(w)
>>> new.t.ustrip("Gyr").round(2)
Array(2.5, dtype=float32, ...)
>>> print(new.q)
<CartesianPos3D: (x, y, z) [km]
    [7.889e+16 1.578e+17 2.367e+17]>

Also the Galilean operators can also be applied to vector.AbstractPos3D and unxt.Quantity:

>>> q = cx.CartesianPos3D.from_([0, 0, 0], "km")
>>> t = u.Quantity(0, "s")
>>> newt, newq = op(t, q)
>>> print(newq)
<CartesianPos3D: (x, y, z) [km]
    [7.889e+16 1.578e+17 2.367e+17]>
>>> newt
Quantity(Array(7.8894005e+16, dtype=float32, ...), unit='s')
classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: Pipe#

The inverse of the operator.

This is the sequence of the inverse of each operator in reverse order.

Examples

>>> import coordinax as cx
>>> shift = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> boost = cx.ops.GalileanBoost.from_([1, 2, 3], "km/s")
>>> pipe = cx.ops.Pipe((shift, boost))
>>> pipe.inverse
Pipe(( GalileanBoost(...), GalileanSpatialTranslation(...) ))
:param self:
:type self: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~coordinax.\_src.operators.composite.AbstractCompositeOperator\``
property is_inertial: bool#

Whether the operations maintain an inertial reference frame. :param self: :type self: HasOperatorsAttr

property operators: tuple[GalileanRotation, GalileanTranslation, GalileanBoost]#

Rotation -> translation -> boost.

rotation(*args: Any, **kwargs: Any): GalileanRotation = GalileanRotation(rotation=f32[3,3])#

The in-frame spatial rotation.

Parameters:
Return type:

AbstractPos

simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
translation(*args: Any, **kwargs: Any): GalileanTranslation = GalileanTranslation(   delta_t=Quantity(weak_f32[], unit='s'),   delta_q=CartesianPos3D(     x=Quantity(i32[], unit='km'),     y=Quantity(i32[], unit='km'),     z=Quantity(i32[], unit='km')   ) )#

The temporal + spatial translation.

The translation vector [T, Q]. This parameters accepts either a coordinax.ops.GalileanTranslation instance or any input that can be used to construct a coordinax.vecs.FourVector, using coordinax.vecs.FourVector.from_. See coordinax.vecs.FourVector for details.

Parameters:
Return type:

AbstractPos

velocity(*args: Any, **kwargs: Any): GalileanBoost = GalileanBoost(CartesianVel3D(   x=Quantity(i32[], unit='km / s'),   y=Quantity(i32[], unit='km / s'),   z=Quantity(i32[], unit='km / s') ))#

The boost to the frame.

This parameters accepts either a coordinax.ops.GalileanBoost instance or any input that can be used to construct one. See coordinax.ops.GalileanBoost.from_ for details.

Parameters:
Return type:

AbstractPos

class coordinax.ops.GalileanRotation(rotation: Any, check_tol: Any = (('atol', 1e-07),))#

Bases: AbstractGalileanOperator

Operator for Galilean rotations.

The coordinate transform is given by:

\[(t,\mathbf{x}) \mapsto (t, R \mathbf{x})\]

where \(R\) is the rotation matrix. Note this is NOT time dependent.

Parameters:
  • rotation (Array[float, (3, 3)]) – The rotation matrix.

  • check_tol (Mapping[str, Any])

Raises:

ValueError – If the rotation matrix is not orthogonal.

Notes

The Galilean rotation is not a time-dependent transformation. This is part of the inhomogeneous Galilean group, which is the group of transformations that leave the space-time interval invariant.

Examples

We start with the required imports:

>>> import jax.numpy as jnp
>>> import unxt as u
>>> import coordinax as cx

We can then create a rotation operator:

>>> Rz = jnp.asarray([[0, -1, 0], [1, 0,  0], [0, 0, 1]])
>>> op = cx.ops.GalileanRotation(Rz)
>>> op
GalileanRotation(rotation=i32[3,3])

Translation operators can be applied to a Quantity[float, (N, 3), β€œβ€¦]:

>>> q = u.Quantity([1, 0, 0], "m")
>>> t = u.Quantity(1, "s")
>>> newt, newq = op(t, q)
>>> newq
Quantity(Array([0, 1, 0], dtype=int32), unit='m')

The time is not affected by the rotation.

>>> newt
Quantity(Array(1, dtype=int32, ...), unit='s')

This also works for a batch of vectors:

>>> q = u.Quantity([[1, 0, 0], [0, 1, 0]], "m")
>>> t = u.Quantity(0, "s")
>>> newt, newq = op(t, q)
>>> newq
Quantity(Array([[ 0,  1,  0],
                [-1,  0,  0]], dtype=int32), unit='m')

Translation operators can be applied to vector.AbstractPos3D:

>>> q = cx.CartesianPos3D.from_(q)  # from the previous example
>>> newt, newq = op(t, q)
>>> newq.x
Quantity(Array([ 0, -1], dtype=int32), unit='m')
>>> newq.norm().value.round(2)
Array([1., 1.], dtype=float32)
Parameters:
  • check_tol (Any)

  • rotation (Shaped[Array, '3 3'])

check_tol: Mapping[str, Any] = (('atol', 1e-07),)#

Tolerance check on the rotation matrix.

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

classmethod from_euler(seq: str, angles: Quantity[PhysicalType('angle')] | Angle, /)#

Initialize from Euler angles.

See jax.scipy.spatial.transform.Rotation.from_euler. XYZ are intrinsic rotations, xyz are extrinsic rotations.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> op = cx.ops.GalileanRotation.from_euler("z", u.Quantity(90, "deg"))
>>> op.rotation.round(2)
Array([[ 0., -1.,  0.],
       [ 1.,  0.,  0.],
       [ 0.,  0.,  1.]], dtype=float32)
Parameters:
  • seq (str)

  • angles (Quantity[PhysicalType('angle')] | Angle)

Return type:

GalileanRotation

property inverse: GalileanRotation#

The inverse of the operator.

Examples

>>> import quaxed.numpy as jnp
>>> import coordinax as cx
>>> Rz = jnp.asarray([[0, -1, 0], [1, 0,  0], [0, 0, 1]])
>>> op = cx.ops.GalileanRotation(Rz)
>>> op.inverse
GalileanRotation(rotation=i32[3,3])
>>> jnp.allclose(op.rotation, op.inverse.rotation.T)
Array(True, dtype=bool)
property is_inertial: Literal[True]#

Galilean rotation is an inertial-frame preserving transform.

Examples

>>> import quaxed.numpy as jnp
>>> import coordinax as cx
>>> Rz = jnp.asarray([[0, -1, 0], [1, 0,  0], [0, 0, 1]])
>>> op = cx.ops.GalileanRotation(Rz)
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
rotation: Shaped[Array, '3 3']#

The rotation vector.

class coordinax.ops.GalileanSpatialTranslation(delta_q: Any)#

Bases: AbstractGalileanOperator

Operator for Galilean spatial translations.

The coordinate transform is given by:

\[(t,\mathbf{x}) \mapsto (t+s, \mathbf{x} + \mathbf {a})\]
Parameters:
  • translation – The spatial translation vector. This parameters accepts either a vector.AbstractPos3D instance or uses coordinax.vecs.CartesianPos3D.from_ to enable a variety of more convenient input types to create a Cartesian vector. See coordinax.vecs.CartesianPos3D for details.

  • delta_q (AbstractPos)

Examples

>>> import quaxed.numpy as jnp
>>> import unxt as u
>>> import coordinax as cx

We can then create a spatial translation operator:

>>> op = cx.ops.GalileanSpatialTranslation.from_([1.0, 2.0, 3.0], "km")
>>> op
GalileanSpatialTranslation(CartesianPos3D( ... ))

Note that the translation is a coordinax.vecs.CartesianPos3D, which was constructed from a 1D array, using coordinax.vecs.CartesianPos3D.from_. We can also construct it directly, which allows for other vector types.

>>> shift = cx.SphericalPos(r=u.Quantity(1.0, "km"),
...                         theta=u.Quantity(jnp.pi/2, "rad"),
...                         phi=u.Quantity(0, "rad"))
>>> op = cx.ops.GalileanSpatialTranslation(shift)
>>> op
GalileanSpatialTranslation(SphericalPos( ... ))

Translation operators can be applied to any vector.AbstractPos:

>>> q = cx.CartesianPos3D.from_([0, 0, 0], "km")
>>> op(q)
CartesianPos3D( ... )

Actually, the operator is very flexible and can be applied to many types of input. Let’s work up the type ladder:

  • unxt.Quantity:

>>> q = u.Quantity([0, 0, 0], "km")
>>> op(q).value.round(2)
Array([ 1.,  0., -0.], dtype=float32)

coordinax.ops.GalileanSpatialTranslation can be used for other dimensional vectors as well:

  • 1D:

>>> op = cx.ops.GalileanSpatialTranslation.from_([1], "km")
>>> q = u.Quantity([0], "km")
>>> op(q)
Quantity(Array([1], dtype=int32), unit='km')
>>> vec = cx.vecs.CartesianPos1D.from_(q).vconvert(cx.vecs.RadialPos)
>>> op(vec)
RadialPos(r=Distance(1, unit='km'))
  • 2D:

>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 2], "km")
>>> q = u.Quantity([0, 0], "km")
>>> op(q)
Quantity(Array([1, 2], dtype=int32), unit='km')
>>> vec = cx.vecs.CartesianPos2D.from_(q).vconvert(cx.vecs.PolarPos)
>>> op(vec)
PolarPos(r=Distance(2.236068, unit='km'), phi=Angle(1.1071488, unit='rad'))
  • 3D:

>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> q = u.Quantity([0, 0, 0], "km")
>>> op(q)
Quantity(Array([1, 2, 3], dtype=int32), unit='km')
>>> vec = cx.CartesianPos3D.from_(q).vconvert(cx.SphericalPos)
>>> op(vec)
SphericalPos(
  r=Distance(3.7416575, unit='km'),
  theta=Angle(0.64052236, unit='rad'),
  phi=Angle(1.1071488, unit='rad')
)

Many operators are time dependent and require a time argument. This operator is time independent and will pass through the time argument:

>>> t = u.Quantity(0, "Gyr")
>>> op(t, q)[0] is t
True

coordinax.ops.GalileanSpatialTranslation can be applied to other input types. Let’s work up the type ladder:

  • jax.Array: Note that since the operator is unitful but the

>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 2, 3], "km")
>>> q = jnp.array([0, 0, 0])
Parameters:

delta_q (Any)

classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: GalileanSpatialTranslation#

The inverse of the operator.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> op.inverse
GalileanSpatialTranslation(CartesianPos3D( ... ))
>>> print(op.inverse.delta_q)
<CartesianPos3D: (x, y, z) [km]
    [-1 -1 -1]>
property is_inertial: Literal[True]#

Galilean translation is an inertial frame-preserving transformation.

Examples

>>> import coordinax.ops as cxo
>>> op = GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
delta_q: AbstractPos#

The spatial translation.

This parameters accepts either a vector.AbstractVector instance or uses a Cartesian vector from_ to enable a variety of more convenient input types to create a Cartesian vector. See coordinax.vecs.CartesianPos3D.from_ for an example when doing a 3D translation.

class coordinax.ops.GalileanTranslation(delta_t: Any, delta_q: ArgT | PassThroughTs)#

Bases: AbstractGalileanOperator

Operator for spatio-temporal translations.

The coordinate transform is given by:

\[(t,\mathbf{x}) \mapsto (t+s, \mathbf{x} + \mathbf {a})\]

where \(a \in R^3\) and \(s \in R\). Therefore for a potential \(\Phi(t,\mathbf{x})\) in the translated frame the potential is given by the subtraction of the translation.

Parameters:
  • delta_t (Any) – The time translation.

  • delta_q (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The spatial translation vector.

Examples

>>> import jax.numpy as jnp
>>> import unxt as u
>>> import coordinax as cx

We can then create a translation operator:

>>> op = cx.ops.GalileanTranslation.from_([1.0, 2.0, 3.0, 4.0], "km")
>>> op
GalileanTranslation(
  delta_t=Quantity(f32[], unit='s'),
  delta_q=CartesianPos3D( ... )
)

Note that the translation is a unxt.Quantity and a coordinax.vecs.AbstractPos, which was constructed from a 1D array, using coordinax.vecs.AbstractPos.from_(). We can also construct it directly, which allows for other vector types.

>>> qshift = cx.SphericalPos(r=u.Quantity(1.0, "km"),
...                          theta=u.Quantity(jnp.pi/2, "rad"),
...                          phi=u.Quantity(0, "rad"))
>>> op = cx.ops.GalileanTranslation(u.Quantity(1.0, "Gyr"), qshift)
>>> op
GalileanTranslation(
  delta_t=Quantity(weak_f32[], unit='Gyr'),
  delta_q=SphericalPos( ... )
)

Translation operators can be applied to coordinax.vecs.AbstractPos and unxt.Quantity:

>>> q = cx.CartesianPos3D.from_([0, 0, 0], "km")
>>> t = u.Quantity(0, "Gyr")
>>> newt, newq = op(t, q)
>>> newq.x
Quantity(Array(1., dtype=float32, ...), unit='km')
>>> newt
Quantity(Array(1., dtype=float32, ...), unit='Gyr')
classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: GalileanTranslation#

The inverse of the operator.

Examples

>>> import unxt as u
>>> import coordinax as cx
>>> qshift = cx.CartesianPos3D.from_([1, 1, 1], "km")
>>> op = cx.ops.GalileanTranslation(u.Quantity(1, "Gyr"), qshift)
>>> print(op.inverse)
GalileanTranslation(
    delta_t=Quantity(-1, unit='Gyr'),
    delta_q=<CartesianPos3D: (x, y, z) [km]
        [-1 -1 -1]>
)
property is_inertial: Literal[True]#

Galilean translation is an inertial-frame preserving transformation.

Examples

>>> import coordinax as cx
>>> op = cx.ops.GalileanTranslation.from_([0, 1, 1, 1], "km")
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
delta_t: Quantity[PhysicalType('time')]#

The time translation.

This parameter uses unxt.Quantity.from_() to enable a variety of more convenient input types. See unxt.Quantity for details.

delta_q: AbstractPos#

The spatial translation.

This parameters uses coordinax.vecs.CartesianPos3D.from_() to enable a variety of more convenient input types. See coordinax.vecs.CartesianPos3D for details.

class coordinax.ops.VelocityBoost(velocity: ArgT | PassThroughTs)#

Bases: AbstractOperator

Operator for an instantaneous velocity boost.

The operation is given by:

\[(\mathbf{v}) \mapsto (\mathbf{v} + \Delta\mathbf{v})\]

where \(\Delta\mathbf{v}\) is the boost velocity.

Parameters:

velocity (Union[TypeVar(ArgT), TypeVar(PassThroughTs)]) – The boost velocity. This parameters uses coordinax.vecs.CartesianVel3D.from_() to enable a variety of more convenient input types.

Examples

>>> import coordinax as cx
>>> op = cx.ops.VelocityBoost.from_([1.0, 2.0, 3.0], "m/s")
>>> op
VelocityBoost(CartesianVel3D( ... ))
>>> q = cx.CartesianPos3D.from_([0.0, 0.0, 0.0], "m")
>>> op(q) is q
True
>>> p = cx.CartesianVel3D.from_([0., 0, 0], "m/s")
>>> op(p) == p + op.velocity
Array(True, dtype=bool)
classmethod from_(cls: type[AbstractOperator], *args: object, **kwargs: object)#

Construct from a set of arguments.

from_(cls: type[AbstractOperator], *args: object, **kwargs: object) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a set of arguments.

This is a low-priority dispatch that will be called if no other dispatch is found. It just tries to pass the arguments to the constructor.

from_(cls: type[AbstractOperator], obj: Mapping[str, Any], /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a mapping.

Examples

>>> import coordinax.ops as cxo
>>> pipe = cxo.Identity() | cxo.Identity()
>>> cxo.Pipe.from_({"operators": pipe})
Pipe((Identity(), Identity()))
from_(cls: type[AbstractOperator], x: ArrayLike | list[float | int], unit: str, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct from a Quantity’s value and unit.

Examples

>>> import coordinax.ops as cxo
>>> op = cxo.GalileanSpatialTranslation.from_([1, 1, 1], "km")
>>> print(op)
GalileanSpatialTranslation(<CartesianPos3D: (x, y, z) [km]
    [1 1 1]>)
>>> op = cxo.GalileanTranslation.from_([3e5, 1, 1, 1], "km")
>>> print(op)
GalileanTranslation(
  delta_t=Quantity(1.0006922, unit='s'),
  delta_q=<CartesianPos3D: (x, y, z) [km]
      [1. 1. 1.]>
)
>>> op = cxo.GalileanBoost.from_([1, 1, 1], "km/s")
>>> print(op)
GalileanBoost(<CartesianVel3D: (x, y, z) [km / s]
    [1 1 1]>)
from_(cls: type[AbstractOperator], obj: AbstractOperator, /) AbstractOperator
Parameters:
Return type:

AbstractOperator

Construct an operator from another operator.

Raises:

TypeError – If the input object is not a subclass of the target class.

Parameters:
Return type:

AbstractOperator

Examples

>>> import coordinax as cx

If the object is the same type, it should return the object itself.

>>> op = cx.ops.Identity()
>>> cx.ops.Identity.from_(op) is op
True

If the object is a different type, it will error.

>>> try:
...     cx.ops.GalileanBoost.from_(op)
... except TypeError as e:
...     print(e)
Cannot construct <class 'coordinax...GalileanBoost'> from <class 'coordinax...Identity'>.

Unless the object is a subclass of the target class.

>>> class MyOperator(cx.ops.Identity):
...     pass
>>> op = MyOperator()
>>> op
MyOperator()
>>> newop = cx.ops.Identity.from_(op)
>>> newop is op, isinstance(newop, cx.ops.Identity)
(False, True)
from_(cls: type[GalileanRotation], obj: Rotation, /) GalileanRotation
Parameters:
Return type:

AbstractOperator

Initialize from a jax.scipy.spatial.transform.Rotation.

Examples

>>> import jax.numpy as jnp
>>> from jax.scipy.spatial.transform import Rotation
>>> import coordinax as cx
>>> R = Rotation.from_euler("z", 90, degrees=True)
>>> op = cx.ops.GalileanRotation.from_(R)
>>> jnp.allclose(op.rotation, R.as_matrix())
Array(True, dtype=bool)
from_(cls: type[GalileanTranslation], delta: AbstractQuantity, /) GalileanTranslation
Parameters:
Return type:

AbstractOperator

Construct from a time+space array.

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> q = u.Quantity([1.0, 2.0, 3.0, 4.0], "km")
>>> op = cxo.GalileanTranslation.from_(q)
Parameters:
Return type:

AbstractOperator

property inverse: VelocityBoost#

The inverse of the operator.

Examples

>>> import coordinax as cx
>>> op = cx.ops.VelocityBoost.from_([1, 2, 3], "m/s")
>>> op.inverse
VelocityBoost(CartesianVel3D( ... ))
>>> print(op.inverse.velocity)
<CartesianVel3D: (x, y, z) [m / s]
    [-1 -2 -3]>
property is_inertial: Literal[True]#

Galilean boost is an inertial-frame preserving transform.

Examples

>>> import coordinax as cx
>>> op = cx.ops.VelocityBoost.from_([1, 2, 3], "m/s")
>>> op.is_inertial
True
simplify()#

Simplify the operator.

This method calls coordinax.ops.simplify_op to simplify the operator.

Return type:

AbstractOperator

Examples

>>> import unxt as u
>>> import coordinax.ops as cxo
>>> op = cxo.Identity()
>>> op.simplify() is op
True
>>> op = cxo.Pipe((cxo.Identity(), cxo.Identity()))
>>> op.simplify()
Identity()
>>> op = cxo.GalileanOperator(translation=u.Quantity([0., 2., 3., 4.], "km"))
>>> op.simplify()
GalileanTranslation(
    delta_t=Quantity(f32[], unit='s'),
    delta_q=CartesianPos3D( ... )
)
velocity: AbstractVel#

The boost velocity.

Unless given a coordinax.AbstractVel, this parameter uses coordinax.CartesianVel3D.from_() to enable a variety of more convenient input types.

coordinax.ops.convert_to_pipe_operators(inp: Any, /)#
coordinax.ops.convert_to_pipe_operators(inp: tuple[AbstractOperator, ...] | list[AbstractOperator]) tuple[AbstractOperator, ...]
Parameters:

inp (Any)

Return type:

tuple[AbstractOperator, …]

Convert to a tuple of operators.

Examples

>>> import coordinax as cx
>>> op1 = cx.ops.GalileanRotation([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
>>> op2 = cx.ops.Identity()
>>> convert_to_pipe_operators((op1, op2))
(GalileanRotation(rotation=i32[3,3]), Identity())
coordinax.ops.convert_to_pipe_operators(inp: AbstractOperator) tuple[AbstractOperator, ...]
Parameters:

inp (Any)

Return type:

tuple[AbstractOperator, …]

Convert to a tuple of operators.

Examples

>>> import coordinax as cx
>>> op1 = cx.ops.GalileanRotation([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
>>> convert_to_pipe_operators(op1)
(GalileanRotation(rotation=i32[3,3]),)
coordinax.ops.convert_to_pipe_operators(inp: Pipe) tuple[AbstractOperator, ...]
Parameters:

inp (Any)

Return type:

tuple[AbstractOperator, …]

Convert to a tuple of operators.

Examples

>>> import coordinax as cx
>>> op1 = cx.ops.Identity()
>>> op2 = cx.ops.Identity()
>>> pipe = cx.ops.Pipe((op1, op2))
>>> convert_to_pipe_operators(pipe)
(Identity(), Identity())
Parameters:

inp (Any)

Return type:

tuple[AbstractOperator, ...]