unxt 0.1.dev463__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of unxt might be problematic. Click here for more details.
- unxt/__init__.py +79 -0
- unxt/_interop/__init__.py +18 -0
- unxt/_interop/optional_deps.py +13 -0
- unxt/_interop/unxt_interop_astropy/__init__.py +5 -0
- unxt/_interop/unxt_interop_astropy/custom_types.py +12 -0
- unxt/_interop/unxt_interop_astropy/dimensions.py +53 -0
- unxt/_interop/unxt_interop_astropy/quantity.py +308 -0
- unxt/_interop/unxt_interop_astropy/units.py +111 -0
- unxt/_interop/unxt_interop_gala/__init__.py +5 -0
- unxt/_interop/unxt_interop_gala/unitsystems.py +108 -0
- unxt/_interop/unxt_interop_mpl/__init__.py +81 -0
- unxt/_src/__init__.py +6 -0
- unxt/_src/dimensions.py +400 -0
- unxt/_src/experimental.py +234 -0
- unxt/_src/quantity/__init__.py +24 -0
- unxt/_src/quantity/angle.py +58 -0
- unxt/_src/quantity/base.py +1160 -0
- unxt/_src/quantity/base_angle.py +89 -0
- unxt/_src/quantity/base_parametric.py +290 -0
- unxt/_src/quantity/flag.py +137 -0
- unxt/_src/quantity/mixins.py +238 -0
- unxt/_src/quantity/quantity.py +123 -0
- unxt/_src/quantity/register_api.py +383 -0
- unxt/_src/quantity/register_conversions.py +95 -0
- unxt/_src/quantity/register_dispatches.py +246 -0
- unxt/_src/quantity/register_primitives.py +5075 -0
- unxt/_src/quantity/static_quantity.py +90 -0
- unxt/_src/quantity/unchecked.py +45 -0
- unxt/_src/quantity/value.py +289 -0
- unxt/_src/units.py +103 -0
- unxt/_src/unitsystems/__init__.py +40 -0
- unxt/_src/unitsystems/base.py +258 -0
- unxt/_src/unitsystems/builtin.py +190 -0
- unxt/_src/unitsystems/builtin_dimensions.py +21 -0
- unxt/_src/unitsystems/compare.py +13 -0
- unxt/_src/unitsystems/core.py +307 -0
- unxt/_src/unitsystems/flags.py +80 -0
- unxt/_src/unitsystems/realizations.py +73 -0
- unxt/_src/unitsystems/utils.py +95 -0
- unxt/_src/utils.py +112 -0
- unxt/_version.py +34 -0
- unxt/_version.pyi +2 -0
- unxt/dims.py +19 -0
- unxt/py.typed +0 -0
- unxt/quantity.py +172 -0
- unxt/setup_package.py +60 -0
- unxt/units.py +19 -0
- unxt/unitsystems.py +67 -0
- unxt-0.1.dev463.dist-info/METADATA +533 -0
- unxt-0.1.dev463.dist-info/RECORD +52 -0
- unxt-0.1.dev463.dist-info/WHEEL +4 -0
- unxt-0.1.dev463.dist-info/licenses/LICENSE +29 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: unxt
|
|
3
|
+
Version: 0.1.dev463
|
|
4
|
+
Summary: Quantities in JAX
|
|
5
|
+
Project-URL: Bug Tracker, https://github.com/GalacticDynamics/unxt/issues
|
|
6
|
+
Project-URL: Changelog, https://github.com/GalacticDynamics/unxt/releases
|
|
7
|
+
Project-URL: Discussions, https://github.com/GalacticDynamics/unxt/discussions
|
|
8
|
+
Project-URL: Homepage, https://github.com/GalacticDynamics/unxt
|
|
9
|
+
Author-email: GalacticDynamics <nstarman@users.noreply.github.com>, Nathaniel Starkman <nstarman@users.noreply.github.com>, Adrian Price-Whelan <adrianmpw@gmail.com>
|
|
10
|
+
License: BSD 3-Clause License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2023, Nathaniel Starkman.
|
|
13
|
+
All rights reserved.
|
|
14
|
+
|
|
15
|
+
Redistribution and use in source and binary forms, with or without
|
|
16
|
+
modification, are permitted provided that the following conditions are met:
|
|
17
|
+
|
|
18
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
19
|
+
list of conditions and the following disclaimer.
|
|
20
|
+
|
|
21
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
22
|
+
this list of conditions and the following disclaimer in the documentation
|
|
23
|
+
and/or other materials provided with the distribution.
|
|
24
|
+
|
|
25
|
+
* Neither the name of the vector package developers nor the names of its
|
|
26
|
+
contributors may be used to endorse or promote products derived from
|
|
27
|
+
this software without specific prior written permission.
|
|
28
|
+
|
|
29
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
30
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
31
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
32
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
33
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
34
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
35
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
36
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
37
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
38
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
39
|
+
License-File: LICENSE
|
|
40
|
+
Classifier: Development Status :: 3 - Alpha
|
|
41
|
+
Classifier: Intended Audience :: Developers
|
|
42
|
+
Classifier: Intended Audience :: Science/Research
|
|
43
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
44
|
+
Classifier: Operating System :: OS Independent
|
|
45
|
+
Classifier: Programming Language :: Python
|
|
46
|
+
Classifier: Programming Language :: Python :: 3
|
|
47
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
48
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
49
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
50
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
51
|
+
Classifier: Topic :: Scientific/Engineering
|
|
52
|
+
Classifier: Typing :: Typed
|
|
53
|
+
Requires-Python: >=3.11
|
|
54
|
+
Requires-Dist: astropy>=7.0.0
|
|
55
|
+
Requires-Dist: dataclassish>=0.8.0
|
|
56
|
+
Requires-Dist: equinox>=0.13.2
|
|
57
|
+
Requires-Dist: is-annotated>=1.0
|
|
58
|
+
Requires-Dist: jax>=0.5.3
|
|
59
|
+
Requires-Dist: jaxlib>=0.5.3
|
|
60
|
+
Requires-Dist: jaxtyping>=0.3.3
|
|
61
|
+
Requires-Dist: optional-dependencies>=0.3.2
|
|
62
|
+
Requires-Dist: plum-dispatch>=2.7.0
|
|
63
|
+
Requires-Dist: quax-blocks>=0.4.0
|
|
64
|
+
Requires-Dist: quax>=0.2.1
|
|
65
|
+
Requires-Dist: quaxed>=0.10.2
|
|
66
|
+
Requires-Dist: unxt-api>=1.10.0
|
|
67
|
+
Requires-Dist: wadler-lindig>=0.1.5
|
|
68
|
+
Requires-Dist: xmmutablemap>=0.1
|
|
69
|
+
Requires-Dist: zeroth>=1.0.0
|
|
70
|
+
Provides-Extra: all
|
|
71
|
+
Requires-Dist: astropy>=6.0; extra == 'all'
|
|
72
|
+
Requires-Dist: gala>=1.8; extra == 'all'
|
|
73
|
+
Requires-Dist: matplotlib>=3.8; extra == 'all'
|
|
74
|
+
Requires-Dist: unxt-api; extra == 'all'
|
|
75
|
+
Requires-Dist: unxt-hypothesis; extra == 'all'
|
|
76
|
+
Provides-Extra: backend-astropy
|
|
77
|
+
Requires-Dist: astropy>=6.0; extra == 'backend-astropy'
|
|
78
|
+
Provides-Extra: cpu
|
|
79
|
+
Requires-Dist: jax[cpu]>=0.5.3; extra == 'cpu'
|
|
80
|
+
Provides-Extra: cuda
|
|
81
|
+
Requires-Dist: jax[cuda]>=0.5.3; extra == 'cuda'
|
|
82
|
+
Provides-Extra: cuda12
|
|
83
|
+
Requires-Dist: jax[cuda12]>=0.5.3; extra == 'cuda12'
|
|
84
|
+
Provides-Extra: cuda12-local
|
|
85
|
+
Requires-Dist: jax[cuda12-local]>=0.5.3; extra == 'cuda12-local'
|
|
86
|
+
Provides-Extra: interop-gala
|
|
87
|
+
Requires-Dist: gala>=1.8; extra == 'interop-gala'
|
|
88
|
+
Provides-Extra: interop-mpl
|
|
89
|
+
Requires-Dist: matplotlib>=3.8; extra == 'interop-mpl'
|
|
90
|
+
Provides-Extra: k8s
|
|
91
|
+
Requires-Dist: jax[k8s]>=0.5.3; extra == 'k8s'
|
|
92
|
+
Provides-Extra: workspace
|
|
93
|
+
Requires-Dist: unxt-api; extra == 'workspace'
|
|
94
|
+
Requires-Dist: unxt-hypothesis; extra == 'workspace'
|
|
95
|
+
Description-Content-Type: text/markdown
|
|
96
|
+
|
|
97
|
+
<h1 align='center'> unxt </h1>
|
|
98
|
+
<h3 align="center">Unitful Quantities in JAX</h3>
|
|
99
|
+
|
|
100
|
+
<p align="center">
|
|
101
|
+
<a href="https://pypi.org/project/unxt/"> <img alt="PyPI: unxt" src="https://img.shields.io/pypi/v/unxt?style=flat" /> </a>
|
|
102
|
+
<a href="https://pypi.org/project/unxt/"> <img alt="PyPI versions: unxt" src="https://img.shields.io/pypi/pyversions/unxt" /> </a>
|
|
103
|
+
<a href="https://unxt.readthedocs.io/en/"> <img alt="ReadTheDocs" src="https://img.shields.io/badge/read_docs-here-orange" /> </a>
|
|
104
|
+
<a href="https://pypi.org/project/unxt/"> <img alt="unxt license" src="https://img.shields.io/github/license/GalacticDynamics/unxt" /> </a>
|
|
105
|
+
</p>
|
|
106
|
+
<p align="center">
|
|
107
|
+
<a href="https://scientific-python.org/specs/spec-0000/"> <img alt="ruff" src="https://img.shields.io/badge/SPEC-0-green?labelColor=%23004811&color=%235CA038" /> </a>
|
|
108
|
+
<a href="https://docs.astral.sh/ruff/"> <img alt="ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json" /> </a>
|
|
109
|
+
<a href="https://pre-commit.com"> <img alt="pre-commit" src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit" /> </a>
|
|
110
|
+
<a href="https://codspeed.io/GalacticDynamics/unxt"><img src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" alt="CodSpeed Badge"/></a>
|
|
111
|
+
</p>
|
|
112
|
+
<p align="center">
|
|
113
|
+
<a href="https://github.com/GalacticDynamics/unxt/actions"> <img alt="CI status" src="https://github.com/GalacticDynamics/unxt/actions/workflows/ci.yml/badge.svg?branch=main" /> </a>
|
|
114
|
+
<a href="https://unxt.readthedocs.io/en/"> <img alt="ReadTheDocs" src="https://readthedocs.org/projects/unxt/badge/?version=latest" /> </a>
|
|
115
|
+
<a href="https://codecov.io/gh/GalacticDynamics/unxt"> <img alt="codecov" src="https://codecov.io/gh/GalacticDynamics/unxt/graph/badge.svg" /> </a>
|
|
116
|
+
</p>
|
|
117
|
+
<p align="center">
|
|
118
|
+
<a style="border-width:0" href="https://doi.org/10.21105/joss.07771"> <img src="https://joss.theoj.org/papers/10.21105/joss.07771/status.svg" alt="DOI badge" > </a>
|
|
119
|
+
</p>
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
Unxt is unitful quantities and calculations in [JAX][jax], built on [Equinox][equinox] and [Quax][quax].
|
|
124
|
+
|
|
125
|
+
Unxt supports JAX's compelling features:
|
|
126
|
+
|
|
127
|
+
- JIT compilation (`jit`)
|
|
128
|
+
- vectorization (`vmap`, etc.)
|
|
129
|
+
- auto-differentiation (`grad`, `jacobian`, `hessian`)
|
|
130
|
+
- GPU/TPU/multi-host acceleration
|
|
131
|
+
|
|
132
|
+
And best of all, `unxt` doesn't force you to use special unit-compatible re-exports of JAX libraries. You can use `unxt` with existing JAX code, and with [quax][quax]'s simple decorator, JAX will work with `unxt.Quantity`.
|
|
133
|
+
|
|
134
|
+
## Installation
|
|
135
|
+
|
|
136
|
+
[![PyPI version][pypi-version]][pypi-link] [![PyPI platforms][pypi-platforms]][pypi-link]
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pip install unxt
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
<details>
|
|
143
|
+
<summary>using <code>uv</code></summary>
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
uv add unxt
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
</details>
|
|
150
|
+
<details>
|
|
151
|
+
<summary>from source, using pip</summary>
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip install git+https://https://github.com/GalacticDynamics/unxt.git
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
</details>
|
|
158
|
+
<details>
|
|
159
|
+
<summary>building from source</summary>
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
cd /path/to/parent
|
|
163
|
+
git clone https://https://github.com/GalacticDynamics/unxt.git
|
|
164
|
+
cd unxt
|
|
165
|
+
pip install -e . # editable mode
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
</details>
|
|
169
|
+
|
|
170
|
+
## [Documentation][rtd-link]
|
|
171
|
+
|
|
172
|
+
[](https://unxt.readthedocs.io/en/)
|
|
173
|
+
|
|
174
|
+
For full documentation, including installation instructions, tutorials, and API reference, please see the [unxt docs][rtd-link]. This README provides a brief overview and some quick examples.
|
|
175
|
+
|
|
176
|
+
### Dimensions
|
|
177
|
+
|
|
178
|
+
Dimensions represent the physical type of a quantity, such as length, time, or mass.
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
import unxt as u
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Create dimensions from strings:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
length_dim = u.dimension("length")
|
|
188
|
+
print(length_dim)
|
|
189
|
+
# PhysicalType('length')
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Dimensions support mathematical expressions:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
speed_dim = u.dimension("length / time")
|
|
196
|
+
print(speed_dim)
|
|
197
|
+
# PhysicalType({'speed', 'velocity'})
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Multi-word dimension names require parentheses in expressions:
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
activity_dim = u.dimension("(amount of substance) / (time)")
|
|
204
|
+
print(activity_dim)
|
|
205
|
+
# PhysicalType('catalytic activity')
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Units
|
|
209
|
+
|
|
210
|
+
Units specify the scale and dimension of measurements.
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
meter = u.unit("m")
|
|
214
|
+
print(meter)
|
|
215
|
+
# Unit("m")
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Units can be combined:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
velocity_unit = u.unit("km/h") # in the expression
|
|
222
|
+
print(velocity_unit)
|
|
223
|
+
# Unit("km / h")
|
|
224
|
+
|
|
225
|
+
velocity_unit2 = u.unit("km") / u.unit("h") # via arithmetic
|
|
226
|
+
print(velocity_unit2)
|
|
227
|
+
# Unit("km / h")
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Get the dimension of a unit:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
print(u.dimension_of(meter))
|
|
234
|
+
# PhysicalType('length')
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Unit Systems
|
|
238
|
+
|
|
239
|
+
Unit systems define consistent sets of base units for specific domains. `unxt` provides built-in unit systems and tools for creating custom ones.
|
|
240
|
+
|
|
241
|
+
### Built-in Unit Systems
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# SI (International System of Units)
|
|
245
|
+
si = u.unitsystem("si")
|
|
246
|
+
print(si)
|
|
247
|
+
# unitsystem(m, kg, s, mol, A, K, cd, rad)
|
|
248
|
+
|
|
249
|
+
# CGS (centimeter-gram-second)
|
|
250
|
+
cgs = u.unitsystem("cgs")
|
|
251
|
+
print(cgs)
|
|
252
|
+
# unitsystem(cm, g, s, dyn, erg, Ba, P, St, rad)
|
|
253
|
+
|
|
254
|
+
# Galactic (astrophysics)
|
|
255
|
+
galactic = u.unitsystem("galactic")
|
|
256
|
+
print(galactic)
|
|
257
|
+
# unitsystem(kpc, Myr, solMass, rad)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Composing Units from a Unit System
|
|
261
|
+
|
|
262
|
+
Once you have a unit system, you can get units for any physical dimension by indexing the system:
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
usys = u.unitsystem("si")
|
|
266
|
+
|
|
267
|
+
# Get specific units
|
|
268
|
+
print(usys["length"])
|
|
269
|
+
# Unit("m")
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Custom Unit Systems
|
|
273
|
+
|
|
274
|
+
Create custom unit systems by specifying base units:
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
import unxt as u
|
|
278
|
+
|
|
279
|
+
# Define a custom unit system
|
|
280
|
+
custom_usys = u.unitsystem("km", "h", "tonne", "degree")
|
|
281
|
+
print(custom_usys)
|
|
282
|
+
# unitsystem(km, h, t, deg)
|
|
283
|
+
|
|
284
|
+
# Access derived units
|
|
285
|
+
print(custom_usys["velocity"])
|
|
286
|
+
# Unit("km / h")
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Dynamical Unit Systems
|
|
290
|
+
|
|
291
|
+
For domains like gravitational dynamics, use dynamical unit systems where $G = 1$:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
from unxt.unitsystems import DynamicalSimUSysFlag
|
|
295
|
+
|
|
296
|
+
# Create a dynamical system where G=1
|
|
297
|
+
# Only specify 2 of (length, time, mass)
|
|
298
|
+
usys = u.unitsystem(DynamicalSimUSysFlag, "kpc", "Myr")
|
|
299
|
+
print(usys)
|
|
300
|
+
# unitsystem(kpc, Myr, ...)
|
|
301
|
+
|
|
302
|
+
# The third dimension (mass) is computed to make G=1
|
|
303
|
+
print(usys["mass"])
|
|
304
|
+
# Unit("10^11 solMass") # computed value
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Quantities
|
|
308
|
+
|
|
309
|
+
Quantities combine values with units, providing type-safe unitful arithmetic.
|
|
310
|
+
|
|
311
|
+
#### Basic Quantities
|
|
312
|
+
|
|
313
|
+
```python
|
|
314
|
+
import jax.numpy as jnp
|
|
315
|
+
|
|
316
|
+
x = u.Quantity(jnp.arange(1, 5, dtype=float), "km")
|
|
317
|
+
print(x)
|
|
318
|
+
# Quantity['length']([1., 2., 3., 4.], unit='km')
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
The constituent value and unit are accessible as attributes:
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
repr(x.value)
|
|
325
|
+
# Array([1., 2., 3., 4.], dtype=float64)
|
|
326
|
+
|
|
327
|
+
repr(x.unit)
|
|
328
|
+
# Unit("km")
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`Quantity` objects obey the rules of unitful arithmetic.
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
# Addition / Subtraction
|
|
335
|
+
print(x + x)
|
|
336
|
+
# Quantity["length"]([2.0, 4.0, 6.0, 8.0], unit="km")
|
|
337
|
+
|
|
338
|
+
# Multiplication / Division
|
|
339
|
+
print(2 * x)
|
|
340
|
+
# Quantity["length"]([2.0, 4.0, 6.0, 8.0], unit="km")
|
|
341
|
+
|
|
342
|
+
y = u.Quantity(jnp.arange(4, 8, dtype=float), "yr")
|
|
343
|
+
|
|
344
|
+
print(x / y)
|
|
345
|
+
# Quantity['speed']([0.25, 0.4 , 0.5 , 0.57142857], unit='km / yr')
|
|
346
|
+
|
|
347
|
+
# Exponentiation
|
|
348
|
+
print(x**2)
|
|
349
|
+
# Quantity['area']([ 1., 4., 9., 16.], unit='km2')
|
|
350
|
+
|
|
351
|
+
# Unit checking on operations
|
|
352
|
+
try:
|
|
353
|
+
x + y
|
|
354
|
+
except Exception as e:
|
|
355
|
+
print(e)
|
|
356
|
+
# 'yr' (time) and 'km' (length) are not convertible
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Quantities can be converted to different units:
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
print(u.uconvert("m", x)) # via function
|
|
363
|
+
# Quantity['length']([1000., 2000., 3000., 4000.], unit='m')
|
|
364
|
+
|
|
365
|
+
print(x.uconvert("m")) # via method
|
|
366
|
+
# Quantity['length']([1000., 2000., 3000., 4000.], unit='m')
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Since `Quantity` is parametric, it can do runtime dimension checking!
|
|
370
|
+
|
|
371
|
+
```python
|
|
372
|
+
LengthQuantity = u.Quantity["length"]
|
|
373
|
+
print(LengthQuantity(2, "km"))
|
|
374
|
+
# Quantity['length'](2, unit='km')
|
|
375
|
+
|
|
376
|
+
try:
|
|
377
|
+
LengthQuantity(2, "s")
|
|
378
|
+
except ValueError as e:
|
|
379
|
+
print(e)
|
|
380
|
+
# Physical type mismatch.
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### BareQuantity
|
|
384
|
+
|
|
385
|
+
For performance-critical code where you don't need dimension checking, use `BareQuantity`:
|
|
386
|
+
|
|
387
|
+
```python
|
|
388
|
+
import unxt as u
|
|
389
|
+
import jax.numpy as jnp
|
|
390
|
+
|
|
391
|
+
# BareQuantity skips dimension checks for better performance
|
|
392
|
+
bq = u.quantity.BareQuantity(jnp.array([1.0, 2.0, 3.0]), "m")
|
|
393
|
+
print(bq)
|
|
394
|
+
# BareQuantity([1., 2., 3.], unit='m')
|
|
395
|
+
|
|
396
|
+
# Works just like Quantity but without dimension validation
|
|
397
|
+
print(bq * 2)
|
|
398
|
+
# BareQuantity([2., 4., 6.], unit='m')
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### Angle
|
|
402
|
+
|
|
403
|
+
`Angle` is a specialized quantity with wrapping support for angular values:
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
import unxt as u
|
|
407
|
+
import jax.numpy as jnp
|
|
408
|
+
|
|
409
|
+
# Angles can wrap to a specified range
|
|
410
|
+
theta = u.Angle(jnp.array([0, 90, 180, 270, 360]), "deg")
|
|
411
|
+
print(theta)
|
|
412
|
+
# Angle([0., 90., 180., 270., 360.], unit='deg')
|
|
413
|
+
|
|
414
|
+
# Optional wrapping to a specified range
|
|
415
|
+
angle = u.Angle(jnp.array([370, -10]), "deg")
|
|
416
|
+
wrapped = angle.wrap_to(u.Q(0, "deg"), u.Q(360, "deg"))
|
|
417
|
+
print(wrapped)
|
|
418
|
+
# Angle([10., 350.], unit='deg')
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### StaticQuantity
|
|
422
|
+
|
|
423
|
+
For static configuration values (e.g., JAX static arguments), use `StaticQuantity`, which stores NumPy values and rejects JAX arrays:
|
|
424
|
+
|
|
425
|
+
```python
|
|
426
|
+
import numpy as np
|
|
427
|
+
from functools import partial
|
|
428
|
+
import jax
|
|
429
|
+
import jax.numpy as jnp
|
|
430
|
+
import unxt as u
|
|
431
|
+
|
|
432
|
+
cfg = u.StaticQuantity(np.array([1.0, 2.0]), "m")
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
@partial(jax.jit, static_argnames=("q",))
|
|
436
|
+
def add(x, q):
|
|
437
|
+
return x + jnp.asarray(q.value)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
print(add(1.0, cfg))
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
#### StaticValue
|
|
444
|
+
|
|
445
|
+
If you want a `Quantity` that keeps a static value but still participates in regular arithmetic, wrap the value with `StaticValue`. Arithmetic behaves like the wrapped array, and `StaticValue + StaticValue` returns a `StaticValue`. Comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`) return NumPy boolean arrays for element-wise comparison:
|
|
446
|
+
|
|
447
|
+
```python
|
|
448
|
+
import numpy as np
|
|
449
|
+
import jax.numpy as jnp
|
|
450
|
+
import unxt as u
|
|
451
|
+
|
|
452
|
+
sv = u.quantity.StaticValue(np.array([1.0, 2.0]))
|
|
453
|
+
q_static = u.Q(sv, "m")
|
|
454
|
+
q = u.Q(jnp.array([3.0, 4.0]), "m")
|
|
455
|
+
|
|
456
|
+
print(q_static + q)
|
|
457
|
+
|
|
458
|
+
# Comparisons return NumPy boolean arrays (element-wise)
|
|
459
|
+
sv2 = u.quantity.StaticValue(np.array([2.0, 1.0]))
|
|
460
|
+
print(sv < sv2) # array([ True, False])
|
|
461
|
+
print(sv == np.array([1.0, 2.0])) # array([ True, True])
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### JAX Integration
|
|
465
|
+
|
|
466
|
+
`unxt` is built on [`quax`][quax], which enables custom array-ish objects in JAX. For convenience we use the [`quaxed`][quaxed] library, which is just a `quax.quaxify` wrapper around `jax` to avoid boilerplate code.
|
|
467
|
+
|
|
468
|
+
> [!NOTE]
|
|
469
|
+
>
|
|
470
|
+
> Using [`quaxed`][quaxed] is optional. You can directly use `quaxify`, and even apply it to the top-level function instead of individual functions.
|
|
471
|
+
|
|
472
|
+
```python
|
|
473
|
+
from quaxed import grad, vmap
|
|
474
|
+
import quaxed.numpy as jnp
|
|
475
|
+
|
|
476
|
+
# Using the x quantity from earlier examples
|
|
477
|
+
print(jnp.square(x))
|
|
478
|
+
# Quantity['area']([ 1., 4., 9., 16.], unit='km2')
|
|
479
|
+
|
|
480
|
+
print(jnp.power(x, 3))
|
|
481
|
+
# Quantity['volume']([ 1., 8., 27., 64.], unit='km3')
|
|
482
|
+
|
|
483
|
+
print(vmap(grad(lambda x: x**3))(x))
|
|
484
|
+
# Quantity['area']([ 3., 12., 27., 48.], unit='km2')
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
See the [documentation][rtd-link] for more examples and details of JIT and AD
|
|
488
|
+
|
|
489
|
+
## Citation
|
|
490
|
+
|
|
491
|
+
[![JOSS][joss-badge]][joss-link]
|
|
492
|
+
|
|
493
|
+
If you found this library to be useful and want to support the development and maintenance of lower-level code libraries for the scientific community, please consider citing this work.
|
|
494
|
+
|
|
495
|
+
## Contributing and Development
|
|
496
|
+
|
|
497
|
+
[![Actions Status][actions-badge]][actions-link] [![Documentation Status][rtd-badge]][rtd-link] [![codecov][codecov-badge]][codecov-link] [![SPEC 0 — Minimum Supported Dependencies][spec0-badge]][spec0-link] [![pre-commit][pre-commit-badge]][pre-commit-link] [![ruff][ruff-badge]][ruff-link] [](https://codspeed.io/GalacticDynamics/unxt)
|
|
498
|
+
|
|
499
|
+
We welcome contributions! Contributions are how open source projects improve and grow.
|
|
500
|
+
|
|
501
|
+
To contribute to `unxt`, please [fork](https://github.com/GalacticDynamics/unxt/fork) the repository, make a development branch, develop on that branch, then [open a pull request](https://github.com/GalacticDynamics/unxt/compare) from the branch in your fork to main.
|
|
502
|
+
|
|
503
|
+
To report bugs, request features, or suggest other ideas, please [open an issue](https://github.com/GalacticDynamics/unxt/issues/new/choose).
|
|
504
|
+
|
|
505
|
+
For more information, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
506
|
+
|
|
507
|
+
<!-- prettier-ignore-start -->
|
|
508
|
+
[equinox]: https://docs.kidger.site/equinox/
|
|
509
|
+
[jax]: https://jax.readthedocs.io/en/latest/
|
|
510
|
+
[quax]: https://github.com/patrick-kidger/quax
|
|
511
|
+
[quaxed]: https://github.com/GalacticDynamics/quaxed
|
|
512
|
+
|
|
513
|
+
[actions-badge]: https://github.com/GalacticDynamics/unxt/actions/workflows/ci.yml/badge.svg?branch=main
|
|
514
|
+
[actions-link]: https://github.com/GalacticDynamics/unxt/actions
|
|
515
|
+
[codecov-badge]: https://codecov.io/gh/GalacticDynamics/unxt/graph/badge.svg
|
|
516
|
+
[codecov-link]: https://codecov.io/gh/GalacticDynamics/unxt
|
|
517
|
+
[joss-badge]: https://joss.theoj.org/papers/10.21105/joss.07771/status.svg
|
|
518
|
+
[joss-link]: https://doi.org/10.21105/joss.07771
|
|
519
|
+
[pre-commit-badge]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
|
|
520
|
+
[pre-commit-link]: https://pre-commit.com
|
|
521
|
+
[pypi-link]: https://pypi.org/project/unxt/
|
|
522
|
+
[pypi-platforms]: https://img.shields.io/pypi/pyversions/unxt
|
|
523
|
+
[pypi-version]: https://img.shields.io/pypi/v/unxt
|
|
524
|
+
[rtd-badge]: https://readthedocs.org/projects/unxt/badge/?version=latest
|
|
525
|
+
[rtd-link]: https://unxt.readthedocs.io/en/
|
|
526
|
+
[ruff-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json
|
|
527
|
+
[ruff-link]: https://docs.astral.sh/ruff/
|
|
528
|
+
[spec0-badge]: https://img.shields.io/badge/SPEC-0-green?labelColor=%23004811&color=%235CA038
|
|
529
|
+
[spec0-link]: https://scientific-python.org/specs/spec-0000/
|
|
530
|
+
[zenodo-badge]: https://zenodo.org/badge/734877295.svg
|
|
531
|
+
[zenodo-link]: https://zenodo.org/doi/10.5281/zenodo.10850455
|
|
532
|
+
|
|
533
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
unxt/__init__.py,sha256=Hgj3FLMZGW4uU6nS1CInQhK2M4zTlUmr_nxyeST0vto,2627
|
|
2
|
+
unxt/_version.py,sha256=GU7RmiIckoK0US2bC9yOr9Xa2OIe1CAw8sw6nRM_0bc,716
|
|
3
|
+
unxt/_version.pyi,sha256=o7uNL6MhuJoiqpEnriU7rBT6TmkJZA-i2qMoNz9YcgQ,82
|
|
4
|
+
unxt/dims.py,sha256=DY1lEoFLMUTldyaeUd2g08uCSmeQCcMBtC8vGl4IItk,506
|
|
5
|
+
unxt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
unxt/quantity.py,sha256=POK2jO41-MyLoDaYCR_s5vhmU-LClmvJb5i7gfsSG_c,4433
|
|
7
|
+
unxt/setup_package.py,sha256=7YasA3u7tWQloEg7N_QsyxOt7F9AN4ZKdQTaf5MHv68,1761
|
|
8
|
+
unxt/units.py,sha256=mUaBg4sqyVUkkr2bs9L6OkOnup9ey9dbKvaMxeKw1LA,441
|
|
9
|
+
unxt/unitsystems.py,sha256=nNHefaNroIE6-0qEyU3Do3FeOT9URpT_Vo8o1fjvuTg,2009
|
|
10
|
+
unxt/_interop/__init__.py,sha256=1dMLLjywMp52MgJ4BBEVkuqksyq40J1NwlZmKhRevr0,447
|
|
11
|
+
unxt/_interop/optional_deps.py,sha256=W2yM761N2fUQz6Fxqr6whJu7Lfhzn35u01B17aGfHvc,351
|
|
12
|
+
unxt/_interop/unxt_interop_astropy/__init__.py,sha256=jy3bEmce2h72ZbJ2LbYF-zwQ1EHhI_icc0fVfwDcEGk,159
|
|
13
|
+
unxt/_interop/unxt_interop_astropy/custom_types.py,sha256=cuYW3JbBWgMSEQbH94dF4T0juOIw5xGAhReoqVOVnY0,232
|
|
14
|
+
unxt/_interop/unxt_interop_astropy/dimensions.py,sha256=39nUdTw1ABgv9GapaUjclyasTDSQlV3m1zZijKqLVCQ,1292
|
|
15
|
+
unxt/_interop/unxt_interop_astropy/quantity.py,sha256=HK_hbxZxgRru1dsYnFt1uffoqJbtJJGd6LLru7wQSvs,8504
|
|
16
|
+
unxt/_interop/unxt_interop_astropy/units.py,sha256=GnHFU5JvrTc3JLalMRf0zhZiR62yllYGoqCsWsRRjzs,2185
|
|
17
|
+
unxt/_interop/unxt_interop_gala/__init__.py,sha256=wAmfWhgAk7UHZhFG8jWtOaS-2ahNnZtw6zFufW4OJpk,143
|
|
18
|
+
unxt/_interop/unxt_interop_gala/unitsystems.py,sha256=BZAKzF0ZOTbbOX6UsBQWgP-7dwE3aklpfmYHKJlHWCg,2968
|
|
19
|
+
unxt/_interop/unxt_interop_mpl/__init__.py,sha256=rRaqzyTWscvX_Pkm-CEeMkJi5weGcS_WlLh2ZlV2PE8,2790
|
|
20
|
+
unxt/_src/__init__.py,sha256=yOXGA2VbIEJPGbWqVs2mN-zveDWdpVIAoB5-U0gutNM,123
|
|
21
|
+
unxt/_src/dimensions.py,sha256=jCO37m8JOhLjS_zzfuWfwP-gcnQgmXTRTTvezNn5RIE,11307
|
|
22
|
+
unxt/_src/experimental.py,sha256=PxE7CCQSqyFv7AtR7cM60q5JQoXmFXYo_2A1drgaNtc,8330
|
|
23
|
+
unxt/_src/units.py,sha256=-dJIds2B2vk0w76XAWeie29VVdro8uhEcUPNKsYTH84,1835
|
|
24
|
+
unxt/_src/utils.py,sha256=EX_JIcB6XTFMTAsm2U4Tbb0XxN0bUsxAybyySIZDAZo,3067
|
|
25
|
+
unxt/_src/quantity/__init__.py,sha256=m0_ODTH_iJsDq3PAt5hjNe079HPgc6igqO7yazwC62c,607
|
|
26
|
+
unxt/_src/quantity/angle.py,sha256=0ORDDn1rQ2lOHtrco382KxMCTnzJ2oUgn4wGay_-8i4,1273
|
|
27
|
+
unxt/_src/quantity/base.py,sha256=n6_4C-uC4azBxosq-7ht6hx46aRd7_7AbHb0bZorMxQ,33778
|
|
28
|
+
unxt/_src/quantity/base_angle.py,sha256=aGROtlaOG0MZ_7gEkG62dqISxEMC4gfs0_N2JYw25_8,2547
|
|
29
|
+
unxt/_src/quantity/base_parametric.py,sha256=-dxLoCi3C4I5nZ8PBgcScloxC6IFQBNY_geKsGg07aQ,9901
|
|
30
|
+
unxt/_src/quantity/flag.py,sha256=S3VeroIKwOs_sPio7UDepmItdamEEWTtb0brSE-M4SM,2777
|
|
31
|
+
unxt/_src/quantity/mixins.py,sha256=WoZRVprLpOm9HDmmh7L1lU69aYhzK1vQhZ4kzTNy_Zo,7152
|
|
32
|
+
unxt/_src/quantity/quantity.py,sha256=4vWGExHUiKhXETMxkJ_DWRvbiwAPbhgH6IP7btZeH7A,3195
|
|
33
|
+
unxt/_src/quantity/register_api.py,sha256=nrdAgrG1ci14St8P4Lkx8m1uBTEsSM5xwh3lLKP6OxI,9109
|
|
34
|
+
unxt/_src/quantity/register_conversions.py,sha256=KCDnNBUBp0SzQHlbd2fllcqR335c5cagn9hSbdJ3Fg8,2447
|
|
35
|
+
unxt/_src/quantity/register_dispatches.py,sha256=TdU2jRL853IQko8KIAc6_HJ1lylk-UFo3RDFjUB8pqQ,6418
|
|
36
|
+
unxt/_src/quantity/register_primitives.py,sha256=s2i3hqQBytcJClywaUgJ0cImIzard3yopHkHATh8cDk,133409
|
|
37
|
+
unxt/_src/quantity/static_quantity.py,sha256=5NxOky0uOmP2rkMy2NQeGqgDL-yOHCgP7btZVQ-Qnw4,2854
|
|
38
|
+
unxt/_src/quantity/unchecked.py,sha256=Cf08wNpQL8iwfhezDCVuS7SdSPZhWevFXbvJM59NuNI,1318
|
|
39
|
+
unxt/_src/quantity/value.py,sha256=7F5fw-Q2ukg4IAzxNG6WCOn1XToeWRp4IgZ04Dt32xw,9141
|
|
40
|
+
unxt/_src/unitsystems/__init__.py,sha256=fx2PD6Huf_Ibi6ss_h8nAxuDGb_wnKiXaY2uIA87uV8,961
|
|
41
|
+
unxt/_src/unitsystems/base.py,sha256=afpsm_6QJhMwj2rjodClo6t-awzENRQk4ZKYO1U0GJw,8169
|
|
42
|
+
unxt/_src/unitsystems/builtin.py,sha256=XRnJEETERzxDzZRd5xjOx8a_5xZSgp5Jtl7zcnV4qgI,5208
|
|
43
|
+
unxt/_src/unitsystems/builtin_dimensions.py,sha256=28e0rabtn5cHbVoA4tdxeRyOnYkMtIttkNIaEUv4zuU,650
|
|
44
|
+
unxt/_src/unitsystems/compare.py,sha256=GyfrmWcXJQyzer2ipG2diYlALRzy72foUjsmlcxYu1A,317
|
|
45
|
+
unxt/_src/unitsystems/core.py,sha256=op0D-QaCV9AtzMbWgrABup5YYAL0M39Y9y0YUgnVh7o,8842
|
|
46
|
+
unxt/_src/unitsystems/flags.py,sha256=9A7pLc6Cdc9SS3AAlXd-wRkLusbmEnrges9d5NIdp8E,2599
|
|
47
|
+
unxt/_src/unitsystems/realizations.py,sha256=-REtFXemLlf-d7WoO_1HKNJvDmUkJ3r2EXc8lLW3Vj0,1592
|
|
48
|
+
unxt/_src/unitsystems/utils.py,sha256=32gmnnIjWi-6-yZcHAsl-Lcze_cEYPjPHwarS9v_M6o,2242
|
|
49
|
+
unxt-0.1.dev463.dist-info/METADATA,sha256=0fZCNXsURlpYaRry2UkDEFAePUbH0nTTqmVLqSFQtiE,18262
|
|
50
|
+
unxt-0.1.dev463.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
51
|
+
unxt-0.1.dev463.dist-info/licenses/LICENSE,sha256=P6foBl0H2WeXsCnK2m4-YzKz5yA2R3i78w4p7GcF5dQ,1528
|
|
52
|
+
unxt-0.1.dev463.dist-info/RECORD,,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023, Nathaniel Starkman.
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the vector package developers nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|