Avatar for the GalacticDynamics user
GalacticDynamics
unxt
BlogDocsChangelog

Performance History

Latest Results

Add unxts.api, unxts.hypothesis, unxts.xarray namespace packages (#681) * feat: add unxts.api namespace package (canonical unxts.api) * feat: add unxts.hypothesis namespace package * feat: add unxts.xarray namespace package; deprecate unxt-xarray * โ™ป๏ธ refactor(unxt-api): convert to backward-compat shim for unxts.api * โ™ป๏ธ refactor(unxt-hypothesis): convert to backward-compat shim for unxts.hypothesis * ๐Ÿงน chore: add unxts.* packages to workspace; update coordinator tags and tools * ๐Ÿ’š ci: add two-stage CD workflows for unxts.api, unxts.hypothesis, unxts.xarray * ๐Ÿ’š ci: add test jobs and labels for unxts.api, unxts.hypothesis, unxts.xarray * ๐Ÿ“ docs: add stub docs for unxts.api, unxts.hypothesis, unxts.xarray * ๐Ÿงน chore: set v2.0.0 as first coordinated release; update shim version floors * ๐Ÿ“ docs: update unxt-api and unxt-hypothesis READMEs with shim notice and migration guide * ๐Ÿ“ docs: replace deprecated package docs with minimal redirect pages * ๐Ÿ“ docs: strip deprecated package docs to minimal redirect pages * ๐Ÿงน chore: remove unxt-xarray (never released; superseded by unxts.xarray) * โœ… test: replace shim test suites with re-export identity checks * ๐ŸŽจ style: fix import ordering flagged by pre-push lint hook * โ™ป๏ธ refactor: rename unxts.xarray to unxts.interop.xarray Nests xarray integration under the unxts.interop namespace, another open namespace for unxt integrations. Renames the package directory, Python module path (unxts.interop.xarray, two levels of implicit PEP 420 namespace packages), git tag pattern (unxts-interop-xarray-v*), CD/CD-publish/CD-PR workflows, coordinator tag wiring, CI test job, labeler/labels entries, and docs. Also fixes a missed __version__ re-export in the unxt-hypothesis shim found while testing this change. * ๐Ÿ“ docs: retarget deprecated-package doc symlinks to canonical unxts.* docs docs/packages/{unxt-api,unxt-hypothesis} now symlink directly to the canonical unxts.api/unxts.hypothesis docs (the packages that replaced them) instead of to their own minimal redirect pages, which are now removed as unreachable. Per-package docs for unxts.api, unxts.hypothesis, and unxts.interop.xarray move into packages/<name>/docs/, matching the existing pattern, with docs/packages/<name> as a symlink to it. Also: drop unxt-api and unxt-hypothesis from the "workspace" optional dependency (unxt-api remains a core runtime dependency of unxt regardless); add a new "interop-xarray" optional dependency for unxts.interop.xarray and reference it from "workspace" via unxt[interop-xarray] instead of repeating the package name. * โœจ feat: auto-import unxts.interop.xarray if installed Registers the .unxt xarray accessor as a side effect of importing unxt, mirroring the existing optional astropy/gala/matplotlib interop hooks. No-op (and no hard dependency) if the optional unxts.interop.xarray package isn't installed. * โ™ป๏ธ refactor: extract gala interop into unxts.interop.gala package Moves the gala <-> unxt unitsystem conversion code from src/unxt/_interop/unxt_interop_gala/ into a new canonical namespace package, packages/unxts.interop.gala/ (src/unxts/interop/gala/, mirroring the unxts.interop.xarray layout: implicit PEP 420 namespace packages at both unxts and unxts.interop, git tag pattern unxts-interop-gala-v*, two-stage CD/CD-publish/CD-PR workflows, coordinator tag wiring, CI test job, labeler/labels entries, and docs (packages/unxts.interop.gala/docs/ with a docs/packages/unxts.interop.gala symlink). unxt itself now imports unxts.interop.gala if installed (mirroring the existing unxts.interop.xarray hook), registering the gala unitsystem dispatches as a side effect -- no hard dependency on gala from unxt. The "interop-gala" optional dependency now installs unxts.interop.gala instead of gala directly; "workspace" references it via unxt[interop-gala,interop-xarray] instead of spelling out the package names. * ๐Ÿ“ docs: move gala/matplotlib interop docs into their unxts.interop.* packages docs/interop/gala.md and docs/interop/matplotlib.md move into packages/unxts.interop.{gala,matplotlib}/docs/index.md respectively, hooked into the main unxt docs the same way as unxts.interop.xarray -- via a docs/packages/<name> symlink and a "๐Ÿ“ฆ Packages" toctree entry -- instead of the generic "๐Ÿค Interoperability" glob section. โ™ป๏ธ refactor: extract matplotlib interop into unxts.interop.matplotlib Moves the matplotlib unit-converter registration out of src/unxt/_interop/unxt_interop_mpl/ into a new canonical namespace package, packages/unxts.interop.matplotlib/ (src/unxts/interop/matplotlib/), mirroring the unxts.interop.{gala,xarray} layout: implicit PEP 420 namespace packages, git tag pattern unxts-interop-matplotlib-v*, two-stage CD/CD-publish/CD-PR workflows, coordinator tag wiring, CI test job, labeler/labels entries, and docs. unxt now imports unxts.interop.matplotlib if installed (new OptDeps.UNXTS_INTEROP_MATPLOTLIB), registering the matplotlib converter as a side effect -- no hard dependency on matplotlib from unxt. The "interop-mpl" optional dependency now installs unxts.interop.matplotlib instead of matplotlib directly; "workspace" references all three interop extras via unxt[interop-gala,interop-mpl,interop-xarray]. * ๐Ÿ“ docs: document unxts.interop.gala's public convert_* functions Documents that unxts.interop.gala exposes convert_gala_unitsystem_to_unxt_unitsystem and convert_unxt_unitsystem_to_gala_unitsystem as public API, while recommending plum.convert(usys, ...) as the idiomatic way to invoke them -- they're plum.conversion_methods registered as a side effect of importing the package. Notes added to the package docstring, both function docstrings, docs/index.md, and README.md. * ๐Ÿ› fix(cd): correct package_tag validation regex in unxts.* publish workflows All five unxts.* stage-B publish workflows validated the release tag against /^unxt-api-v.../ (a leftover from the cd-publish-unxt-api.yml template) instead of their own tag pattern, so a valid unxts-<pkg>-vX.Y.Z tag would be rejected and publishing would fail. Each now matches its own pattern (unxts-api, unxts-hypothesis, unxts-interop-gala, unxts-interop-matplotlib, unxts-interop-xarray). * โœ… test: add smoke-test suites for the unxts.* packages The tests-unxts-* CI jobs run `pytest packages/unxts.<pkg>/tests`, but those directories did not exist, so each job would exit with "file or directory not found" when triggered. Add a minimal but functional suite per package: - unxts.api / unxts.hypothesis: public-API presence + a strategy check - unxts.interop.gala: gala <-> unxt unitsystem conversion round-trip - unxts.interop.matplotlib: converter registration + unit stripping - unxts.interop.xarray: accessor registration + attach/strip round-trip Also fix stale `unxt_xarray` references in the unxts.interop.xarray docstrings (leftovers from the rename; the unxt-xarray package no longer exists) to point at unxts.interop.xarray. * ๐Ÿ’š ci: fix nox lint session for the unxts.* package layout The `Format โ†’ Lint` CI job (`nox -s lint`) failed for two reasons: - `pylint(package='unxt')` could not resolve the `unxts.interop.*` imports in `src/unxt/_interop/__init__.py`, because the pylint nox session did not install those packages. The session now installs the `workspace` extra so every namespace package is importable. - `pylint(package='xarray')` (and the pytest xarray group) still referenced `packages/unxt-xarray`, which was removed. The PackageEnum is reworked to the current layout and each package is linted in its own pylint process (so the duplicate-code checker does not flag the intentional shim/canonical similarity), and pytest points the namespace packages at their `tests/` dirs. Also remove the dead `_src/` implementation trees left in the unxt-api and unxt-hypothesis shims: the shims re-export from unxts.api / unxts.hypothesis and never import `_src`, so those files were unused duplicates (and the source of the pylint duplicate-code findings). * ๐Ÿ’š ci: align unxts.* workflow action pins with main (post-rebase) The unxts.* CD/CD-publish/CD-PR workflows were copied from the unxt/unxt-api templates before the dependabot action bump (#680) that now sits on main. After rebasing, bring every pinned action in the new workflows (and the unxts.* test jobs in ci.yml) up to the same versions main uses: actions/checkout v7.0.0, setup-uv v8.2.0, codecov-action v7.0.0, build-and-inspect-python-package v2.18.0, gh-action-pypi-publish v1.14.0, attest-build-provenance v4.1.1. * โœ… test: update validate_tag tests for the v2.0.0 threshold scripts/validate_tag.py now grandfathers the whole 1.x series (`major < 2`; v2.0.0 is the first coordinated release), but these tests still used v1.11.x as their "new, strict-rules" version, so six of them asserted rejection/coordinator-checks against tags that are now legacy-valid. Bump the strict-path examples to the 2.x series and add an explicit 1.11.0 legacy case documenting the new boundary. * ๐Ÿ’š ci: fix full-suite jobs after unxt-hypothesis left the workspace extra Removing unxt-hypothesis from the `workspace` optional dependency broke the push/deps CI jobs (tests-unxt, test-oldest, test-newest, test-interoperability): tests/unit/test_dims.py and test_quantity.py imported `unxt_hypothesis`, which those jobs no longer install. Point them at the canonical `unxts.hypothesis` (which the workspace extra does install). Also, the `workspace` extra now pulls matplotlib via `unxt[interop-mpl]`, so the matplotlib integration tests are collected in the nox `pytest(package='unxt')` session; switch that session to the `test-all` group so `pytest-mpl` registers the `mpl_image_compare` marker. * ๐Ÿ’š ci: use importlib pytest import-mode to fix cross-package test collisions The deps CI jobs (test-oldest, test-newest, test-interoperability) run a bare pytest over the root testpaths, which collect both packages/unxt-api/tests/test_public_api.py and packages/unxt-hypothesis/tests/test_public_api.py. Under the default prepend import-mode these same-named, __init__-less modules collide ("import file mismatch"). importlib mode imports each by its full path, which also stops a namespace-package leaf dir (e.g. unxts/interop/xarray) from shadowing the real library during src-doctest collection. * ๐Ÿ› fix: make gala interop inert where gala cannot build (Windows) Putting interop-gala in the workspace extra meant the cross-platform nox test env tried to install gala, which has no Windows wheels and fails to build there (GSL / C++ compile errors), breaking the Windows unxt CI jobs. Mark gala as an off-Windows dependency of unxts.interop.gala (`gala>=1.8; sys_platform != 'win32'`) so the package installs everywhere but pulls gala only where it can build. unxt's interop hook and the docs collection now gate on gala itself being importable (new OptDeps.GALA), not just on the unxts.interop.gala distribution being present, so `import unxt` stays safe and the gala docs are skipped on Windows. * ๐Ÿ’š ci: skip the deprecated unxt-hypothesis sweep and ignore gala docs on Windows Two follow-ups so the push/deps CI jobs go green: - Drop packages/unxt-hypothesis/ from the shared `testpaths`. It is a deprecated shim that is no longer installed by default (removed from the workspace extra), so the bare-pytest deps jobs (test-oldest, test-newest, test-interoperability) hit ModuleNotFoundError importing `unxt_hypothesis`. The shim keeps its own per-package CI job. - Fix the gala/matplotlib docs collect-ignore to use the docs/packages/<name> symlink path that pytest actually walks (the previous packages/<name>/docs path never matched), so the gala doctest page is correctly skipped on Windows where gala isn't installed. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
main
5 hours ago
build(deps): bump the actions group with 10 updates (#680) Bumps the actions group with 10 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `5.0.0` | `7.0.0` | | [hynek/build-and-inspect-python-package](https://github.com/hynek/build-and-inspect-python-package) | `2.14.0` | `2.18.0` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `6.0.0` | `8.0.1` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` | | [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `4.1.0` | `4.1.1` | | [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `8.0.0` | `8.2.0` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `7.0.0` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `4.13.0` | `4.18.1` | | [actions/labeler](https://github.com/actions/labeler) | `6.0.1` | `6.1.0` | | [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) | `7.0.8` | `8.1.1` | Updates `actions/checkout` from 5.0.0 to 7.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) Updates `hynek/build-and-inspect-python-package` from 2.14.0 to 2.18.0 - [Release notes](https://github.com/hynek/build-and-inspect-python-package/releases) - [Changelog](https://github.com/hynek/build-and-inspect-python-package/blob/main/CHANGELOG.md) - [Commits](https://github.com/hynek/build-and-inspect-python-package/compare/v2.14...d44ca7d91762de7a7d5436ddae667c6da6d1c3df) Updates `actions/download-artifact` from 6.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v6...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e...cef221092ed1bacb1cc03d23a2d87d1d172e277b) Updates `actions/attest-build-provenance` from 4.1.0 to 4.1.1 - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32...0f67c3f4856b2e3261c31976d6725780e5e4c373) Updates `astral-sh/setup-uv` from 8.0.0 to 8.2.0 - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/cec208311dfd045dd5311c1add060b2062131d57...fac544c07dec837d0ccb6301d7b5580bf5edae39) Updates `codecov/codecov-action` from 6.0.0 to 7.0.0 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/57e3a136b779b570ffcdbf80b3bdc90e7fab3de2...fb8b3582c8e4def4969c97caa2f19720cb33a72f) Updates `CodSpeedHQ/action` from 4.13.0 to 4.18.1 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/d872884a306dd4853acf0f584f4b706cf0cc72a2...a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f) Updates `actions/labeler` from 6.0.1 to 6.1.0 - [Release notes](https://github.com/actions/labeler/releases) - [Commits](https://github.com/actions/labeler/compare/634933edcd8ababfe52f92936142cc22ac488b1b...f27b608878404679385c85cfa523b85ccb86e213) Updates `peter-evans/create-pull-request` from 7.0.8 to 8.1.1 - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/271a8d0340265f705b14b6d32b9829c1cb33d45e...5f6978faf089d4d20b00c7766989d076bb2fc7f1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: hynek/build-and-inspect-python-package dependency-version: 2.18.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/attest-build-provenance dependency-version: 4.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: astral-sh/setup-uv dependency-version: 8.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: codecov/codecov-action dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: CodSpeedHQ/action dependency-version: 4.18.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/labeler dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: peter-evans/create-pull-request dependency-version: 8.1.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
main
9 hours ago
๐ŸŽ‰ init: unxt-xarray (#498) * ๐ŸŽ‰ init: unxt-xarray * โœจ feat(unxt-xarray): export functions as public API * โœจ feat(unxt-xarray): units attribute * fix: accept dimensionless-Quantity integer indices in dynamic_slice/gather JAX's nan-aware quantile (`nanquantile`/`nanmedian`) internally builds a boolean nan-mask, performs integer arithmetic on it to obtain indices, then calls `lax.dynamic_slice` and `lax.gather` with those indices. After #679 made comparisons return dimensionless `Quantity` objects, these index values became dimensionless-Quantity integersโ€”but the two dispatch rules only accepted `ArrayLike`, triggering a materialise error. Broaden both rules to `ArrayLike | ABCQ` and strip the index with `ustrip(AllowValue, โ€ฆ)` before binding the primitive. The operand still requires a typed `ABCQ` position, so no type piracy is introduced. * feat(unxt-xarray): document and test unit propagation through xarray ops Add an integration test suite (`test_operations.py`) covering reductions (sum, prod, median, quantile), masking (where, fillna), and products (dot), plus a test asserting that `unxt_xarray` leaves xarray's namespace resolver untouched. Expand the xarray-guide with an "Operations Preserve Units" section showing which operations work natively and an honest Limitations section (dimension coordinates, rolling, interp). Wire `packages/unxt-xarray/` into the root `testpaths` so CI picks up the package's tests. * fix(unxt-xarray): address PR review comments - conversion.py: copy attrs dicts defensively (dict(obj.attrs), dict(coord.attrs)) to prevent mutations from propagating back to the caller's objects - conversion.py: use _array_attach_units() for coordinate data in attach_units() to centralise unit-parsing logic - docs/index.md: fix malformed nested code fence in uv tab-item - .github/copilot-instructions.md: fix malformed tab-set example * fix(ci): add unxt-xarray to the workspace optional-dependency The "Newest supported deps" job and the nox pytest session with `uv_extras=["workspace"]` install `--extra workspace` (via `--extra all`). Since `unxt-xarray` was absent from that list, pytest collected its tests but could not import the package, causing a collection error. * fix(docs): remove stray fenced-code remnant in copilot-instructions tab-set example * docs: flesh out the Documentation section in copilot-instructions Replace the single tab-set bullet with real guidance: NumPy docstring format, Sybil-as-doctest implications, example quality bar, and MyST/Sphinx workflow. * fix(unxt-xarray): address second round of PR review comments strip_units: copy attrs dicts defensively (dict(coord.attrs), dict(var.attrs), dict(obj.attrs)) to match the pattern already applied to attach_units and prevent cross-object mutation. docs: fix three examples that used dimension coordinates and claimed the coordinate data would survive as a Quantity โ€” xarray coerces dimension coords to plain arrays. Switch Coordinates-with-Units guide example to a non-dimension coord; simplify the Quick Start examples in docs/index.md and README.md to not show coordinate quantification. Add missing `import unxt_xarray` and `import jax.numpy as jnp` to xarray-guide.md code blocks so Sybil can execute them. pyproject.toml: expand inline raw-options table into the structured [tool.hatch.version.raw-options] / [tool.hatch.version.raw-options.scm.git] form used by all other workspace packages. * fix(unxt-xarray): address third round of PR review comments - conversion.py attach_units(Dataset): copy var.attrs to dict for consistency with coords and strip_units - accessors.py: correct final_units annotation to include str since callers may pass unit strings, not just AbstractUnit objects - cd-unxt-xarray.yml: add paths: filter to pull_request trigger so the workflow only runs on PRs that touch xarray package files * docs(unxt-xarray): add lower-level API section, unit-conversion example, and dimension-coord warning - Add prominent :::{warning} admonition near the Coordinates with Units section so the dimension-coordinate pitfall is visible early, not just in Limitations - Expand the Unit Conversion common-pattern example to show uconvert() on a DataArray and the quantifyโ†’convertโ†’dequantify roundtrip - Add a new "Lower-Level API" section documenting attach_units, extract_units, extract_unit_attributes, and strip_units with runnable examples and a summary table of when to use each vs. the accessor Signed-off-by: nstarman <nstarman@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
main
2 days ago
Array-API-conformant boolean ops + dispatch consolidation (#679) * feat: isfinite returns a dimensionless Quantity (Array API) `isfinite` now returns a dimensionless Quantity of the same type as the input, so the output shares a namespace with the input per the Array API, rather than a raw jax Array. To keep this coherent: - Add mixed `and_p` registrations (Quantity/Array, both orders) that strip the dimensionless operand and return a raw array, so JAX composites (`isclose`, `allclose`, ...) that combine predicate results with raw boolean arrays keep working. - Teach `AbstractQuantity.__getitem__` to strip a dimensionless-Quantity key, so boolean masking `q[isfinite(q)]` works. * feat: comparisons (eq/ne/lt/le/gt/ge) return dimensionless Quantities The comparison primitives (and `isnan`/`isinf`, which lower to `ne`/`eq`) now return a dimensionless Quantity of the same namespace as the Quantity operand, rather than a raw jax Array, for Array API conformance. - Wrap all 18 comparison registrations via `_as_dimensionless_like`, which preserves the operand's Quantity type but falls back to a plain dimensionless `Quantity` for subtypes that cannot be dimensionless (`Angle` -> ValueError, `StaticQuantity` -> TypeError on traced values). - Add mixed `or_p` registrations (Quantity/Array, both orders) mirroring the phase-1 `and_p` ones, so predicate/comparison results degrade to raw arrays inside JAX composites (isclose, allclose, ...). - Add `select_n` registrations for a dimensionless-Quantity selector over raw-array / mixed cases (e.g. digitize, linalg.pinv). - Update doctests, integration tests, and the quantity guide accordingly. * test: lock in where driven by predicate/comparison conditions `where` (select_n) already preserves the Quantity namespace; once predicates and comparisons return dimensionless Quantities, feeding them straight into `where` works end-to-end. Add an integration test guarding that composition (comparison- and isfinite-driven conditions, plus BareQuantity end-to-end). No production code needed โ€” the capability was delivered by the comparison-phase select_n registrations. * feat: logical ops + all return dimensionless Quantities Complete the Array-API namespace consistency for boolean ops: logical/ bitwise AND/OR/XOR and `all` (reduce_and) now return a dimensionless Quantity sharing the operand's namespace, matching the comparisons and the already-converted OR/XOR/NOT/any. - `and_p` (all variants incl. mixed Quantity/Array) -> dimensionless Q. - `or_p`/`xor_p` mixed Quantity/Array variants -> dimensionless Q (xor mixed registrations added). - `reduce_and_p` (`jnp.all`) -> dimensionless Q; un-xfail test_all. - Fix select_n with a dimensionless-Quantity selector to strip it and re-dispatch through the array-selector registrations, so the result follows the *cases'* namespace. This keeps `Angle % q` an Angle and `StaticQuantity // StaticQuantity` a Quantity now that the internal `where` conditions are Quantities rather than raw arrays. - Update tests + doctests accordingly. * refactor: consolidate sort_p dispatches into one variadic handler Merge the separate one-operand (`sort`) and two-operand (`argsort`) `sort_p` registrations into a single `*operands: ABCQ | ArrayLike` dispatch that strips quantity operands, binds the primitive, and re-wraps each output by position. Besides removing duplication, this fixes a real gap: sorting a key Quantity while reordering a *second* Quantity payload of a different unit previously had no matching dispatch and raised "Refusing to materialise". Each output now keeps its own unit. Add a doctest + integration test covering multi-operand, different-unit sorting. * refactor: consolidate dispatches without type piracy (concat/stack/sort/atan2) concatenate_p / stack_p: collapse the three registrations each into a shared `_combine_quantities` helper plus two thin registrations: `(operand0: ABCQ, *rest)` and `(operand0: ArrayLike, operand1: ABCQ, *rest)`. Every registration requires a quantity in a typed position, so quax never routes an all-array `concatenate`/`stack` to these handlers -- no type piracy. (The earlier `*operands: ABCQ | ArrayLike` variadic matched all-array calls and wrapped them in a dimensionless Quantity; that band-aid guard is gone.) sort_p: tighten the consolidated handler the same way -- require the first operand (a sort key) to be a quantity, so an all-array sort is not pirated. atan2_p: drop three redundant registrations (6 -> 3). `atan2_p_qq`, `atan2_p_vq`, and `atan2_p_qv` are strict subtypes of `atan2_p_aqaq`, `atan2_p_vaq`, and `atan2_p_aqv` with identical results (`type_np` of a parametric `Quantity` is `Quantity`), so the general registrations subsume them. Their per-type doctests are folded into the survivors. * test: guard against type piracy in concat/stack/sort Add explicit regression tests asserting that concat, stack, sort, and argsort of only raw arrays return a plain jax.Array and are never wrapped in a Quantity. These lock in the "no type piracy" invariant so a future change to the variadic registrations can't silently start matching all-array calls. * refactor: collapse the four quantity-selector select_n dispatches into one Since a dimensionless-quantity `which` is handled by stripping it and re-dispatching through `qlax.select_n`, the four quantity-selector registrations (`select_n_p`, `_vq`, `_qjq`, `_qjj`) had byte-identical bodies that differed only in their case-type signatures. Merge them into a single `select_n_p_q(which: ABCQ, *cases: ABCQ | ArrayLike)`. Requiring `which` to be a quantity keeps this from pirating an all-array select_n; the result follows the cases' namespace (Quantity / Angle / StaticQuantity, or a raw array when all cases are arrays), handled by the array-selector registrations. * refactor: remove redundant parametric trig dispatches (atan2-style) The inverse-trig and (co)sine primitives each carried a parametric `..._q(x: ABCPQ["dimensionless"]/["angle"])` registration that is a strict subtype of the general `..._aq(x: ABCQ)` one with an identical result (`type_np` of a parametric `Quantity` is `Quantity`). Drop the redundant registrations for asin_p, asinh_p, atan_p, atanh_p, cos_p, and cosh_p (folding their `u.Q` doctests into the survivors), and point `cos_p_abstractangle` at `cos_p_aq`. The `_abstractangle` variants are kept: they convert the Angle to a Quantity first, since `type_np(Angle)(..., unit='')` would fail (an Angle cannot be dimensionless). Also drop the now-unused `Q` import. * refactor: use Q alias instead of Quantity in register_primitives * chore: import quaxed.lax as qlax in register_primitives Signed-off-by: nstarman <nstarman@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
main
2 days ago

Latest Branches

CodSpeed Performance Gauge
+20%
๐Ÿ‘ท build(benchmarks): add more benchmarks and config#363
1 year ago
9d3d51f
nstarman:tests/fix-benchmarks
CodSpeed Performance Gauge
0%
1 year ago
309136f
meeseeksmachine:auto-backport-of-pr-361-on-versions/v1.0.x
ยฉ 2026 CodSpeed Technology
Home Terms Privacy Docs