How to convert between units#
unxt offers three levels of conversion, and which one you want depends on what you are holding and what you want back.
You have |
You want back |
Use |
|---|---|---|
a |
a |
|
a |
the bare array in new units |
|
a raw value |
a raw value in new units |
|
Each has both a function form and, where it applies, a method form. See About unxtโs API conventions for why both exist.
>>> import unxt as u
>>> q = u.Q(5, "m")
Convert a quantity#
To keep the units attached, use uconvert. If you prefer an object-oriented style, call the method:
>>> q.uconvert("cm")
Quantity(Array(500., dtype=float32, ...), unit='cm')
To write it functionally โ operator first, operand last โ call the function:
>>> u.uconvert("cm", q)
Quantity(Array(500., dtype=float32, ...), unit='cm')
If you are porting code from astropy, the .to method is available and does the same thing:
>>> q.to("cm")
Quantity(Array(500., dtype=float32, ...), unit='cm')
Converting between incompatible dimensions raises:
>>> try: q.uconvert("s")
... except Exception as e: print(e)
'm' (length) and 's' (time) are not convertible
Strip the units off#
To drop out of unxt and back into plain JAX โ at an I/O boundary, or before handing an array to a library that does not understand quantities โ use ustrip. It converts and unwraps in one step, so the unit you name is the unit the numbers are in:
>>> u.ustrip("cm", q)
Array(500., dtype=float32, ...)
or as a method:
>>> q.ustrip("cm")
Array(500., dtype=float32, ...)
The astropy spelling .to_value also works:
>>> q.to_value("cm")
Array(500., dtype=float32, ...)
ustrip is also how you hand a quantity to code that does not understand units at all. A dimensionful Quantity refuses to become a bare array on its own โ np.asarray(q) raises rather than guess which unit you meant โ so name the unit and the refusal goes away:
>>> import numpy as np
>>> np.asarray(u.ustrip("cm", q))
array(500., dtype=float32)
See The sharp bits for why it refuses.
If your input may be either a quantity or a bare array โ a common signature in library code โ pass the AllowValue flag. A bare array is then taken to be already in the output units and passed through untouched, instead of raising:
>>> u.ustrip(u.quantity.AllowValue, "cm", 500)
500
Convert raw values#
When you never wanted the wrapper in the first place โ inside a jitted kernel, or converting a large batch โ uconvert_value takes from and to units explicitly and works on raw numbers:
>>> u.uconvert_value("km", "m", 1000)
1.0
>>> import jax.numpy as jnp
>>> u.uconvert_value("km", "m", jnp.array([1000, 2000, 5000]))
Array([1., 2., 5.], dtype=float32, ...)
Unit objects work in place of strings:
>>> u.uconvert_value(u.unit("km"), u.unit("m"), 5000)
5.0
Reach for it when you are performing batch conversions, working inside jit, vmap or grad, or want to avoid constructing Quantity objects on a hot path. uconvert delegates to it internally for the numerical step.
For convenience the same function also accepts a Quantity, in which case it just calls uconvert โ so you can migrate a call site to the lower-level function without first rewriting its inputs:
>>> u.uconvert_value("km", "m", q)
Quantity(Array(0.005, dtype=float32, ...), unit='km')
Inside a jitted function it composes as you would expect:
>>> import jax
>>> @jax.jit
... def batch_convert_to_km(values_in_m):
... return u.uconvert_value("km", "m", values_in_m)
>>> batch_convert_to_km(jnp.array([1000., 5000., 10000.]))
Array([ 1., 5., 10.], dtype=float32)
See also#
Quantity โ the full
Quantitysurface.How to interoperate with astropy โ converting with
astropyunits and quantities.How to optimize performance with unitful quantities โ where conversion overhead actually costs you.