From 153ac867c99a9745cd1ca58746805d729ab8c5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole-Christian=20Galbo=20Engstr=C3=B8m?= Date: Tue, 30 Jun 2026 02:39:22 +0200 Subject: [PATCH] Add optional JAX backend, migrate Poetry->uv, and benchmark JAX vs NumPy JAX backend: optional backend="jax" (Literal, default "numpy") routing array ops through numpy/jax.numpy so per-fold training_XTX/XTY/XTX_XTY/statistics trace under jax.jit and batch over folds with jax.vmap on CPU/GPU/TPU. Trace-safe (tracer-gated raises keyed on val_indices, maximum/where std clamp, auto x64); numpy backend byte-identical and perf-neutral. Type hints admit jax values (FloatDType via a TYPE_CHECKING npt.DTypeLike alias). Tests parametrized over both backends + jit/vmap trace tests + degenerate-fold + jax-absent ImportError. Tooling: migrate Poetry->uv (PEP 621 [project], hatchling, PEP 735 dependency-groups; uv.lock replaces poetry.lock; ruff replaces flake8 for the build lint); version 3.1.6 -> 3.2.0. Benchmarks: optional jax backend + JAX execution-mode variants (no-/cold-/warm-JIT, CPU/GPU); two new multi-threaded CVMatrix-only figures (NumPy vs warm JAX; JIT modes). --- .github/actions/build/action.yml | 38 +- .github/actions/test/action.yml | 30 +- .../pull_request_package_workflow.yml | 2 +- .../workflows/pull_request_test_workflow.yml | 41 +- .github/workflows/test_workflow.yml | 43 +- CHANGELOG.md | 14 +- CONTRIBUTING.md | 37 +- README.md | 57 ++ benchmarks/benchmark.py | 268 ++++-- .../benchmark_cvmatrix_numpy_vs_jax.png | Bin 0 -> 138462 bytes benchmarks/benchmark_jax_variants.png | Bin 0 -> 180177 bytes benchmarks/benchmark_results.csv | 401 ++++++--- benchmarks/benchmark_results_jax.csv | 169 ++++ benchmarks/plot_benchmark.py | 250 +++++- cvmatrix/__init__.py | 2 +- cvmatrix/cvmatrix.py | 315 ++++--- examples/training_matrices_jax.py | 78 ++ poetry.lock | 87 -- pyproject.toml | 44 +- tests/test_cvmatrix.py | 135 ++- uv.lock | 800 ++++++++++++++++++ 21 files changed, 2305 insertions(+), 506 deletions(-) create mode 100644 benchmarks/benchmark_cvmatrix_numpy_vs_jax.png create mode 100644 benchmarks/benchmark_jax_variants.png create mode 100644 benchmarks/benchmark_results_jax.csv create mode 100644 examples/training_matrices_jax.py delete mode 100644 poetry.lock create mode 100644 uv.lock diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 3011cc1..23e4667 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -4,43 +4,31 @@ description: Build the package runs: using: "composite" steps: - - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v3 + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 with: python-version: '3.14' - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install flake8 pytest - python3 -m pip install poetry - python3 -m pip install twine - shell: bash - - - name: Lint with flake8 + - name: Lint with ruff run: | # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + uvx ruff check . --select=E9,F63,F7,F82 --output-format=full + # exit-zero treats all findings (line length + complexity) as warnings + uvx ruff check . --select=E501,C901 --line-length=88 --exit-zero --statistics shell: bash - - name: Install CVMatrix dependencies - run: poetry install - shell: bash - - name: Build a binary wheel and a source tarball - run: poetry build + run: uv build shell: bash - + - name: Check the distribution with twine - run: twine check dist/* + run: uvx twine check dist/* shell: bash - + - name: Store the distribution packages uses: actions/upload-artifact@v4 with: name: python-package-distributions - path: dist/ \ No newline at end of file + path: dist/ diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index ed89ad9..c675176 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -5,31 +5,33 @@ inputs: PYTHON_VERSION: description: Test Python version required: true + INSTALL_JAX: + description: Whether to install the optional JAX backend extra (true/false) + required: false + default: 'true' runs: using: "composite" steps: - - name: Set up Python - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v5 with: python-version: ${{ inputs.PYTHON_VERSION }} - - name: Install Poetry - run: | - python -m pip install --upgrade pip - python -m pip install poetry - shell: bash - - - name: Install project dependencies - run: poetry install + - name: Install project dependencies (with JAX backend) + if: ${{ inputs.INSTALL_JAX == 'true' }} + run: uv sync --extra jax --group dev shell: bash - - name: Install additional dependencies for testing - run: | - poetry add --group dev pandas pytest flake8 pytest-cov typeguard + - name: Install project dependencies (numpy-only, without JAX) + if: ${{ inputs.INSTALL_JAX != 'true' }} + run: uv sync --group dev shell: bash + # The same test suite runs in both modes. With the JAX backend installed it also + # exercises the parametrized backend="jax" tests; without JAX those parametrizations + # are skipped (pytest.importorskip), verifying the numpy-only path. - name: Run tests run: | - poetry run pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=cvmatrix/ --cov-report=xml --typeguard-packages=cvmatrix/ + uv run pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=cvmatrix/ --cov-report=xml --typeguard-packages=cvmatrix/ shell: bash diff --git a/.github/workflows/pull_request_package_workflow.yml b/.github/workflows/pull_request_package_workflow.yml index fad9e84..28f6cb1 100644 --- a/.github/workflows/pull_request_package_workflow.yml +++ b/.github/workflows/pull_request_package_workflow.yml @@ -8,7 +8,7 @@ on: - 'tests/**' - '.github/**' - 'pyproject.toml' - - 'poetry.lock' + - 'uv.lock' jobs: build_package: diff --git a/.github/workflows/pull_request_test_workflow.yml b/.github/workflows/pull_request_test_workflow.yml index 9e29b2b..0e35627 100644 --- a/.github/workflows/pull_request_test_workflow.yml +++ b/.github/workflows/pull_request_test_workflow.yml @@ -8,14 +8,15 @@ on: - 'tests/**' - '.github/**' - 'pyproject.toml' - - 'poetry.lock' + - 'uv.lock' jobs: - test_package: + # Full test suite with the JAX backend installed (also runs backend="jax" tests) + test_package_with_jax: runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: + strategy: + fail-fast: false + matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.11", "3.12", "3.13", "3.14"] steps: @@ -23,17 +24,41 @@ jobs: - uses: ./.github/actions/test with: PYTHON_VERSION: ${{ matrix.python-version }} - + INSTALL_JAX: 'true' + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: coverage.xml + flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }}-jax + parallel: true + + # Numpy-only installation (without JAX); backend="jax" tests are skipped + test_package_numpy_only: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + python-version: ["3.11", "3.12", "3.13", "3.14"] + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/test + with: + PYTHON_VERSION: ${{ matrix.python-version }} + INSTALL_JAX: 'false' + - name: Upload coverage to Coveralls uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: coverage.xml - flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }} + flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }}-numpy-only parallel: true finish: - needs: test_package + needs: [test_package_with_jax, test_package_numpy_only] runs-on: ubuntu-latest steps: - name: Finish Coveralls diff --git a/.github/workflows/test_workflow.yml b/.github/workflows/test_workflow.yml index 0b90c33..3c01227 100644 --- a/.github/workflows/test_workflow.yml +++ b/.github/workflows/test_workflow.yml @@ -8,14 +8,15 @@ on: - 'tests/**' - '.github/**' - 'pyproject.toml' - - 'poetry.lock' + - 'uv.lock' jobs: - test_package: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: + # Full test suite with the JAX backend installed (also runs backend="jax" tests) + test_package_with_jax: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.11", "3.12", "3.13", "3.14"] steps: @@ -23,17 +24,41 @@ jobs: - uses: ./.github/actions/test with: PYTHON_VERSION: ${{ matrix.python-version }} - + INSTALL_JAX: 'true' + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: coverage.xml + flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }}-jax + parallel: true + + # Numpy-only installation (without JAX); backend="jax" tests are skipped + test_package_numpy_only: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + python-version: ["3.11", "3.12", "3.13", "3.14"] + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/test + with: + PYTHON_VERSION: ${{ matrix.python-version }} + INSTALL_JAX: 'false' + - name: Upload coverage to Coveralls uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: coverage.xml - flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }} + flag-name: ${{ matrix.os }}-python-${{ matrix.python-version }}-numpy-only parallel: true finish: - needs: test_package + needs: [test_package_with_jax, test_package_numpy_only] runs-on: ubuntu-latest steps: - name: Finish Coveralls diff --git a/CHANGELOG.md b/CHANGELOG.md index 6960dd2..6b7f5fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [4.0.0] - 2025 +## [3.2.0] - 2026-06-29 + +### Added +- Optional **JAX backend** for `CVMatrix` via `backend="jax"` (a `Literal["numpy", "jax"]`; default remains `"numpy"`). All array operations are routed through a resolved array namespace (`numpy` or `jax.numpy`), so the per-fold `training_XTX`/`training_XTY`/`training_XTX_XTY`/`training_statistics` computations can be traced by `jax.jit` and batched with `jax.vmap` on CPU/GPU/TPU. Install with `cvmatrix[jax]`. +- Backend-neutral, trace-safe standard-deviation clamping (`maximum`/`where` instead of boolean-mask assignment). Degenerate-fold validation (`ValueError`s) still fires for eager (numpy or concrete jax) execution; under `jax.jit`/`jax.vmap` tracing the check is deferred to a host-side pre-flight by the caller. + +### Changed +- Switched build and development tooling from Poetry to [uv](https://docs.astral.sh/uv/): the project now uses PEP 621 `[project]` metadata, the `hatchling` build backend, and a PEP 735 `[dependency-groups]` dev group (`poetry.lock` is replaced by `uv.lock`). The published package, its runtime dependencies, and the `jax` extra are unchanged. + +### Notes +- The numpy backend is byte-identical to previous releases (verified against the existing test suite) and performance-neutral. + +## [3.1.6] - 2025 ### Changed - `CVMatrix` and `Partitioner` can now be imported with `from cvmatrix import CVMatrix, Partitioner` or `import cvmatrix` followed by `cvmatrix.CVMatrix` and `cvmatrix.Partitioner`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b4eefc..afff81c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,7 +44,7 @@ If you feel like you've made a valuable contribution, but you don't know how to ## Build from source -CVMatrix uses [poetry](https://python-poetry.org/) to manage its dependencies and packaging. To build the package from source, follow these steps: +CVMatrix uses [uv](https://docs.astral.sh/uv/) to manage its dependencies and packaging. To build the package from source, follow these steps: 1. Clone the repository: @@ -58,57 +58,50 @@ CVMatrix uses [poetry](https://python-poetry.org/) to manage its dependencies an cd CVMatrix ``` -3. Install poetry and twine: +3. [Install uv](https://docs.astral.sh/uv/getting-started/installation/), e.g.: ```shell - pip3 install poetry - pip3 install twine + curl -LsSf https://astral.sh/uv/install.sh | sh ``` -4. Install the dependencies: +4. Build the package. uv builds in an isolated environment, so no separate dependency-install step is needed: ```shell - poetry install + uv build ``` -5. Build the package: +5. Check the package with twine: ```shell - poetry build - ``` - -6. Check the package with twine: - - ```shell - twine check dist/* + uvx twine check dist/* ``` ## Run the test suite To run the test suite, follow these steps: -1. Install poetry: +1. [Install uv](https://docs.astral.sh/uv/getting-started/installation/), e.g.: ```shell - pip3 install poetry + curl -LsSf https://astral.sh/uv/install.sh | sh ``` -2. Install the project dependencies with poetry: +2. Install the project together with its development dependencies. To also exercise the optional JAX backend (the `backend="jax"` tests), include the `jax` extra: ```shell - poetry install + uv sync --extra jax --group dev ``` -3. Install additional dependencies for testing: + To test the numpy-only installation instead (the `backend="jax"` tests are skipped automatically), omit the extra: ```shell - poetry add --group dev pandas pytest flake8 pytest-cov typeguard + uv sync --group dev ``` -4. Now, the tests can be run with the following command: +3. Now, the tests can be run with the following command: ```shell - poetry run pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=cvmatrix/ --cov-report=xml --cov-report=html --typeguard-packages=cvmatrix/ + uv run pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=cvmatrix/ --cov-report=xml --cov-report=html --typeguard-packages=cvmatrix/ ``` ## Build the documentation diff --git a/README.md b/README.md index d3b0139..e406827 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,54 @@ The `cvmatrix` software package now also features **weigthed matrix produts** $\ from cvmatrix import CVMatrix ``` +- You can also install the optional JAX dependency to enable the JAX backend of + `CVMatrix`: + ```shell + pip3 install "cvmatrix[jax]" + ``` +- Now, you can select the JAX backend by passing `backend="jax"` to the constructor: + ```python + from cvmatrix import CVMatrix + + cvm = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, backend="jax" + ) + ``` + With `backend="jax"`, the per-fold training-matrix computations (`training_XTX`, + `training_XTY`, `training_XTX_XTY`, and `training_statistics`) use `jax.numpy` and can + be traced by `jax.jit` and batched over folds with `jax.vmap` on CPUs, GPUs, and TPUs. + The default `backend="numpy"` is unchanged and remains byte-for-byte identical to + previous releases. + +### Prerequisites for the JAX backend + +The JAX backend supports running on CPU, GPU, and TPU. + +- To enable NVIDIA GPU execution, install JAX and CUDA with: + ```shell + pip3 install -U "jax[cuda13]" + ``` + +- To enable Google Cloud TPU execution, install JAX with: + ```shell + pip3 install -U "jax[tpu]" + ``` + +These are typical installation instructions that will be what most users are looking for. +For customized installations, follow the instructions from the [JAX Installation +Guide](https://jax.readthedocs.io/en/latest/installation.html). + +To ensure that the JAX backend uses float64, set the environment variable +```JAX_ENABLE_X64=True``` as per the [Common +Gotchas](https://docs.jax.dev/en/latest/notebooks/Common_Gotchas_in_JAX.html#double-64bit-precision). +`CVMatrix` also enables this automatically when constructed with `backend="jax"` and a +64-bit `dtype` (the default). Alternatively, float64 can be enabled with the following +function call: +```python +import jax +jax.config.update("jax_enable_x64", True) +``` + ## Quick Start ### Use the cvmatrix package for fast computation of training set kernel matrices @@ -96,6 +144,7 @@ The `cvmatrix` software package now also features **weigthed matrix produts** $\ In [examples](https://github.com/Sm00thix/CVMatrix/tree/main/examples), you will find: - [Compute training matrices with CVMatrix](https://github.com/Sm00thix/CVMatrix/tree/main/examples/training_matrices.py) +- [Compute training matrices with the JAX backend, batched over folds with `jax.vmap` on CPU/GPU/TPU](https://github.com/Sm00thix/CVMatrix/tree/main/examples/training_matrices_jax.py) ## Benchmarks @@ -107,6 +156,14 @@ In [benchmarks](https://github.com/Sm00thix/CVMatrix/tree/main/benchmarks), we h Left: Benchmarking cross-validation with the CVMatrix implementation versus the baseline implementation using three common combinations of (column-wise) centering and scaling. Right: Benchmarking cross-validation with the CVMatrix implementation for all possible combinations of (column-wise) centering and scaling. Here, most of the graphs lie on top of eachother. In general, no preprocessing is faster than centering which, in turn, is faster than scaling.

+The figures below add the optional JAX backend to the comparison (NumPy vs. JAX, and the JAX execution modes). They are measured **multi-threaded** (no thread limit; GPU on an NVIDIA RTX 3090 Ti) and **exclude `NaiveCVMatrix`**: + +

+ +
+ Left: CVMatrix with the NumPy backend versus the JAX backend (warm, JIT-compiled jax.vmap over folds) on CPU and GPU, for the three common preprocessing combinations. Right: The JAX backend under no-JIT (eager vmap), cold-JIT (compilation + run) and warm-JIT (run only), on CPU and GPU. JIT compilation is a large fixed cost: on the GPU, no-JIT beats cold-JIT for a single run, whereas on the CPU, JIT (even cold) is far faster than eager vmap at a large number of folds. +

+ ## Contribute To contribute, please read the [Contribution diff --git a/benchmarks/benchmark.py b/benchmarks/benchmark.py index 872878d..7638480 100644 --- a/benchmarks/benchmark.py +++ b/benchmarks/benchmark.py @@ -17,10 +17,8 @@ # Add the parent directory of 'CVMatrix' to sys.path sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -# Set the number of threads to 1. This must be done before importing numpy. -os.environ["OMP_NUM_THREADS"] = "1" - from itertools import product +from time import perf_counter from timeit import timeit from typing import Hashable, Iterable, Union @@ -35,15 +33,15 @@ def save_result_to_csv( model, use_weights, P, N, K, M, center_X, center_Y, scale_X, scale_Y, time, version ): + csv_path = os.environ.get("BENCH_CSV", "benchmark_results.csv") try: - with open("benchmark_results.csv", "x") as f: + with open(csv_path, "x") as f: f.write( - "model,weights,P,N,K,M," - "center_X,center_Y,scale_X,scale_Y,time,version\n" + "model,weights,P,N,K,M,center_X,center_Y,scale_X,scale_Y,time,version\n" ) except FileExistsError: pass - with open("benchmark_results.csv", "a") as f: + with open(csv_path, "a") as f: f.write( f"{model},{use_weights},{P},{N},{K},{M}," f"{center_X},{center_Y},{scale_X},{scale_Y}," @@ -61,6 +59,8 @@ def execute_algorithm( X: np.ndarray, Y: np.ndarray, weights: Union[None, np.ndarray], + backend: str = "numpy", + batch_size: int = 10000, ): """ Execute the computation of the training set matrices @@ -98,15 +98,26 @@ def execute_algorithm( The weights for the samples, if any. If None, no weights are used. """ - # Create the model - model = model_class( - center_X=center_X, - center_Y=center_Y, - scale_X=scale_X, - scale_Y=scale_Y, - dtype=X.dtype, - copy=True, - ) + # Create the model. The CVMatrix model takes a `backend` ("numpy" or "jax"). + if model_class is CVMatrix: + model = CVMatrix( + center_X=center_X, + center_Y=center_Y, + scale_X=scale_X, + scale_Y=scale_Y, + dtype=X.dtype, + copy=True, + backend=backend, + ) + else: + model = model_class( + center_X=center_X, + center_Y=center_Y, + scale_X=scale_X, + scale_Y=scale_Y, + dtype=X.dtype, + copy=True, + ) # Create the validation partitioner p = Partitioner(folds=cv_splits) @@ -122,6 +133,23 @@ def execute_algorithm( [p.get_validation_indices(f) for f in p.folds_dict if f != fold] ) model.training_XTX_XTY(training_indices) + elif backend == "jax": + # Batch the per-fold training matrices over folds with jax.vmap (grouping by + # validation-set size so shapes are fixed, and chunking by `batch_size` to bound + # memory). + import jax + import jax.numpy as jnp + from collections import defaultdict + + buckets: dict[int, list] = defaultdict(list) + for fold in p.folds_dict: + vi = p.get_validation_indices(fold) + buckets[vi.shape[0]].append(vi) + vmapped = jax.jit(jax.vmap(model.training_XTX_XTY)) + for vis in buckets.values(): + stack = jnp.asarray(np.stack(vis)) + for s in range(0, len(vis), batch_size): + jax.block_until_ready(vmapped(stack[s : s + batch_size])) else: # Compute the training set matrices for fold in p.folds_dict: @@ -130,26 +158,130 @@ def execute_algorithm( model.training_XTX_XTY(validation_indices) +def benchmark_jax_variants( + cv_splits, center_X, center_Y, scale_X, scale_Y, X, Y, weights, batch_size +): + """ + Times the per-fold training-matrix computation (vmapped over folds, chunked by + `batch_size`) under three JAX execution modes, each including the one-time fit so the + result is the total cross-validation time (comparable to the numpy/naive totals): + + - "nojit": eager ``jax.vmap`` (no JIT compilation). + - "coldjit": ``jax.jit(jax.vmap(...))`` timed on its first call (compilation + run). + - "warmjit": the same jitted function timed on a subsequent call (run only). + + Returns a dict mapping each mode to its total time in seconds. + """ + import jax + import jax.numpy as jnp + from collections import defaultdict + + p = Partitioner(folds=cv_splits) + + t0 = perf_counter() + model = CVMatrix( + center_X=center_X, center_Y=center_Y, scale_X=scale_X, scale_Y=scale_Y, + dtype=X.dtype, copy=True, backend="jax", + ) + model.fit(X, Y, weights) + # Stack the per-fold validation indices into fixed-shape batches (one per fold size). + buckets = defaultdict(list) + for fold in p.folds_dict: + vi = p.get_validation_indices(fold) + buckets[vi.shape[0]].append(vi) + batches = [jnp.asarray(np.stack(vis)) for vis in buckets.values()] + fit_time = perf_counter() - t0 + + def run(vf): + for stack in batches: + for s in range(0, stack.shape[0], batch_size): + jax.block_until_ready(vf(stack[s : s + batch_size])) + + # No JIT: eager vmap. + vf_nojit = jax.vmap(model.training_XTX_XTY) + t0 = perf_counter() + run(vf_nojit) + nojit = perf_counter() - t0 + + # JIT: the first call compiles (cold); a subsequent call reuses it (warm). + vf_jit = jax.jit(jax.vmap(model.training_XTX_XTY)) + t0 = perf_counter() + run(vf_jit) + coldjit = perf_counter() - t0 + t0 = perf_counter() + run(vf_jit) + warmjit = perf_counter() - t0 + + return { + "nojit": fit_time + nojit, + "coldjit": fit_time + coldjit, + "warmjit": fit_time + warmjit, + } + + if __name__ == "__main__": seed = 42 # Seed for reproducibility rng = np.random.default_rng(seed=seed) - N = 100000 # 100k samples - K = 500 # 500 features - M = 10 # 10 targets + N = int(os.environ.get("BENCH_N", 100000)) # 100k samples + K = int(os.environ.get("BENCH_K", 500)) # 500 features + M = int(os.environ.get("BENCH_M", 10)) # 10 targets dtype = np.float64 # Data type X = rng.random((N, K), dtype=dtype) # Random X matrix Y = rng.random((N, M), dtype=dtype) # Random Y matrix weights = rng.random((N,), dtype=dtype) # Random weights cv_splits = np.arange(N) # We can use mod P for P-fold cross-validation use_weights = [True, False] # Whether to use weights or not - center_Xs = [True, False] - center_Ys = [True, False] - scale_Xs = [True, False] - scale_Ys = [True, False] - Ps = [3, 5, 10, 100, 1000, 10000, 100000] - - for use_w, center_X, center_Y, scale_X, scale_Y, P in product( - use_weights, center_Xs, center_Ys, scale_Xs, scale_Ys, Ps + # Preprocessing combinations. BENCH_CONFIGS="plot" restricts to the three + # combinations shown in benchmark_cvmatrix_vs_naive.png (and the ones for which + # NaiveCVMatrix is benchmarked): no preprocessing, centering only, and centering + + # scaling. "all" (the default) sweeps every combination of the four flags. + if os.environ.get("BENCH_CONFIGS", "all") == "plot": + preprocessing_configs = [ + (False, False, False, False), + (True, True, False, False), + (True, True, True, True), + ] + else: + preprocessing_configs = list( + product([True, False], [True, False], [True, False], [True, False]) + ) + # Ps = [3, 5, 10, 100, 1000, 10000, 100000] + Ps = [int(p) for p in os.environ.get("BENCH_PS", "100000").split(",")] + # CVMatrix backends to benchmark (comma-separated). "jax" requires cvmatrix[jax]. + backends = os.environ.get("BENCH_BACKENDS", "numpy").split(",") + batch_size = int(os.environ.get("BENCH_BATCH", 10000)) + + # BENCH_JAX_VARIANTS=1: instead of the numpy/naive/jax sweep, benchmark the JAX + # backend under no-JIT / cold-JIT / warm-JIT (weighted only) for the figure + # benchmark_jax_variants.png. + if os.environ.get("BENCH_JAX_VARIANTS", "0") == "1": + import jax + + platform = jax.devices()[0].platform + for (center_X, center_Y, scale_X, scale_Y), P in product( + preprocessing_configs, Ps + ): + print( + f"JAX variants ({platform}): P={P}, center_X={center_X}, " + f"center_Y={center_Y}, scale_X={scale_X}, scale_Y={scale_Y}" + ) + mode_times = benchmark_jax_variants( + cv_splits % P, center_X, center_Y, scale_X, scale_Y, + X, Y, weights, batch_size, + ) + for mode, t in mode_times.items(): + print(f" CVMatrix-jax-{platform}-{mode}: {t:.2f} seconds") + save_result_to_csv( + f"CVMatrix-jax-{platform}-{mode}", + True, + P, N, K, M, + center_X, center_Y, scale_X, scale_Y, + t, __version__, + ) + sys.exit(0) + + for use_w, (center_X, center_Y, scale_X, scale_Y), P in product( + use_weights, preprocessing_configs, Ps ): print( f"weights={use_w}, " @@ -157,40 +289,56 @@ def execute_algorithm( f"center_X={center_X}, center_Y={center_Y}, " f"scale_X={scale_X}, scale_Y={scale_Y}, " ) - time = timeit( - stmt=lambda: execute_algorithm( - model_class=CVMatrix, - cv_splits=cv_splits % P, - center_X=center_X, - center_Y=center_Y, - scale_X=scale_X, - scale_Y=scale_Y, - X=X, - Y=Y, - weights=weights if use_weights else None, - ), - number=1, - ) - print(f"CVMatrix, Time: {time:.2f} seconds") - save_result_to_csv( - "CVMatrix", - use_w, - P, - N, - K, - M, - center_X, - center_Y, - scale_X, - scale_Y, - time, - __version__, - ) + for backend in backends: + time = timeit( + stmt=lambda backend=backend: execute_algorithm( + model_class=CVMatrix, + cv_splits=cv_splits % P, + center_X=center_X, + center_Y=center_Y, + scale_X=scale_X, + scale_Y=scale_Y, + X=X, + Y=Y, + weights=weights if use_w else None, + backend=backend, + batch_size=batch_size, + ), + number=1, + ) + if backend == "jax": + import jax + + # Distinguish CPU vs GPU/TPU JAX runs in the results. + model_name = f"CVMatrix-jax-{jax.devices()[0].platform}" + else: + model_name = ( + "CVMatrix" if backend == "numpy" else f"CVMatrix-{backend}" + ) + print(f"{model_name}, Time: {time:.2f} seconds") + save_result_to_csv( + model_name, + use_w, + P, + N, + K, + M, + center_X, + center_Y, + scale_X, + scale_Y, + time, + __version__, + ) - if ( + # NaiveCVMatrix is only benchmarked for the three preprocessing combinations + # shown in benchmark_cvmatrix_vs_naive.png (no preprocessing, centering only, and + # centering + scaling). It is extremely slow (hours at large P), so it only runs + # when BENCH_NAIVE=1 is set explicitly. + if os.environ.get("BENCH_NAIVE", "0") == "1" and ( center_X == center_Y == scale_X == scale_Y - or center_X == center_Y == True - and scale_X == scale_Y == False + or center_X == center_Y is True + and scale_X == scale_Y is False ): time = timeit( stmt=lambda: execute_algorithm( @@ -202,7 +350,7 @@ def execute_algorithm( scale_Y=scale_Y, X=X, Y=Y, - weights=weights, + weights=weights if use_w else None, ), number=1, ) diff --git a/benchmarks/benchmark_cvmatrix_numpy_vs_jax.png b/benchmarks/benchmark_cvmatrix_numpy_vs_jax.png new file mode 100644 index 0000000000000000000000000000000000000000..7aa4e105aa8cd62fc6f43185240252bc615d1bd7 GIT binary patch literal 138462 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¨R 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

{)zV>ZYjzqHaSo>(S*Ro-Cbv2)qRMhq(&VEOF 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 z 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 TVRF}IXs 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 literal 0 HcmV?d00001 diff --git a/benchmarks/benchmark_results.csv b/benchmarks/benchmark_results.csv index b288dec..bb767dd 100644 --- a/benchmarks/benchmark_results.csv +++ b/benchmarks/benchmark_results.csv @@ -1,134 +1,267 @@ -model,P,N,K,M,center_X,center_Y,scale_X,scale_Y,time,version -CVMatrix,3,100000,500,10,True,True,True,True,1.1192415489999803,1.0.0 -NaiveCVMatrix,3,100000,500,10,True,True,True,True,1.525318347999928,1.0.0 -CVMatrix,5,100000,500,10,True,True,True,True,1.1311610759998985,1.0.0 -NaiveCVMatrix,5,100000,500,10,True,True,True,True,3.018902382000306,1.0.0 -CVMatrix,10,100000,500,10,True,True,True,True,1.1376194539998323,1.0.0 -NaiveCVMatrix,10,100000,500,10,True,True,True,True,6.742205670000203,1.0.0 -CVMatrix,100,100000,500,10,True,True,True,True,1.1367952779996813,1.0.0 -NaiveCVMatrix,100,100000,500,10,True,True,True,True,73.3318574079999,1.0.0 -CVMatrix,1000,100000,500,10,True,True,True,True,1.7896336470003007,1.0.0 -NaiveCVMatrix,1000,100000,500,10,True,True,True,True,729.6242519150001,1.0.0 -CVMatrix,10000,100000,500,10,True,True,True,True,8.568363662000138,1.0.0 -NaiveCVMatrix,10000,100000,500,10,True,True,True,True,7256.869186553,1.0.0 -CVMatrix,100000,100000,500,10,True,True,True,True,87.74830843000018,1.0.0 -NaiveCVMatrix,100000,100000,500,10,True,True,True,True,73826.453205139,1.0.0 -CVMatrix,3,100000,500,10,True,True,True,False,1.118339446009486,1.0.0 -CVMatrix,5,100000,500,10,True,True,True,False,1.123899715996231,1.0.0 -CVMatrix,10,100000,500,10,True,True,True,False,1.12319784500869,1.0.0 -CVMatrix,100,100000,500,10,True,True,True,False,1.114717668009689,1.0.0 -CVMatrix,1000,100000,500,10,True,True,True,False,1.7559398589946795,1.0.0 -CVMatrix,10000,100000,500,10,True,True,True,False,8.289280587996473,1.0.0 -CVMatrix,100000,100000,500,10,True,True,True,False,86.02160608601116,1.0.0 -CVMatrix,3,100000,500,10,True,True,False,True,1.0702028819941916,1.0.0 -CVMatrix,5,100000,500,10,True,True,False,True,1.0765490460034923,1.0.0 -CVMatrix,10,100000,500,10,True,True,False,True,1.0745869239908643,1.0.0 -CVMatrix,100,100000,500,10,True,True,False,True,1.0526132069935557,1.0.0 -CVMatrix,1000,100000,500,10,True,True,False,True,1.4689054019981995,1.0.0 -CVMatrix,10000,100000,500,10,True,True,False,True,5.673868882993702,1.0.0 -CVMatrix,100000,100000,500,10,True,True,False,True,59.158317786990665,1.0.0 -CVMatrix,3,100000,500,10,True,True,False,False,1.071286210004473,1.0.0 -NaiveCVMatrix,3,100000,500,10,True,True,False,False,1.2249300480034435,1.0.0 -CVMatrix,5,100000,500,10,True,True,False,False,1.0742946690006647,1.0.0 -NaiveCVMatrix,5,100000,500,10,True,True,False,False,2.3995333990023937,1.0.0 -CVMatrix,10,100000,500,10,True,True,False,False,1.0759979769936765,1.0.0 -NaiveCVMatrix,10,100000,500,10,True,True,False,False,5.318012420000741,1.0.0 -CVMatrix,100,100000,500,10,True,True,False,False,1.0516475519980304,1.0.0 -NaiveCVMatrix,100,100000,500,10,True,True,False,False,57.35077489100513,1.0.0 -CVMatrix,1000,100000,500,10,True,True,False,False,1.4252776270004688,1.0.0 -NaiveCVMatrix,1000,100000,500,10,True,True,False,False,578.4537375619984,1.0.0 -CVMatrix,10000,100000,500,10,True,True,False,False,5.3335611680086,1.0.0 -NaiveCVMatrix,10000,100000,500,10,True,True,False,False,5781.912272988004,1.0.0 -CVMatrix,100000,100000,500,10,True,True,False,False,56.71489888700307,1.0.0 -NaiveCVMatrix,100000,100000,500,10,True,True,False,False,58952.35878656501,1.0.0 -CVMatrix,3,100000,500,10,True,False,True,True,1.1248798799933866,1.0.0 -CVMatrix,5,100000,500,10,True,False,True,True,1.1283268360130023,1.0.0 -CVMatrix,10,100000,500,10,True,False,True,True,1.1263538440107368,1.0.0 -CVMatrix,100,100000,500,10,True,False,True,True,1.119193897000514,1.0.0 -CVMatrix,1000,100000,500,10,True,False,True,True,1.7814686659839936,1.0.0 -CVMatrix,10000,100000,500,10,True,False,True,True,8.538902194995899,1.0.0 -CVMatrix,100000,100000,500,10,True,False,True,True,87.61705726798391,1.0.0 -CVMatrix,3,100000,500,10,True,False,True,False,1.1210701089876238,1.0.0 -CVMatrix,5,100000,500,10,True,False,True,False,1.1266690100019332,1.0.0 -CVMatrix,10,100000,500,10,True,False,True,False,1.1292253129940946,1.0.0 -CVMatrix,100,100000,500,10,True,False,True,False,1.1189919460157398,1.0.0 -CVMatrix,1000,100000,500,10,True,False,True,False,1.7613697280175984,1.0.0 -CVMatrix,10000,100000,500,10,True,False,True,False,8.302096697007073,1.0.0 -CVMatrix,100000,100000,500,10,True,False,True,False,86.14565880500595,1.0.0 -CVMatrix,3,100000,500,10,True,False,False,True,1.0740263529878575,1.0.0 -CVMatrix,5,100000,500,10,True,False,False,True,1.072119502001442,1.0.0 -CVMatrix,10,100000,500,10,True,False,False,True,1.069851884996751,1.0.0 -CVMatrix,100,100000,500,10,True,False,False,True,1.0546411169925705,1.0.0 -CVMatrix,1000,100000,500,10,True,False,False,True,1.4577812999777962,1.0.0 -CVMatrix,10000,100000,500,10,True,False,False,True,5.598208290990442,1.0.0 -CVMatrix,100000,100000,500,10,True,False,False,True,59.14233927798341,1.0.0 -CVMatrix,3,100000,500,10,True,False,False,False,1.072362840990536,1.0.0 -CVMatrix,5,100000,500,10,True,False,False,False,1.068599329009885,1.0.0 -CVMatrix,10,100000,500,10,True,False,False,False,1.0694805849925615,1.0.0 -CVMatrix,100,100000,500,10,True,False,False,False,1.051443169999402,1.0.0 -CVMatrix,1000,100000,500,10,True,False,False,False,1.4250595640041863,1.0.0 -CVMatrix,10000,100000,500,10,True,False,False,False,5.306501427985495,1.0.0 -CVMatrix,100000,100000,500,10,True,False,False,False,56.23384317601449,1.0.0 -CVMatrix,3,100000,500,10,False,True,True,True,1.1242727210046723,1.0.0 -CVMatrix,5,100000,500,10,False,True,True,True,1.1221562070131768,1.0.0 -CVMatrix,10,100000,500,10,False,True,True,True,1.1232905049982946,1.0.0 -CVMatrix,100,100000,500,10,False,True,True,True,1.093528530007461,1.0.0 -CVMatrix,1000,100000,500,10,False,True,True,True,1.50849640899105,1.0.0 -CVMatrix,10000,100000,500,10,False,True,True,True,5.678116741997656,1.0.0 -CVMatrix,100000,100000,500,10,False,True,True,True,59.44565243599936,1.0.0 -CVMatrix,3,100000,500,10,False,True,True,False,1.1244757279928308,1.0.0 -CVMatrix,5,100000,500,10,False,True,True,False,1.1264495220093522,1.0.0 -CVMatrix,10,100000,500,10,False,True,True,False,1.1244927080115303,1.0.0 -CVMatrix,100,100000,500,10,False,True,True,False,1.0898696849762928,1.0.0 -CVMatrix,1000,100000,500,10,False,True,True,False,1.487639525992563,1.0.0 -CVMatrix,10000,100000,500,10,False,True,True,False,5.532944937003776,1.0.0 -CVMatrix,100000,100000,500,10,False,True,True,False,57.769016504025785,1.0.0 -CVMatrix,3,100000,500,10,False,True,False,True,1.0699797239794862,1.0.0 -CVMatrix,5,100000,500,10,False,True,False,True,1.076646833011182,1.0.0 -CVMatrix,10,100000,500,10,False,True,False,True,1.066042849997757,1.0.0 -CVMatrix,100,100000,500,10,False,True,False,True,1.022873626992805,1.0.0 -CVMatrix,1000,100000,500,10,False,True,False,True,1.1741839119931683,1.0.0 -CVMatrix,10000,100000,500,10,False,True,False,True,2.767864119989099,1.0.0 -CVMatrix,100000,100000,500,10,False,True,False,True,31.288429460983025,1.0.0 -CVMatrix,3,100000,500,10,False,True,False,False,1.067737389006652,1.0.0 -CVMatrix,5,100000,500,10,False,True,False,False,1.0645694179984275,1.0.0 -CVMatrix,10,100000,500,10,False,True,False,False,1.0654148519970477,1.0.0 -CVMatrix,100,100000,500,10,False,True,False,False,1.0180366100103129,1.0.0 -CVMatrix,1000,100000,500,10,False,True,False,False,1.1448387459968217,1.0.0 -CVMatrix,10000,100000,500,10,False,True,False,False,2.4890578409831505,1.0.0 -CVMatrix,100000,100000,500,10,False,True,False,False,28.57835416399757,1.0.0 -CVMatrix,3,100000,500,10,False,False,True,True,1.1212003620166795,1.0.0 -CVMatrix,5,100000,500,10,False,False,True,True,1.1258387090056203,1.0.0 -CVMatrix,10,100000,500,10,False,False,True,True,1.128786824992858,1.0.0 -CVMatrix,100,100000,500,10,False,False,True,True,1.0982693690166343,1.0.0 -CVMatrix,1000,100000,500,10,False,False,True,True,1.4995669290074147,1.0.0 -CVMatrix,10000,100000,500,10,False,False,True,True,5.570729988015955,1.0.0 -CVMatrix,100000,100000,500,10,False,False,True,True,58.68603180799983,1.0.0 -CVMatrix,3,100000,500,10,False,False,True,False,1.1134203580149915,1.0.0 -CVMatrix,5,100000,500,10,False,False,True,False,1.1239128790039103,1.0.0 -CVMatrix,10,100000,500,10,False,False,True,False,1.1241297630185727,1.0.0 -CVMatrix,100,100000,500,10,False,False,True,False,1.087912362010684,1.0.0 -CVMatrix,1000,100000,500,10,False,False,True,False,1.4660285169957206,1.0.0 -CVMatrix,10000,100000,500,10,False,False,True,False,5.316281512990827,1.0.0 -CVMatrix,100000,100000,500,10,False,False,True,False,56.17939067899715,1.0.0 -CVMatrix,3,100000,500,10,False,False,False,True,1.0351853250176646,1.0.0 -CVMatrix,5,100000,500,10,False,False,False,True,1.033534198009875,1.0.0 -CVMatrix,10,100000,500,10,False,False,False,True,1.0377773079962935,1.0.0 -CVMatrix,100,100000,500,10,False,False,False,True,0.9942518580064644,1.0.0 -CVMatrix,1000,100000,500,10,False,False,False,True,1.1315311660000589,1.0.0 -CVMatrix,10000,100000,500,10,False,False,False,True,2.5680760239774827,1.0.0 -CVMatrix,100000,100000,500,10,False,False,False,True,29.533790613000747,1.0.0 -CVMatrix,3,100000,500,10,False,False,False,False,1.0287453010096217,1.0.0 -NaiveCVMatrix,3,100000,500,10,False,False,False,False,1.0761993249761872,1.0.0 -CVMatrix,5,100000,500,10,False,False,False,False,1.0289292840170674,1.0.0 -NaiveCVMatrix,5,100000,500,10,False,False,False,False,2.1083633030066267,1.0.0 -CVMatrix,10,100000,500,10,False,False,False,False,1.0330040709814057,1.0.0 -NaiveCVMatrix,10,100000,500,10,False,False,False,False,4.668692281993572,1.0.0 -CVMatrix,100,100000,500,10,False,False,False,False,0.9845351910043972,1.0.0 -NaiveCVMatrix,100,100000,500,10,False,False,False,False,50.40878304699436,1.0.0 -CVMatrix,1000,100000,500,10,False,False,False,False,1.0881256299908273,1.0.0 -NaiveCVMatrix,1000,100000,500,10,False,False,False,False,506.2128036149952,1.0.0 -CVMatrix,10000,100000,500,10,False,False,False,False,2.194315168017056,1.0.0 -NaiveCVMatrix,10000,100000,500,10,False,False,False,False,5044.3570687549945,1.0.0 -CVMatrix,100000,100000,500,10,False,False,False,False,26.013640838005813,1.0.0 -NaiveCVMatrix,100000,100000,500,10,False,False,False,False,52100.47697248199,1.0.0 +model,weights,P,N,K,M,center_X,center_Y,scale_X,scale_Y,time,version +CVMatrix,True,3,100000,500,10,True,True,True,True,1.984333821994369,3.1.2 +NaiveCVMatrix,True,3,100000,500,10,True,True,True,True,2.391529404994799,3.1.2 +CVMatrix,True,5,100000,500,10,True,True,True,True,2.0060565159947146,3.1.2 +NaiveCVMatrix,True,5,100000,500,10,True,True,True,True,4.756514220003737,3.1.2 +CVMatrix,True,10,100000,500,10,True,True,True,True,2.0229949439963093,3.1.2 +NaiveCVMatrix,True,10,100000,500,10,True,True,True,True,10.702684000993031,3.1.2 +CVMatrix,True,100,100000,500,10,True,True,True,True,1.9863586209976347,3.1.2 +NaiveCVMatrix,True,100,100000,500,10,True,True,True,True,116.75834354999824,3.1.2 +CVMatrix,True,1000,100000,500,10,True,True,True,True,2.696976027000346,3.1.2 +NaiveCVMatrix,True,1000,100000,500,10,True,True,True,True,1167.3831180050038,3.1.2 +CVMatrix,True,10000,100000,500,10,True,True,True,True,10.405765339004574,3.1.2 +NaiveCVMatrix,True,10000,100000,500,10,True,True,True,True,11684.97914216001,3.1.2 +CVMatrix,True,100000,100000,500,10,True,True,True,True,97.79410633000953,3.1.2 +NaiveCVMatrix,True,100000,100000,500,10,True,True,True,True,117450.870239473,3.1.2 +CVMatrix,True,3,100000,500,10,True,True,True,False,1.9866961159859784,3.1.2 +CVMatrix,True,5,100000,500,10,True,True,True,False,1.9947043650026899,3.1.2 +CVMatrix,True,10,100000,500,10,True,True,True,False,2.0186615100246854,3.1.2 +CVMatrix,True,100,100000,500,10,True,True,True,False,1.9616220210155006,3.1.2 +CVMatrix,True,1000,100000,500,10,True,True,True,False,2.6776564110186882,3.1.2 +CVMatrix,True,10000,100000,500,10,True,True,True,False,10.229800548026105,3.1.2 +CVMatrix,True,100000,100000,500,10,True,True,True,False,96.38440647299285,3.1.2 +CVMatrix,True,3,100000,500,10,True,True,False,True,1.8646600369829684,3.1.2 +CVMatrix,True,5,100000,500,10,True,True,False,True,1.8728829300089274,3.1.2 +CVMatrix,True,10,100000,500,10,True,True,False,True,1.8833721109840553,3.1.2 +CVMatrix,True,100,100000,500,10,True,True,False,True,1.8414228140027262,3.1.2 +CVMatrix,True,1000,100000,500,10,True,True,False,True,2.2803589590184856,3.1.2 +CVMatrix,True,10000,100000,500,10,True,True,False,True,7.142492076003691,3.1.2 +CVMatrix,True,100000,100000,500,10,True,True,False,True,65.46094575102325,3.1.2 +CVMatrix,True,3,100000,500,10,True,True,False,False,1.8603149139962625,3.1.2 +NaiveCVMatrix,True,3,100000,500,10,True,True,False,False,2.0659156549954787,3.1.2 +CVMatrix,True,5,100000,500,10,True,True,False,False,1.8669229579973035,3.1.2 +NaiveCVMatrix,True,5,100000,500,10,True,True,False,False,4.117473580001388,3.1.2 +CVMatrix,True,10,100000,500,10,True,True,False,False,1.8735272120102309,3.1.2 +NaiveCVMatrix,True,10,100000,500,10,True,True,False,False,9.192210117995273,3.1.2 +CVMatrix,True,100,100000,500,10,True,True,False,False,1.8366783630044665,3.1.2 +NaiveCVMatrix,True,100,100000,500,10,True,True,False,False,100.20058388100006,3.1.2 +CVMatrix,True,1000,100000,500,10,True,True,False,False,2.2641661269881297,3.1.2 +NaiveCVMatrix,True,1000,100000,500,10,True,True,False,False,1013.2832974810153,3.1.2 +CVMatrix,True,10000,100000,500,10,True,True,False,False,6.955503848002991,3.1.2 +NaiveCVMatrix,True,10000,100000,500,10,True,True,False,False,10075.192611823994,3.1.2 +CVMatrix,True,100000,100000,500,10,True,True,False,False,63.794935021025594,3.1.2 +NaiveCVMatrix,True,100000,100000,500,10,True,True,False,False,101962.998182905,3.1.2 +CVMatrix,True,3,100000,500,10,True,False,True,True,1.9902973789721727,3.1.2 +CVMatrix,True,5,100000,500,10,True,False,True,True,2.0029557759989984,3.1.2 +CVMatrix,True,10,100000,500,10,True,False,True,True,2.0234543079859577,3.1.2 +CVMatrix,True,100,100000,500,10,True,False,True,True,1.9662584849866107,3.1.2 +CVMatrix,True,1000,100000,500,10,True,False,True,True,2.7020226089516655,3.1.2 +CVMatrix,True,10000,100000,500,10,True,False,True,True,10.588881150993984,3.1.2 +CVMatrix,True,100000,100000,500,10,True,False,True,True,97.88805527199293,3.1.2 +CVMatrix,True,3,100000,500,10,True,False,True,False,1.9904241299955174,3.1.2 +CVMatrix,True,5,100000,500,10,True,False,True,False,1.9963804120197892,3.1.2 +CVMatrix,True,10,100000,500,10,True,False,True,False,2.0168173640267923,3.1.2 +CVMatrix,True,100,100000,500,10,True,False,True,False,1.9618249780032784,3.1.2 +CVMatrix,True,1000,100000,500,10,True,False,True,False,2.6584641320514493,3.1.2 +CVMatrix,True,10000,100000,500,10,True,False,True,False,10.064942481054459,3.1.2 +CVMatrix,True,100000,100000,500,10,True,False,True,False,96.15522754698759,3.1.2 +CVMatrix,True,3,100000,500,10,True,False,False,True,1.893277476017829,3.1.2 +CVMatrix,True,5,100000,500,10,True,False,False,True,1.9007876650430262,3.1.2 +CVMatrix,True,10,100000,500,10,True,False,False,True,1.9073550690081902,3.1.2 +CVMatrix,True,100,100000,500,10,True,False,False,True,1.8717375870328397,3.1.2 +CVMatrix,True,1000,100000,500,10,True,False,False,True,2.3017041080165654,3.1.2 +CVMatrix,True,10000,100000,500,10,True,False,False,True,7.046903911978006,3.1.2 +CVMatrix,True,100000,100000,500,10,True,False,False,True,65.85458980698604,3.1.2 +CVMatrix,True,3,100000,500,10,True,False,False,False,1.8796638959902339,3.1.2 +CVMatrix,True,5,100000,500,10,True,False,False,False,1.888564449036494,3.1.2 +CVMatrix,True,10,100000,500,10,True,False,False,False,1.8975845539825968,3.1.2 +CVMatrix,True,100,100000,500,10,True,False,False,False,1.8584078709827736,3.1.2 +CVMatrix,True,1000,100000,500,10,True,False,False,False,2.2896918160258792,3.1.2 +CVMatrix,True,10000,100000,500,10,True,False,False,False,6.9467962449998595,3.1.2 +CVMatrix,True,100000,100000,500,10,True,False,False,False,64.19237864797469,3.1.2 +CVMatrix,True,3,100000,500,10,False,True,True,True,2.0172123850206845,3.1.2 +CVMatrix,True,5,100000,500,10,False,True,True,True,2.0274247500346974,3.1.2 +CVMatrix,True,10,100000,500,10,False,True,True,True,2.043387685029302,3.1.2 +CVMatrix,True,100,100000,500,10,False,True,True,True,1.9616288489778526,3.1.2 +CVMatrix,True,1000,100000,500,10,False,True,True,True,2.4196650039521046,3.1.2 +CVMatrix,True,10000,100000,500,10,False,True,True,True,7.325938726018649,3.1.2 +CVMatrix,True,100000,100000,500,10,False,True,True,True,67.4904927710304,3.1.2 +CVMatrix,True,3,100000,500,10,False,True,True,False,2.0081770819961093,3.1.2 +CVMatrix,True,5,100000,500,10,False,True,True,False,2.017824358015787,3.1.2 +CVMatrix,True,10,100000,500,10,False,True,True,False,2.038971511996351,3.1.2 +CVMatrix,True,100,100000,500,10,False,True,True,False,1.9466590040246956,3.1.2 +CVMatrix,True,1000,100000,500,10,False,True,True,False,2.388793147983961,3.1.2 +CVMatrix,True,10000,100000,500,10,False,True,True,False,7.244912572961766,3.1.2 +CVMatrix,True,100000,100000,500,10,False,True,True,False,65.45056431303965,3.1.2 +CVMatrix,True,3,100000,500,10,False,True,False,True,1.8663307260139845,3.1.2 +CVMatrix,True,5,100000,500,10,False,True,False,True,1.8724938009981997,3.1.2 +CVMatrix,True,10,100000,500,10,False,True,False,True,1.8761495150392875,3.1.2 +CVMatrix,True,100,100000,500,10,False,True,False,True,1.8221882159705274,3.1.2 +CVMatrix,True,1000,100000,500,10,False,True,False,True,1.9893430410302244,3.1.2 +CVMatrix,True,10000,100000,500,10,False,True,False,True,4.0838878019712865,3.1.2 +CVMatrix,True,100000,100000,500,10,False,True,False,True,34.84725921304198,3.1.2 +CVMatrix,True,3,100000,500,10,False,True,False,False,1.8596344610559754,3.1.2 +CVMatrix,True,5,100000,500,10,False,True,False,False,1.8675400780048221,3.1.2 +CVMatrix,True,10,100000,500,10,False,True,False,False,1.86872684804257,3.1.2 +CVMatrix,True,100,100000,500,10,False,True,False,False,1.7929440249572508,3.1.2 +CVMatrix,True,1000,100000,500,10,False,True,False,False,1.9514500600052997,3.1.2 +CVMatrix,True,10000,100000,500,10,False,True,False,False,3.9068712599691935,3.1.2 +CVMatrix,True,100000,100000,500,10,False,True,False,False,33.09635844203876,3.1.2 +CVMatrix,True,3,100000,500,10,False,False,True,True,2.0005321159842424,3.1.2 +CVMatrix,True,5,100000,500,10,False,False,True,True,2.004382062004879,3.1.2 +CVMatrix,True,10,100000,500,10,False,False,True,True,2.019039334030822,3.1.2 +CVMatrix,True,100,100000,500,10,False,False,True,True,1.9341456539696082,3.1.2 +CVMatrix,True,1000,100000,500,10,False,False,True,True,2.3803899489575997,3.1.2 +CVMatrix,True,10000,100000,500,10,False,False,True,True,7.2361443800036795,3.1.2 +CVMatrix,True,100000,100000,500,10,False,False,True,True,65.62882983498275,3.1.2 +CVMatrix,True,3,100000,500,10,False,False,True,False,1.9825511670205742,3.1.2 +CVMatrix,True,5,100000,500,10,False,False,True,False,1.9831450549536385,3.1.2 +CVMatrix,True,10,100000,500,10,False,False,True,False,2.0022322680451907,3.1.2 +CVMatrix,True,100,100000,500,10,False,False,True,False,1.9140952400048263,3.1.2 +CVMatrix,True,1000,100000,500,10,False,False,True,False,2.3420013989671133,3.1.2 +CVMatrix,True,10000,100000,500,10,False,False,True,False,7.000652107002679,3.1.2 +CVMatrix,True,100000,100000,500,10,False,False,True,False,63.63822188001359,3.1.2 +CVMatrix,True,3,100000,500,10,False,False,False,True,1.8365034110029228,3.1.2 +CVMatrix,True,5,100000,500,10,False,False,False,True,1.8420435070293024,3.1.2 +CVMatrix,True,10,100000,500,10,False,False,False,True,1.8439627279876731,3.1.2 +CVMatrix,True,100,100000,500,10,False,False,False,True,1.778978560003452,3.1.2 +CVMatrix,True,1000,100000,500,10,False,False,False,True,1.9684552230173722,3.1.2 +CVMatrix,True,10000,100000,500,10,False,False,False,True,3.770185924018733,3.1.2 +CVMatrix,True,100000,100000,500,10,False,False,False,True,33.78727348102257,3.1.2 +CVMatrix,True,3,100000,500,10,False,False,False,False,1.8392871209653094,3.1.2 +NaiveCVMatrix,True,3,100000,500,10,False,False,False,False,1.8614093359792605,3.1.2 +CVMatrix,True,5,100000,500,10,False,False,False,False,1.8229632530128583,3.1.2 +NaiveCVMatrix,True,5,100000,500,10,False,False,False,False,3.6891562480013818,3.1.2 +CVMatrix,True,10,100000,500,10,False,False,False,False,1.8274640979943797,3.1.2 +NaiveCVMatrix,True,10,100000,500,10,False,False,False,False,8.244838489044923,3.1.2 +CVMatrix,True,100,100000,500,10,False,False,False,False,1.758714469964616,3.1.2 +NaiveCVMatrix,True,100,100000,500,10,False,False,False,False,89.59703296300722,3.1.2 +CVMatrix,True,1000,100000,500,10,False,False,False,False,1.9054143269895576,3.1.2 +NaiveCVMatrix,True,1000,100000,500,10,False,False,False,False,901.6295390359592,3.1.2 +CVMatrix,True,10000,100000,500,10,False,False,False,False,3.409175298991613,3.1.2 +NaiveCVMatrix,True,10000,100000,500,10,False,False,False,False,9001.239257315989,3.1.2 +CVMatrix,True,100000,100000,500,10,False,False,False,False,31.26620070001809,3.1.2 +NaiveCVMatrix,True,100000,100000,500,10,False,False,False,False,91358.00990715699,3.1.2 +CVMatrix,False,3,100000,500,10,True,True,True,True,2.034291260992177,3.1.2 +NaiveCVMatrix,False,3,100000,500,10,True,True,True,True,2.3922783290036023,3.1.2 +CVMatrix,False,5,100000,500,10,True,True,True,True,2.0007808249793015,3.1.2 +NaiveCVMatrix,False,5,100000,500,10,True,True,True,True,4.754343311011326,3.1.2 +CVMatrix,False,10,100000,500,10,True,True,True,True,2.023401284997817,3.1.2 +NaiveCVMatrix,False,10,100000,500,10,True,True,True,True,10.633911692013498,3.1.2 +CVMatrix,False,100,100000,500,10,True,True,True,True,1.9663792649516836,3.1.2 +NaiveCVMatrix,False,100,100000,500,10,True,True,True,True,116.16608670901041,3.1.2 +CVMatrix,False,1000,100000,500,10,True,True,True,True,2.6782585170003586,3.1.2 +NaiveCVMatrix,False,1000,100000,500,10,True,True,True,True,1166.5175434830016,3.1.2 +CVMatrix,False,10000,100000,500,10,True,True,True,True,10.234425690025091,3.1.2 +NaiveCVMatrix,False,10000,100000,500,10,True,True,True,True,11639.73957652098,3.1.2 +CVMatrix,False,100000,100000,500,10,True,True,True,True,97.09211129194591,3.1.2 +NaiveCVMatrix,False,100000,100000,500,10,True,True,True,True,117549.17203807004,3.1.2 +CVMatrix,False,3,100000,500,10,True,True,True,False,1.989648396964185,3.1.2 +CVMatrix,False,5,100000,500,10,True,True,True,False,1.9888193310471252,3.1.2 +CVMatrix,False,10,100000,500,10,True,True,True,False,2.0101286600111052,3.1.2 +CVMatrix,False,100,100000,500,10,True,True,True,False,1.955858564004302,3.1.2 +CVMatrix,False,1000,100000,500,10,True,True,True,False,2.6559186059748754,3.1.2 +CVMatrix,False,10000,100000,500,10,True,True,True,False,10.178072172100656,3.1.2 +CVMatrix,False,100000,100000,500,10,True,True,True,False,95.63062967301812,3.1.2 +CVMatrix,False,3,100000,500,10,True,True,False,True,1.8668326110346243,3.1.2 +CVMatrix,False,5,100000,500,10,True,True,False,True,1.874564933939837,3.1.2 +CVMatrix,False,10,100000,500,10,True,True,False,True,1.8787338759284467,3.1.2 +CVMatrix,False,100,100000,500,10,True,True,False,True,1.8407839860301465,3.1.2 +CVMatrix,False,1000,100000,500,10,True,True,False,True,2.278446708107367,3.1.2 +CVMatrix,False,10000,100000,500,10,True,True,False,True,7.0909933460643515,3.1.2 +CVMatrix,False,100000,100000,500,10,True,True,False,True,65.29609195003286,3.1.2 +CVMatrix,False,3,100000,500,10,True,True,False,False,1.8607327690115198,3.1.2 +NaiveCVMatrix,False,3,100000,500,10,True,True,False,False,2.0708270779578015,3.1.2 +CVMatrix,False,5,100000,500,10,True,True,False,False,1.865100613096729,3.1.2 +NaiveCVMatrix,False,5,100000,500,10,True,True,False,False,4.10796340694651,3.1.2 +CVMatrix,False,10,100000,500,10,True,True,False,False,1.875420168042183,3.1.2 +NaiveCVMatrix,False,10,100000,500,10,True,True,False,False,9.184276239015162,3.1.2 +CVMatrix,False,100,100000,500,10,True,True,False,False,1.8323370669968426,3.1.2 +NaiveCVMatrix,False,100,100000,500,10,True,True,False,False,100.16243708797265,3.1.2 +CVMatrix,False,1000,100000,500,10,True,True,False,False,2.2622019361006096,3.1.2 +NaiveCVMatrix,False,1000,100000,500,10,True,True,False,False,1008.8384319560137,3.1.2 +CVMatrix,False,10000,100000,500,10,True,True,False,False,6.879046739079058,3.1.2 +NaiveCVMatrix,False,10000,100000,500,10,True,True,False,False,10082.962717239046,3.1.2 +CVMatrix,False,100000,100000,500,10,True,True,False,False,63.4832807140192,3.1.2 +NaiveCVMatrix,False,100000,100000,500,10,True,True,False,False,101787.87960566801,3.1.2 +CVMatrix,False,3,100000,500,10,True,False,True,True,1.9959409980801865,3.1.2 +CVMatrix,False,5,100000,500,10,True,False,True,True,2.005585574079305,3.1.2 +CVMatrix,False,10,100000,500,10,True,False,True,True,2.025371566065587,3.1.2 +CVMatrix,False,100,100000,500,10,True,False,True,True,1.965202496969141,3.1.2 +CVMatrix,False,1000,100000,500,10,True,False,True,True,2.6782691329717636,3.1.2 +CVMatrix,False,10000,100000,500,10,True,False,True,True,10.276601496967487,3.1.2 +CVMatrix,False,100000,100000,500,10,True,False,True,True,97.20974447694607,3.1.2 +CVMatrix,False,3,100000,500,10,True,False,True,False,1.9936210400192067,3.1.2 +CVMatrix,False,5,100000,500,10,True,False,True,False,2.0063806009711698,3.1.2 +CVMatrix,False,10,100000,500,10,True,False,True,False,2.0131727680563927,3.1.2 +CVMatrix,False,100,100000,500,10,True,False,True,False,1.9558848090237007,3.1.2 +CVMatrix,False,1000,100000,500,10,True,False,True,False,2.66691228793934,3.1.2 +CVMatrix,False,10000,100000,500,10,True,False,True,False,10.278925959952176,3.1.2 +CVMatrix,False,100000,100000,500,10,True,False,True,False,95.35915566701442,3.1.2 +CVMatrix,False,3,100000,500,10,True,False,False,True,1.8701620240462944,3.1.2 +CVMatrix,False,5,100000,500,10,True,False,False,True,1.8752742019714788,3.1.2 +CVMatrix,False,10,100000,500,10,True,False,False,True,1.8875069540226832,3.1.2 +CVMatrix,False,100,100000,500,10,True,False,False,True,1.8479511609766632,3.1.2 +CVMatrix,False,1000,100000,500,10,True,False,False,True,2.2901278500212356,3.1.2 +CVMatrix,False,10000,100000,500,10,True,False,False,True,7.146467910963111,3.1.2 +CVMatrix,False,100000,100000,500,10,True,False,False,True,65.34969825902954,3.1.2 +CVMatrix,False,3,100000,500,10,True,False,False,False,1.8654925209702924,3.1.2 +CVMatrix,False,5,100000,500,10,True,False,False,False,1.8686304850270972,3.1.2 +CVMatrix,False,10,100000,500,10,True,False,False,False,1.8761505350703374,3.1.2 +CVMatrix,False,100,100000,500,10,True,False,False,False,1.8384834351018071,3.1.2 +CVMatrix,False,1000,100000,500,10,True,False,False,False,2.263621968915686,3.1.2 +CVMatrix,False,10000,100000,500,10,True,False,False,False,6.93361745798029,3.1.2 +CVMatrix,False,100000,100000,500,10,True,False,False,False,63.50186239590403,3.1.2 +CVMatrix,False,3,100000,500,10,False,True,True,True,2.0191891490248963,3.1.2 +CVMatrix,False,5,100000,500,10,False,True,True,True,2.029355225036852,3.1.2 +CVMatrix,False,10,100000,500,10,False,True,True,True,2.0495906240539625,3.1.2 +CVMatrix,False,100,100000,500,10,False,True,True,True,1.952279514982365,3.1.2 +CVMatrix,False,1000,100000,500,10,False,True,True,True,2.402014493010938,3.1.2 +CVMatrix,False,10000,100000,500,10,False,True,True,True,7.273113304981962,3.1.2 +CVMatrix,False,100000,100000,500,10,False,True,True,True,66.23194423306268,3.1.2 +CVMatrix,False,3,100000,500,10,False,True,True,False,1.9889022349379957,3.1.2 +CVMatrix,False,5,100000,500,10,False,True,True,False,1.9955584389390424,3.1.2 +CVMatrix,False,10,100000,500,10,False,True,True,False,2.009456299012527,3.1.2 +CVMatrix,False,100,100000,500,10,False,True,True,False,1.9206904279999435,3.1.2 +CVMatrix,False,1000,100000,500,10,False,True,True,False,2.3591902510961518,3.1.2 +CVMatrix,False,10000,100000,500,10,False,True,True,False,7.152248831000179,3.1.2 +CVMatrix,False,100000,100000,500,10,False,True,True,False,64.83727667492349,3.1.2 +CVMatrix,False,3,100000,500,10,False,True,False,True,1.8642071209615096,3.1.2 +CVMatrix,False,5,100000,500,10,False,True,False,True,1.8696786060463637,3.1.2 +CVMatrix,False,10,100000,500,10,False,True,False,True,1.8767199279973283,3.1.2 +CVMatrix,False,100,100000,500,10,False,True,False,True,1.8024164760718122,3.1.2 +CVMatrix,False,1000,100000,500,10,False,True,False,True,1.9886140170274302,3.1.2 +CVMatrix,False,10000,100000,500,10,False,True,False,True,4.061778323026374,3.1.2 +CVMatrix,False,100000,100000,500,10,False,True,False,True,34.55365612602327,3.1.2 +CVMatrix,False,3,100000,500,10,False,True,False,False,1.861834149924107,3.1.2 +CVMatrix,False,5,100000,500,10,False,True,False,False,1.8671569019788876,3.1.2 +CVMatrix,False,10,100000,500,10,False,True,False,False,1.870482338941656,3.1.2 +CVMatrix,False,100,100000,500,10,False,True,False,False,1.792074027005583,3.1.2 +CVMatrix,False,1000,100000,500,10,False,True,False,False,1.96328009897843,3.1.2 +CVMatrix,False,10000,100000,500,10,False,True,False,False,3.902390431961976,3.1.2 +CVMatrix,False,100000,100000,500,10,False,True,False,False,32.91603452595882,3.1.2 +CVMatrix,False,3,100000,500,10,False,False,True,True,1.996446231030859,3.1.2 +CVMatrix,False,5,100000,500,10,False,False,True,True,2.0023212619125843,3.1.2 +CVMatrix,False,10,100000,500,10,False,False,True,True,2.022794905002229,3.1.2 +CVMatrix,False,100,100000,500,10,False,False,True,True,1.9379006010713056,3.1.2 +CVMatrix,False,1000,100000,500,10,False,False,True,True,2.375303284963593,3.1.2 +CVMatrix,False,10000,100000,500,10,False,False,True,True,7.249086086987518,3.1.2 +CVMatrix,False,100000,100000,500,10,False,False,True,True,65.29011618508957,3.1.2 +CVMatrix,False,3,100000,500,10,False,False,True,False,1.9788222559727728,3.1.2 +CVMatrix,False,5,100000,500,10,False,False,True,False,1.9821522230049595,3.1.2 +CVMatrix,False,10,100000,500,10,False,False,True,False,2.000355315976776,3.1.2 +CVMatrix,False,100,100000,500,10,False,False,True,False,1.9086465439759195,3.1.2 +CVMatrix,False,1000,100000,500,10,False,False,True,False,2.3407338060205802,3.1.2 +CVMatrix,False,10000,100000,500,10,False,False,True,False,6.991061829030514,3.1.2 +CVMatrix,False,100000,100000,500,10,False,False,True,False,63.54187911900226,3.1.2 +CVMatrix,False,3,100000,500,10,False,False,False,True,1.831602277001366,3.1.2 +CVMatrix,False,5,100000,500,10,False,False,False,True,1.8437130060046911,3.1.2 +CVMatrix,False,10,100000,500,10,False,False,False,True,1.8450647690333426,3.1.2 +CVMatrix,False,100,100000,500,10,False,False,False,True,1.7816835039993748,3.1.2 +CVMatrix,False,1000,100000,500,10,False,False,False,True,1.9584064349764958,3.1.2 +CVMatrix,False,10000,100000,500,10,False,False,False,True,3.921983759966679,3.1.2 +CVMatrix,False,100000,100000,500,10,False,False,False,True,33.24656160501763,3.1.2 +CVMatrix,False,3,100000,500,10,False,False,False,False,1.8175993909826502,3.1.2 +NaiveCVMatrix,False,3,100000,500,10,False,False,False,False,1.8584301760420203,3.1.2 +CVMatrix,False,5,100000,500,10,False,False,False,False,1.8229373840149492,3.1.2 +NaiveCVMatrix,False,5,100000,500,10,False,False,False,False,3.6857824749313295,3.1.2 +CVMatrix,False,10,100000,500,10,False,False,False,False,1.8272661580704153,3.1.2 +NaiveCVMatrix,False,10,100000,500,10,False,False,False,False,8.242961511947215,3.1.2 +CVMatrix,False,100,100000,500,10,False,False,False,False,1.7539957320550457,3.1.2 +NaiveCVMatrix,False,100,100000,500,10,False,False,False,False,89.79859544499777,3.1.2 +CVMatrix,False,1000,100000,500,10,False,False,False,False,1.9064412079751492,3.1.2 +NaiveCVMatrix,False,1000,100000,500,10,False,False,False,False,906.4757035330404,3.1.2 +CVMatrix,False,10000,100000,500,10,False,False,False,False,3.561416274984367,3.1.2 +NaiveCVMatrix,False,10000,100000,500,10,False,False,False,False,9033.89608011092,3.1.2 +CVMatrix,False,100000,100000,500,10,False,False,False,False,30.454796339967288,3.1.2 +NaiveCVMatrix,False,100000,100000,500,10,False,False,False,False,91219.7644988551,3.1.2 \ No newline at end of file diff --git a/benchmarks/benchmark_results_jax.csv b/benchmarks/benchmark_results_jax.csv new file mode 100644 index 0000000..4ca2bb8 --- /dev/null +++ b/benchmarks/benchmark_results_jax.csv @@ -0,0 +1,169 @@ +model,weights,P,N,K,M,center_X,center_Y,scale_X,scale_Y,time,version +CVMatrix,True,3,100000,500,10,False,False,False,False,1.1941567149478942,3.2.0 +CVMatrix,True,5,100000,500,10,False,False,False,False,1.2388604329898953,3.2.0 +CVMatrix,True,10,100000,500,10,False,False,False,False,1.2152469219872728,3.2.0 +CVMatrix,True,100,100000,500,10,False,False,False,False,0.8777078640414402,3.2.0 +CVMatrix,True,1000,100000,500,10,False,False,False,False,1.2294215579750016,3.2.0 +CVMatrix,True,10000,100000,500,10,False,False,False,False,1.9392532469937578,3.2.0 +CVMatrix,True,100000,100000,500,10,False,False,False,False,34.31822472799104,3.2.0 +CVMatrix,True,3,100000,500,10,True,True,False,False,1.3004615990212187,3.2.0 +CVMatrix,True,5,100000,500,10,True,True,False,False,1.2773295060032979,3.2.0 +CVMatrix,True,10,100000,500,10,True,True,False,False,1.3540909610455856,3.2.0 +CVMatrix,True,100,100000,500,10,True,True,False,False,0.9889725480461493,3.2.0 +CVMatrix,True,1000,100000,500,10,True,True,False,False,1.9933221020037308,3.2.0 +CVMatrix,True,10000,100000,500,10,True,True,False,False,6.104556004982442,3.2.0 +CVMatrix,True,100000,100000,500,10,True,True,False,False,69.0630395989865,3.2.0 +CVMatrix,True,3,100000,500,10,True,True,True,True,1.6016558419214562,3.2.0 +CVMatrix,True,5,100000,500,10,True,True,True,True,1.952684861025773,3.2.0 +CVMatrix,True,10,100000,500,10,True,True,True,True,1.9289571170229465,3.2.0 +CVMatrix,True,100,100000,500,10,True,True,True,True,1.3856251860270277,3.2.0 +CVMatrix,True,1000,100000,500,10,True,True,True,True,2.928624163963832,3.2.0 +CVMatrix,True,10000,100000,500,10,True,True,True,True,10.213626472046599,3.2.0 +CVMatrix,True,100000,100000,500,10,True,True,True,True,108.04169350804295,3.2.0 +CVMatrix,False,3,100000,500,10,False,False,False,False,0.8644924859981984,3.2.0 +CVMatrix,False,5,100000,500,10,False,False,False,False,0.8797790000680834,3.2.0 +CVMatrix,False,10,100000,500,10,False,False,False,False,0.7050728399772197,3.2.0 +CVMatrix,False,100,100000,500,10,False,False,False,False,0.514429033966735,3.2.0 +CVMatrix,False,1000,100000,500,10,False,False,False,False,0.8157944809645414,3.2.0 +CVMatrix,False,10000,100000,500,10,False,False,False,False,3.271460584946908,3.2.0 +CVMatrix,False,100000,100000,500,10,False,False,False,False,34.160362099064514,3.2.0 +CVMatrix,False,3,100000,500,10,True,True,False,False,0.7326359620783478,3.2.0 +CVMatrix,False,5,100000,500,10,True,True,False,False,0.7950215539894998,3.2.0 +CVMatrix,False,10,100000,500,10,True,True,False,False,0.7952526080189273,3.2.0 +CVMatrix,False,100,100000,500,10,True,True,False,False,0.6158564779907465,3.2.0 +CVMatrix,False,1000,100000,500,10,True,True,False,False,1.4742512800730765,3.2.0 +CVMatrix,False,10000,100000,500,10,True,True,False,False,10.907702341093682,3.2.0 +CVMatrix,False,100000,100000,500,10,True,True,False,False,69.9015849790303,3.2.0 +CVMatrix,False,3,100000,500,10,True,True,True,True,1.1621856829151511,3.2.0 +CVMatrix,False,5,100000,500,10,True,True,True,True,1.1924858170095831,3.2.0 +CVMatrix,False,10,100000,500,10,True,True,True,True,1.209067014977336,3.2.0 +CVMatrix,False,100,100000,500,10,True,True,True,True,0.8500632049981505,3.2.0 +CVMatrix,False,1000,100000,500,10,True,True,True,True,1.8347180710406974,3.2.0 +CVMatrix,False,10000,100000,500,10,True,True,True,True,14.872147740912624,3.2.0 +CVMatrix,False,100000,100000,500,10,True,True,True,True,105.06958515406586,3.2.0 +CVMatrix-jax-gpu-nojit,True,3,100000,500,10,False,False,False,False,1.632313295849599,3.2.0 +CVMatrix-jax-gpu-coldjit,True,3,100000,500,10,False,False,False,False,23.34611799486447,3.2.0 +CVMatrix-jax-gpu-warmjit,True,3,100000,500,10,False,False,False,False,0.9329864250030369,3.2.0 +CVMatrix-jax-gpu-nojit,True,5,100000,500,10,False,False,False,False,0.5289996319916099,3.2.0 +CVMatrix-jax-gpu-coldjit,True,5,100000,500,10,False,False,False,False,11.792680245125666,3.2.0 +CVMatrix-jax-gpu-warmjit,True,5,100000,500,10,False,False,False,False,0.15165713499300182,3.2.0 +CVMatrix-jax-gpu-nojit,True,10,100000,500,10,False,False,False,False,0.5324810020392761,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10,100000,500,10,False,False,False,False,11.824156131013297,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10,100000,500,10,False,False,False,False,0.15182622498832643,3.2.0 +CVMatrix-jax-gpu-nojit,True,100,100000,500,10,False,False,False,False,0.5337930739624426,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100,100000,500,10,False,False,False,False,11.681885494850576,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100,100000,500,10,False,False,False,False,0.14219606888946146,3.2.0 +CVMatrix-jax-gpu-nojit,True,1000,100000,500,10,False,False,False,False,0.539993820944801,3.2.0 +CVMatrix-jax-gpu-coldjit,True,1000,100000,500,10,False,False,False,False,11.779184759943746,3.2.0 +CVMatrix-jax-gpu-warmjit,True,1000,100000,500,10,False,False,False,False,0.16031630500219762,3.2.0 +CVMatrix-jax-gpu-nojit,True,10000,100000,500,10,False,False,False,False,0.7048436108743772,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10000,100000,500,10,False,False,False,False,11.936229861923493,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10000,100000,500,10,False,False,False,False,0.27667936484795064,3.2.0 +CVMatrix-jax-gpu-nojit,True,100000,100000,500,10,False,False,False,False,1.5053048130357638,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100000,100000,500,10,False,False,False,False,11.766612329054624,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100000,100000,500,10,False,False,False,False,0.37316381302662194,3.2.0 +CVMatrix-jax-gpu-nojit,True,3,100000,500,10,True,True,False,False,2.366172896930948,3.2.0 +CVMatrix-jax-gpu-coldjit,True,3,100000,500,10,True,True,False,False,23.621587069006637,3.2.0 +CVMatrix-jax-gpu-warmjit,True,3,100000,500,10,True,True,False,False,0.7769030149793252,3.2.0 +CVMatrix-jax-gpu-nojit,True,5,100000,500,10,True,True,False,False,1.1171795859700069,3.2.0 +CVMatrix-jax-gpu-coldjit,True,5,100000,500,10,True,True,False,False,12.005785148008727,3.2.0 +CVMatrix-jax-gpu-warmjit,True,5,100000,500,10,True,True,False,False,0.14345634903293103,3.2.0 +CVMatrix-jax-gpu-nojit,True,10,100000,500,10,True,True,False,False,1.0804275509435683,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10,100000,500,10,True,True,False,False,11.986124473973177,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10,100000,500,10,True,True,False,False,0.14493258495349437,3.2.0 +CVMatrix-jax-gpu-nojit,True,100,100000,500,10,True,True,False,False,0.93102929496672,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100,100000,500,10,True,True,False,False,11.866976546007209,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100,100000,500,10,True,True,False,False,0.14944440498948097,3.2.0 +CVMatrix-jax-gpu-nojit,True,1000,100000,500,10,True,True,False,False,0.9813496950082481,3.2.0 +CVMatrix-jax-gpu-coldjit,True,1000,100000,500,10,True,True,False,False,11.930314689991064,3.2.0 +CVMatrix-jax-gpu-warmjit,True,1000,100000,500,10,True,True,False,False,0.16065363702364266,3.2.0 +CVMatrix-jax-gpu-nojit,True,10000,100000,500,10,True,True,False,False,1.1416200449457392,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10000,100000,500,10,True,True,False,False,12.290474948938936,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10000,100000,500,10,True,True,False,False,0.282087006024085,3.2.0 +CVMatrix-jax-gpu-nojit,True,100000,100000,500,10,True,True,False,False,2.967109062941745,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100000,100000,500,10,True,True,False,False,12.140538009931333,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100000,100000,500,10,True,True,False,False,0.5534275260288268,3.2.0 +CVMatrix-jax-gpu-nojit,True,3,100000,500,10,True,True,True,True,1.4237911779200658,3.2.0 +CVMatrix-jax-gpu-coldjit,True,3,100000,500,10,True,True,True,True,34.12143419694621,3.2.0 +CVMatrix-jax-gpu-warmjit,True,3,100000,500,10,True,True,True,True,0.3091441129799932,3.2.0 +CVMatrix-jax-gpu-nojit,True,5,100000,500,10,True,True,True,True,0.8284593160497025,3.2.0 +CVMatrix-jax-gpu-coldjit,True,5,100000,500,10,True,True,True,True,17.56956055003684,3.2.0 +CVMatrix-jax-gpu-warmjit,True,5,100000,500,10,True,True,True,True,0.14575090806465596,3.2.0 +CVMatrix-jax-gpu-nojit,True,10,100000,500,10,True,True,True,True,0.8230793218826875,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10,100000,500,10,True,True,True,True,17.819756863988005,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10,100000,500,10,True,True,True,True,0.1455215640598908,3.2.0 +CVMatrix-jax-gpu-nojit,True,100,100000,500,10,True,True,True,True,0.8331331339431927,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100,100000,500,10,True,True,True,True,17.688981912913732,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100,100000,500,10,True,True,True,True,0.14719849301036447,3.2.0 +CVMatrix-jax-gpu-nojit,True,1000,100000,500,10,True,True,True,True,0.8850459699751809,3.2.0 +CVMatrix-jax-gpu-coldjit,True,1000,100000,500,10,True,True,True,True,17.638945414917544,3.2.0 +CVMatrix-jax-gpu-warmjit,True,1000,100000,500,10,True,True,True,True,0.16532829497009516,3.2.0 +CVMatrix-jax-gpu-nojit,True,10000,100000,500,10,True,True,True,True,1.3153250009054318,3.2.0 +CVMatrix-jax-gpu-coldjit,True,10000,100000,500,10,True,True,True,True,18.117243187036365,3.2.0 +CVMatrix-jax-gpu-warmjit,True,10000,100000,500,10,True,True,True,True,0.3333543869666755,3.2.0 +CVMatrix-jax-gpu-nojit,True,100000,100000,500,10,True,True,True,True,4.518371606129222,3.2.0 +CVMatrix-jax-gpu-coldjit,True,100000,100000,500,10,True,True,True,True,18.720431115012616,3.2.0 +CVMatrix-jax-gpu-warmjit,True,100000,100000,500,10,True,True,True,True,1.2993427510373294,3.2.0 +CVMatrix-jax-cpu-nojit,True,3,100000,500,10,False,False,False,False,2.0641746720066294,3.2.0 +CVMatrix-jax-cpu-coldjit,True,3,100000,500,10,False,False,False,False,11.801093348069116,3.2.0 +CVMatrix-jax-cpu-warmjit,True,3,100000,500,10,False,False,False,False,0.8850470650941133,3.2.0 +CVMatrix-jax-cpu-nojit,True,5,100000,500,10,False,False,False,False,1.5895351129584014,3.2.0 +CVMatrix-jax-cpu-coldjit,True,5,100000,500,10,False,False,False,False,6.010262299911119,3.2.0 +CVMatrix-jax-cpu-warmjit,True,5,100000,500,10,False,False,False,False,0.6328710300149396,3.2.0 +CVMatrix-jax-cpu-nojit,True,10,100000,500,10,False,False,False,False,1.5342505369335413,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10,100000,500,10,False,False,False,False,6.067426074063405,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10,100000,500,10,False,False,False,False,0.6160863609984517,3.2.0 +CVMatrix-jax-cpu-nojit,True,100,100000,500,10,False,False,False,False,1.5889573320746422,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100,100000,500,10,False,False,False,False,6.2229238480795175,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100,100000,500,10,False,False,False,False,0.6620993650285527,3.2.0 +CVMatrix-jax-cpu-nojit,True,1000,100000,500,10,False,False,False,False,2.8438327610492706,3.2.0 +CVMatrix-jax-cpu-coldjit,True,1000,100000,500,10,False,False,False,False,6.3065667391056195,3.2.0 +CVMatrix-jax-cpu-warmjit,True,1000,100000,500,10,False,False,False,False,1.0215598409995437,3.2.0 +CVMatrix-jax-cpu-nojit,True,10000,100000,500,10,False,False,False,False,9.625814352999441,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10000,100000,500,10,False,False,False,False,9.841091375914402,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10000,100000,500,10,False,False,False,False,4.731531122932211,3.2.0 +CVMatrix-jax-cpu-nojit,True,100000,100000,500,10,False,False,False,False,56.788117082905956,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100000,100000,500,10,False,False,False,False,31.856476944987662,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100000,100000,500,10,False,False,False,False,26.553785535972565,3.2.0 +CVMatrix-jax-cpu-nojit,True,3,100000,500,10,True,True,False,False,2.1291528119472787,3.2.0 +CVMatrix-jax-cpu-coldjit,True,3,100000,500,10,True,True,False,False,11.624330532969907,3.2.0 +CVMatrix-jax-cpu-warmjit,True,3,100000,500,10,True,True,False,False,0.8000447900267318,3.2.0 +CVMatrix-jax-cpu-nojit,True,5,100000,500,10,True,True,False,False,1.6868692770367488,3.2.0 +CVMatrix-jax-cpu-coldjit,True,5,100000,500,10,True,True,False,False,6.064092201995663,3.2.0 +CVMatrix-jax-cpu-warmjit,True,5,100000,500,10,True,True,False,False,0.6561844360549003,3.2.0 +CVMatrix-jax-cpu-nojit,True,10,100000,500,10,True,True,False,False,1.7295897040748969,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10,100000,500,10,True,True,False,False,6.04276000300888,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10,100000,500,10,True,True,False,False,0.6275438821176067,3.2.0 +CVMatrix-jax-cpu-nojit,True,100,100000,500,10,True,True,False,False,1.7782964339712635,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100,100000,500,10,True,True,False,False,6.049204112030566,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100,100000,500,10,True,True,False,False,0.6719458089210093,3.2.0 +CVMatrix-jax-cpu-nojit,True,1000,100000,500,10,True,True,False,False,3.6490812728879973,3.2.0 +CVMatrix-jax-cpu-coldjit,True,1000,100000,500,10,True,True,False,False,6.275046626920812,3.2.0 +CVMatrix-jax-cpu-warmjit,True,1000,100000,500,10,True,True,False,False,0.918339499970898,3.2.0 +CVMatrix-jax-cpu-nojit,True,10000,100000,500,10,True,True,False,False,18.705401667044498,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10000,100000,500,10,True,True,False,False,9.688336852006614,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10000,100000,500,10,True,True,False,False,4.674701331998222,3.2.0 +CVMatrix-jax-cpu-nojit,True,100000,100000,500,10,True,True,False,False,143.26303969405126,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100000,100000,500,10,True,True,False,False,30.803388206055388,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100000,100000,500,10,True,True,False,False,25.407287453999743,3.2.0 +CVMatrix-jax-cpu-nojit,True,3,100000,500,10,True,True,True,True,2.5567956919549033,3.2.0 +CVMatrix-jax-cpu-coldjit,True,3,100000,500,10,True,True,True,True,17.105665273033082,3.2.0 +CVMatrix-jax-cpu-warmjit,True,3,100000,500,10,True,True,True,True,0.786845215014182,3.2.0 +CVMatrix-jax-cpu-nojit,True,5,100000,500,10,True,True,True,True,2.0708149360725656,3.2.0 +CVMatrix-jax-cpu-coldjit,True,5,100000,500,10,True,True,True,True,8.711395109072328,3.2.0 +CVMatrix-jax-cpu-warmjit,True,5,100000,500,10,True,True,True,True,0.6519641680642962,3.2.0 +CVMatrix-jax-cpu-nojit,True,10,100000,500,10,True,True,True,True,1.9614091481780633,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10,100000,500,10,True,True,True,True,8.78678807709366,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10,100000,500,10,True,True,True,True,0.6999291750835255,3.2.0 +CVMatrix-jax-cpu-nojit,True,100,100000,500,10,True,True,True,True,2.295204345951788,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100,100000,500,10,True,True,True,True,8.709234067006037,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100,100000,500,10,True,True,True,True,0.7009000619873405,3.2.0 +CVMatrix-jax-cpu-nojit,True,1000,100000,500,10,True,True,True,True,4.529199573909864,3.2.0 +CVMatrix-jax-cpu-coldjit,True,1000,100000,500,10,True,True,True,True,9.04653775296174,3.2.0 +CVMatrix-jax-cpu-warmjit,True,1000,100000,500,10,True,True,True,True,1.0235839679371566,3.2.0 +CVMatrix-jax-cpu-nojit,True,10000,100000,500,10,True,True,True,True,24.003119080909528,3.2.0 +CVMatrix-jax-cpu-coldjit,True,10000,100000,500,10,True,True,True,True,12.497502946993336,3.2.0 +CVMatrix-jax-cpu-warmjit,True,10000,100000,500,10,True,True,True,True,4.75980460701976,3.2.0 +CVMatrix-jax-cpu-nojit,True,100000,100000,500,10,True,True,True,True,197.2365424539894,3.2.0 +CVMatrix-jax-cpu-coldjit,True,100000,100000,500,10,True,True,True,True,33.92279968911316,3.2.0 +CVMatrix-jax-cpu-warmjit,True,100000,100000,500,10,True,True,True,True,25.930547127034515,3.2.0 diff --git a/benchmarks/plot_benchmark.py b/benchmarks/plot_benchmark.py index 2f075da..27f5f5b 100644 --- a/benchmarks/plot_benchmark.py +++ b/benchmarks/plot_benchmark.py @@ -11,6 +11,7 @@ E-mail: ole.e@di.ku.dk """ +import os from itertools import product import matplotlib.pyplot as plt @@ -20,23 +21,28 @@ from matplotlib.text import Text -def plot_cvmatrix_vs_naive(df, combination_to_color_map): +def plot_cvmatrix_vs_naive(df, combination_to_color_map, weights): + # Set text and label sizes to 20 + plt.rcParams.update({'font.size': 15, 'axes.labelsize': 15, 'axes.titlesize': 20, 'legend.fontsize': 15}) fig, ax = plt.subplots(figsize=(10, 10)) preprocessing_combinations = [] preprocessing_combinations.append( - {'center_X': False, 'center_Y': False, 'scale_X': False, 'scale_Y': False} + {'center_X': False, 'center_Y': False, 'scale_X': False, 'scale_Y': False, 'weights': weights} ) preprocessing_combinations.append( - {'center_X': True, 'center_Y': True, 'scale_X': False, 'scale_Y': False} + {'center_X': True, 'center_Y': True, 'scale_X': False, 'scale_Y': False, 'weights': weights} ) preprocessing_combinations.append( - {'center_X': True, 'center_Y': True, 'scale_X': True, 'scale_Y': True} + {'center_X': True, 'center_Y': True, 'scale_X': True, 'scale_Y': True, 'weights': weights} ) N = df['N'].unique()[0] K = df['K'].unique()[0] M = df['M'].unique()[0] for combination in preprocessing_combinations: - color = combination_to_color_map[str(combination)] + # Do not use the 'weights' key in combination when getting color + combination_no_weights = {k: v for k, v in combination.items() if k != 'weights'} + color = combination_to_color_map[str(combination_no_weights)] + fast_times = [] naive_times = [] Ps = [] @@ -47,7 +53,8 @@ def plot_cvmatrix_vs_naive(df, combination_to_color_map): (df['center_X'] == combination['center_X']) & (df['center_Y'] == combination['center_Y']) & (df['scale_X'] == combination['scale_X']) & - (df['scale_Y'] == combination['scale_Y']) + (df['scale_Y'] == combination['scale_Y']) & + (df['weights'] == combination['weights']) ]['time'].values[0] naive_time = df[ (df['model'] == 'NaiveCVMatrix') & @@ -55,29 +62,42 @@ def plot_cvmatrix_vs_naive(df, combination_to_color_map): (df['center_X'] == combination['center_X']) & (df['center_Y'] == combination['center_Y']) & (df['scale_X'] == combination['scale_X']) & - (df['scale_Y'] == combination['scale_Y']) + (df['scale_Y'] == combination['scale_Y']) & + (df['weights'] == combination['weights']) ]['time'].values[0] fast_times.append(fast_time) naive_times.append(naive_time) Ps.append(P) - label = "Fast (CVMatrix), " + ', '.join([f"{k}={v}" for k, v in combination.items()]) + # label = "Baseline, " + ', '.join( + # [f"{k}={v}" for k, v in combination.items() if k != 'weights'] + # ) + if combination['scale_X']: + label = "Algorithm 6" + elif combination['center_X']: + label = "Algorithm 4" + else: + label = "Algorithm 2" ax.plot( Ps, - fast_times, - marker='D', + naive_times, + marker='s', color=color, - linestyle='dashed', + linestyle='dotted', label=label ) - label = "Baseline, " + ', '.join( - [f"{k}={v}" for k, v in combination.items()] - ) + # label = "Fast (CVMatrix), " + ', '.join([f"{k}={v}" for k, v in combination.items() if k != 'weights']) + if combination['scale_X']: + label = "Algorithm 7" + elif combination['center_X']: + label = "Algorithm 5" + else: + label = "Algorithm 3" ax.plot( Ps, - naive_times, - marker='s', + fast_times, + marker='D', color=color, - linestyle='dotted', + linestyle='dashed', label=label ) lines = [1, 60, 3600, 86400] @@ -85,11 +105,11 @@ def plot_cvmatrix_vs_naive(df, combination_to_color_map): for j, line in enumerate(lines): ax.axhline(y=line, color='k', linestyle='--', linewidth=1) ax.text( - 310000, line, f"1 {line_names[j]}", fontsize=10, ha='center', va='center' + 310000, line, f"1 {line_names[j]}", fontsize=12, ha='center', va='center' ) cvmatrix_version = df['version'].unique()[0] - version_text = f'CVMatrix version: {cvmatrix_version}' - ax.text(1, 330000, version_text, fontsize=9, ha='center', va='center') + version_text = f'cvmatrix version: {cvmatrix_version}' + ax.text(1, 330000, version_text, fontsize=10, ha='center', va='center') ax.set_xscale('log') ax.set_yscale('log') current_x_ticks, current_x_labels = plt.xticks() @@ -106,16 +126,20 @@ def plot_cvmatrix_vs_naive(df, combination_to_color_map): new_x_labels = new_x_labels[start_idx:stop_idx] ax.set_xticks(new_x_ticks) ax.set_xticklabels(new_x_labels) - ax.set_title(f'Fast (CVMatrix) vs. Baseline Cross-Validation\n(N={N:,}, K={K}, M={M})', fontsize=10) + ax.set_title(f'Fast (cvmatrix) vs. Baseline Weighted Cross-Validation\n(N={N:,}, K={K}, M={M})', fontsize=20) ax.set_xlabel('P (cross-validation folds)') ax.set_ylabel('Time (s)') - fig.set_size_inches(8.27, 0.37 * 11.7) - ax.legend(loc='upper left', fontsize='xx-small') - plt.tight_layout() - plt.savefig('benchmark_cvmatrix_vs_naive.png') + # fig.set_size_inches(8.27, 0.37 * 11.7) + ax.legend(loc='upper left')#, fontsize='xx-small') + # plt.tight_layout() + if weights: + plt.savefig('benchmark_cvmatrix_vs_naive_weights.png') + plt.savefig('benchmark_cvmatrix_vs_naive_weights.eps') + else: + plt.savefig('benchmark_cvmatrix_vs_naive_no_weights.png') plt.clf() -def plot_cvmatrix(df, combination_to_color_map): +def plot_cvmatrix(df, combination_to_color_map, weights): fig, ax = plt.subplots(figsize=(10, 10)) preprocessing_combinations = [] center_Xs = [False, True] @@ -129,14 +153,16 @@ def plot_cvmatrix(df, combination_to_color_map): 'center_X': center_X, 'center_Y': center_Y, 'scale_X': scale_X, - 'scale_Y': scale_Y + 'scale_Y': scale_Y, + 'weights': weights } ) N = df['N'].unique()[0] K = df['K'].unique()[0] M = df['M'].unique()[0] for combination in preprocessing_combinations: - color = combination_to_color_map[str(combination)] + combination_no_weights = {k: v for k, v in combination.items() if k != 'weights'} + color = combination_to_color_map[str(combination_no_weights)] fast_times = [] Ps = [] for P in df['P'].unique(): @@ -146,11 +172,12 @@ def plot_cvmatrix(df, combination_to_color_map): (df['center_X'] == combination['center_X']) & (df['center_Y'] == combination['center_Y']) & (df['scale_X'] == combination['scale_X']) & - (df['scale_Y'] == combination['scale_Y']) + (df['scale_Y'] == combination['scale_Y']) & + (df['weights'] == combination['weights']) ]['time'].values[0] fast_times.append(fast_time) Ps.append(P) - label = ', '.join([f"{k}={v}" for k, v in combination.items()]) + label = ', '.join([f"{k}={v}" for k, v in combination.items() if k != 'weights']) ax.plot( Ps, fast_times, @@ -164,11 +191,11 @@ def plot_cvmatrix(df, combination_to_color_map): for j, line in enumerate(lines): ax.axhline(y=line, color='k', linestyle='--', linewidth=1) ax.text( - 310000,line, f"1 {line_names[j]}", fontsize=10, ha='center', va='center' + 310000,line, f"1 {line_names[j]}", fontsize=20, ha='center', va='center' ) cvmatrix_version = df['version'].unique()[0] version_text = f'CVMatrix version: {cvmatrix_version}' - ax.text(1, 330000, version_text, fontsize=9, ha='center', va='center') + ax.text(1, 330000, version_text, fontsize=20, ha='center', va='center') ax.set_xscale('log') ax.set_yscale('log') current_x_ticks, current_x_labels = plt.xticks() @@ -191,9 +218,155 @@ def plot_cvmatrix(df, combination_to_color_map): fig.set_size_inches(8.27, 0.37 * 11.7) ax.legend(loc='upper left', fontsize='xx-small') plt.tight_layout() - plt.savefig('benchmark_cvmatrix.png') + if weights: + plt.savefig('benchmark_cvmatrix_weights.png') + else: + plt.savefig('benchmark_cvmatrix_no_weights.png') + plt.clf() + +def _add_time_reflines(ax, ymax): + """Draw "1 Second/Minute/Hour/Day" reference lines up to (a little above) ymax.""" + from matplotlib.text import Text # noqa: F401 (kept for parity with other plots) + for y, name in [(1, 'Second'), (60, 'Minute'), (3600, 'Hour'), (86400, 'Day')]: + if y <= ymax * 2: + ax.axhline(y=y, color='k', linestyle='--', linewidth=1) + ax.text(310000, y, f'1 {name}', fontsize=11, ha='center', va='center') + + +_COMBOS = [ + ((False, False, False, False), 'solid', 'no preprocessing'), + ((True, True, False, False), 'dashed', 'centering'), + ((True, True, True, True), 'dotted', 'centering + scaling'), +] + + +def _combo_dict(key): + return dict(zip(('center_X', 'center_Y', 'scale_X', 'scale_Y'), key)) + + +def _series_times(df, model, key, Ps_all): + """Per-P times (weighted) for a given model and (center_X, center_Y, scale_X, + scale_Y) combination; returns (Ps, times) over the P values that have a row.""" + cX, cY, sX, sY = key + times, Ps = [], [] + for P in Ps_all: + sel = df[ + (df['model'] == model) & (df['P'] == P) & (df['weights'] == True) + & (df['center_X'] == cX) & (df['center_Y'] == cY) + & (df['scale_X'] == sX) & (df['scale_Y'] == sY) + ]['time'].values + if len(sel): + times.append(sel[0]) + Ps.append(P) + return Ps, times + + +def plot_numpy_vs_jax(df, combination_to_color_map): + """ + benchmark_cvmatrix_numpy_vs_jax.png: total weighted cross-validation time for the + CVMatrix NumPy backend vs. the JAX backend (warm, JIT-compiled jax.vmap over folds) on + CPU and GPU, across the three preprocessing combinations. All measured multi-threaded + (no thread limit) at cvmatrix 3.2.0. Color encodes preprocessing; line style encodes + backend. + """ + from matplotlib.lines import Line2D + plt.rcParams.update({'font.size': 15, 'axes.labelsize': 15, + 'axes.titlesize': 18, 'legend.fontsize': 11}) + fig, ax = plt.subplots(figsize=(10, 10)) + # (model, linestyle, marker, legend label) + series = [ + ('CVMatrix', 'dashed', 'D', 'NumPy'), + ('CVMatrix-jax-cpu-warmjit', 'dashdot', '^', 'JAX warm (CPU)'), + ('CVMatrix-jax-gpu-warmjit', 'solid', 'o', 'JAX warm (GPU)'), + ] + N = df['N'].unique()[0] + K = df['K'].unique()[0] + M = df['M'].unique()[0] + Ps_all = sorted(df['P'].unique()) + ymax = 0.0 + for key, _ls, combo_lab in _COMBOS: + color = combination_to_color_map[str(_combo_dict(key))] + for model, linestyle, marker, _lab in series: + Ps, times = _series_times(df, model, key, Ps_all) + if times: + ax.plot(Ps, times, marker=marker, color=color, linestyle=linestyle) + ymax = max(ymax, max(times)) + _add_time_reflines(ax, ymax) + ax.set_xscale('log') + ax.set_yscale('log') + ax.set_title('CVMatrix NumPy vs. JAX (warm) Weighted Cross-Validation\n' + f'(N={N:,}, K={K}, M={M})', fontsize=18) + ax.set_xlabel('P (cross-validation folds)') + ax.set_ylabel('Time (s)') + backend_handles = [Line2D([0], [0], color='gray', linestyle=ls, marker=mk, label=lab) + for _m, ls, mk, lab in series] + combo_handles = [Line2D([0], [0], color=combination_to_color_map[str(_combo_dict(k))], + lw=3, label=lab) for k, _ls, lab in _COMBOS] + leg1 = ax.legend(handles=backend_handles, loc='upper left', title='Backend') + ax.add_artist(leg1) + ax.legend(handles=combo_handles, loc='lower right', title='Preprocessing') + fig.text(0.5, 0.01, 'cvmatrix 3.2.0; multi-threaded CPU; GPU: RTX 3090 Ti', + ha='center', va='bottom', fontsize=9, alpha=0.7) + plt.tight_layout(rect=(0, 0.03, 1, 1)) + plt.savefig('benchmark_cvmatrix_numpy_vs_jax.png') plt.clf() + +def plot_jax_variants(df): + """ + benchmark_jax_variants.png: total weighted cross-validation time for the CVMatrix JAX + backend under no-JIT (eager vmap), cold-JIT (compilation + run) and warm-JIT (run + only), on CPU and GPU, across the three preprocessing combinations. Multi-threaded + CPU, cvmatrix 3.2.0. Color encodes the JAX mode/device; line style encodes + preprocessing. + """ + from matplotlib.lines import Line2D + plt.rcParams.update({'font.size': 15, 'axes.labelsize': 15, + 'axes.titlesize': 18, 'legend.fontsize': 10}) + fig, ax = plt.subplots(figsize=(10, 10)) + variants = [ + ('CVMatrix-jax-gpu-nojit', 'GPU, no-JIT'), + ('CVMatrix-jax-gpu-coldjit', 'GPU, cold-JIT'), + ('CVMatrix-jax-gpu-warmjit', 'GPU, warm-JIT'), + ('CVMatrix-jax-cpu-nojit', 'CPU, no-JIT'), + ('CVMatrix-jax-cpu-coldjit', 'CPU, cold-JIT'), + ('CVMatrix-jax-cpu-warmjit', 'CPU, warm-JIT'), + ] + cm = colormaps.get_cmap('tab10') + variant_colors = {m: cm(i) for i, (m, _lab) in enumerate(variants)} + N = df['N'].unique()[0] + K = df['K'].unique()[0] + M = df['M'].unique()[0] + Ps_all = sorted(df['P'].unique()) + ymax = 0.0 + for key, linestyle, _combo_lab in _COMBOS: + for model, _lab in variants: + Ps, times = _series_times(df, model, key, Ps_all) + if times: + ax.plot(Ps, times, color=variant_colors[model], linestyle=linestyle, + linewidth=1.8) + ymax = max(ymax, max(times)) + _add_time_reflines(ax, ymax) + ax.set_xscale('log') + ax.set_yscale('log') + ax.set_title('CVMatrix JAX backend: execution-mode comparison\n' + f'(weighted, N={N:,}, K={K}, M={M})', fontsize=18) + ax.set_xlabel('P (cross-validation folds)') + ax.set_ylabel('Time (s)') + variant_handles = [Line2D([0], [0], color=variant_colors[m], lw=2.5, label=lab) + for m, lab in variants] + combo_handles = [Line2D([0], [0], color='gray', linestyle=ls, label=lab) + for _k, ls, lab in _COMBOS] + leg1 = ax.legend(handles=variant_handles, loc='upper left', title='JAX mode / device') + ax.add_artist(leg1) + ax.legend(handles=combo_handles, loc='lower right', title='Preprocessing') + fig.text(0.5, 0.01, 'cvmatrix 3.2.0; multi-threaded CPU; GPU: RTX 3090 Ti', + ha='center', va='bottom', fontsize=9, alpha=0.7) + plt.tight_layout(rect=(0, 0.03, 1, 1)) + plt.savefig('benchmark_jax_variants.png') + plt.clf() + + def get_combination_to_color_map(): preprocessing_combinations = [] center_Xs = [False, True] @@ -223,5 +396,12 @@ def get_combination_to_color_map(): plt.rcParams.update({'font.size': 12}) df = pd.read_csv('benchmark_results.csv') combination_to_color_map = get_combination_to_color_map() - plot_cvmatrix_vs_naive(df, combination_to_color_map) - plot_cvmatrix(df, combination_to_color_map) + for weights in [True, False]: + plot_cvmatrix_vs_naive(df, combination_to_color_map, weights) + plot_cvmatrix(df, combination_to_color_map, weights) + # Multi-threaded CVMatrix NumPy-vs-JAX and JAX execution-mode figures, from the + # separate results CSV produced by the BENCH_JAX_VARIANTS / multi-threaded runs. + if os.path.exists('benchmark_results_jax.csv'): + df_jax = pd.read_csv('benchmark_results_jax.csv') + plot_numpy_vs_jax(df_jax, combination_to_color_map) + plot_jax_variants(df_jax) diff --git a/cvmatrix/__init__.py b/cvmatrix/__init__.py index 0e2a5c9..9e40323 100644 --- a/cvmatrix/__init__.py +++ b/cvmatrix/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.1.6" +__version__ = "3.2.0" __all__ = ["CVMatrix", "Partitioner"] from .cvmatrix import CVMatrix from .partitioner import Partitioner diff --git a/cvmatrix/cvmatrix.py b/cvmatrix/cvmatrix.py index 3fba937..ee0135d 100644 --- a/cvmatrix/cvmatrix.py +++ b/cvmatrix/cvmatrix.py @@ -10,11 +10,84 @@ E-mail: ocge@foss.dk """ -from typing import Optional, Tuple, Union +from typing import TYPE_CHECKING, Literal, Optional, Tuple, Union import numpy as np from numpy import typing as npt +try: + # Broaden the array/scalar type hints so that, with backend="jax", jax.numpy values + # (which are jax.Array instances, including under jit/vmap tracing) satisfy runtime + # type checking. numpy remains the only required dependency; this is skipped if jax + # is not installed, leaving the hints numpy-only. + import jax as _jax + + Array = Union[np.ndarray, _jax.Array] + Scalar = Union[np.floating, _jax.Array, float, int] + # float dtype types accepted by `dtype`: numpy float types (`type[np.floating]`) and + # JAX scalar dtypes. The latter (e.g. jnp.float64/float32/bfloat16) are instances of + # JAX's scalar-type metaclass -- NOT numpy.floating subclasses -- so they must be + # admitted via that metaclass. + _JaxScalarMeta = type(_jax.numpy.float64) + FloatDType = Union[type[np.floating], _JaxScalarMeta] + # Abstract values produced while a function is traced by jax.jit/jax.vmap. Used to + # skip data-dependent validity raises that cannot run under tracing (the host-side + # caller is expected to validate folds before vmap); eager (concrete) jax values are + # NOT tracers, so they still validate like the numpy backend. + _TRACER_TYPES: tuple = (_jax.core.Tracer,) +except ImportError: # pragma: no cover - exercised only without jax + Array = np.ndarray + Scalar = Union[np.floating, float, int] + FloatDType = type[np.floating] + _TRACER_TYPES = () + +if TYPE_CHECKING: + # JAX's scalar-dtype metaclass (`type(jnp.float64)`) has no public *static* type, so + # the precise runtime `FloatDType` union above is built from a value (`_JaxScalarMeta`) + # that static type checkers reject in a type expression ("variables are not allowed in + # type expressions"). For static analysis only, expose numpy's standard dtype-specifier + # alias, which cleanly accepts both numpy float types and JAX scalar dtypes. At run + # time `TYPE_CHECKING` is False, so typeguard still validates against the precise union. + FloatDType = npt.DTypeLike + + +def _resolve_backend(backend: str): + """ + Resolve the array-namespace module for a given backend name. + + Parameters + ---------- + backend : {"numpy", "jax"} + The array backend to use. ``"numpy"`` uses ``numpy`` (the default and only + required dependency). ``"jax"`` uses ``jax.numpy`` so that the per-fold training + matrix computations can run inside ``jax.jit``/``jax.vmap`` on CPU/GPU/TPU; it + requires the optional ``jax`` dependency (``pip install cvmatrix[jax]``). + + Returns + ------- + module + The resolved array namespace (``numpy`` or ``jax.numpy``). + + Raises + ------ + ValueError + If ``backend`` is not ``"numpy"`` or ``"jax"``. + ImportError + If ``backend == "jax"`` but JAX is not installed. + """ + if backend == "numpy": + return np + if backend == "jax": + try: + import jax.numpy as jnp + except ImportError as e: # pragma: no cover - exercised only without jax + raise ImportError( + "backend='jax' requires the optional JAX dependency. Install it with " + "`pip install cvmatrix[jax]`." + ) from e + return jnp + raise ValueError(f"Invalid backend: {backend!r}. Must be 'numpy' or 'jax'.") + class CVMatrix: r""" @@ -81,8 +154,9 @@ def __init__( scale_X: bool = True, scale_Y: bool = True, ddof: int = 1, - dtype: type[np.floating] = np.float64, + dtype: FloatDType = np.float64, copy: bool = True, + backend: Literal["numpy", "jax"] = "numpy", ) -> None: self.center_X = center_X self.center_Y = center_Y @@ -91,6 +165,18 @@ def __init__( self.ddof = ddof self.dtype = dtype.type if isinstance(dtype, np.dtype) else dtype self.copy = copy + self.backend = backend + # Array namespace: numpy (default) or jax.numpy. All array operations are routed + # through `self.xp` so that, with backend="jax", the per-fold `training_*` + # methods can be traced by jax.jit/jax.vmap. The numpy backend is byte-identical + # to previous releases. + self.xp = _resolve_backend(backend) + if backend == "jax" and np.dtype(self.dtype).itemsize >= 8: + # JAX defaults to 32-bit; enable 64-bit precision so a requested float64 + # dtype is honored instead of being silently truncated to float32. + import jax + + jax.config.update("jax_enable_x64", True) self.resolution = np.finfo(dtype).resolution * 10 self.X = None self.Y = None @@ -139,10 +225,10 @@ def fit( Attributes ---------- - X : np.ndarray + X : Array The total predictor matrix `X` for the entire dataset. - Y : np.ndarray or None + Y : Array or None The total response matrix `Y` for the entire dataset. If `Y` is `None`, this is `None`. @@ -155,60 +241,60 @@ def fit( M : int or None The number of response variables in `Y`. If `Y` is `None`, this is `None`. - XTX : np.ndarray + XTX : Array The total matrix :math:`\mathbf{X}^{\mathbf{T}}\mathbf{W}\mathbf{X}` for the entire dataset. - XTY : np.ndarray or None + XTY : Array or None The total matrix :math:`\mathbf{X}^{\mathbf{T}}\mathbf{W}\mathbf{Y}` for the entire dataset. This is computed only if `Y` is not `None`. - sum_X : np.ndarray or None + sum_X : Array or None The row of column-wise weighted sums of `X` for the entire dataset. This is computed only if `center_X`, `scale_X`, or `center_Y` is `True`. This is the row of column-wise sums of :math:`\mathbf{W}\mathbf{X}` if `weights` are provided and otherwise the row of column-wise sums of :math:`\mathbf{X}`. - sum_Y : np.ndarray or None + sum_Y : Array or None The row of column-wise weighted sums of `Y` for the entire dataset. This is computed only if `center_Y`, `scale_Y`, or `center_X` is `True` and `Y` is not `None`. This is the row of column-wise sums of :math:`\mathbf{W}\mathbf{Y}` if `weights` are provided and otherwise the row of column-wise sums of :math:`\mathbf{Y}`. - sum_sq_X : np.ndarray or None + sum_sq_X : Array or None The row of column-wise weighted squared sums of `X` for the entire dataset. This is computed only if `scale_X` is `True`. This is the row of column-wise sums of :math:`\mathbf{W}\mathbf{X}\odot\mathbf{X}` if `weights` are provided and otherwise the row of column-wise sums of :math:`\mathbf{X}\odot\mathbf{X}`. - sum_sq_Y : np.ndarray or None + sum_sq_Y : Array or None The row of column-wise weighted squared sums of `Y` for the entire dataset. This is computed only if `scale_Y` is `True` and `Y` is not `None`. This is the row of column-wise sums of :math:`\mathbf{W}\mathbf{Y}\odot\mathbf{Y}` if `weights` are provided and otherwise the row of column-wise sums of :math:`\mathbf{Y}\odot\mathbf{Y}`. - sq_X : np.ndarray or None + sq_X : Array or None The total weighted squared predictor matrix `X` for the entire dataset. This is :math:`\mathbf{W}\mathbf{X}\odot\mathbf{X}`. This is computed only if `scale_X` is `True`. - sq_Y : np.ndarray or None + sq_Y : Array or None The total weighted squared response matrix `Y` for the entire dataset. This is :math:`\mathbf{W}\mathbf{Y}\odot\mathbf{Y}`. This is computed only if `scale_Y` is `True` and `Y` is not `None`. - WX : np.ndarray or None + WX : Array or None The total weighted predictor matrix `X` for the entire dataset. This is :math:`\mathbf{W}\mathbf{X}`. - WY : np.ndarray or None + WY : Array or None The total weighted response matrix `Y` for the entire dataset. This is :math:`\mathbf{W}\mathbf{Y}`. This is computed only if `Y` is not `None`. - weights : np.ndarray or None + weights : Array or None The total weights for the entire dataset. This is an array of shape (N, 1). If `weights` is `None`, this is `None`. @@ -237,7 +323,7 @@ def fit( def training_XTX( self, validation_indices: npt.NDArray[np.int_] ) -> Tuple[ - np.ndarray, Tuple[Optional[np.ndarray], Optional[np.ndarray], None, None] + Array, Tuple[Optional[Array], Optional[Array], None, None] ]: r""" Computes the training set :math:`\mathbf{X}^{\mathbf{T}}\mathbf{W}\mathbf{X}` @@ -292,12 +378,12 @@ def training_XTX( def training_XTY( self, validation_indices: npt.NDArray[np.int_] ) -> Tuple[ - np.ndarray, + Array, Tuple[ - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Array], ], ]: r""" @@ -358,12 +444,12 @@ def training_XTY( def training_XTX_XTY( self, validation_indices: npt.NDArray[np.int_] ) -> Tuple[ - Tuple[np.ndarray, np.ndarray], + Tuple[Array, Array], Tuple[ - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Array], ], ]: r""" @@ -426,10 +512,10 @@ def training_XTX_XTY( def training_statistics( self, validation_indices: npt.NDArray[np.int_] ) -> Tuple[ - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Array], ]: """ Computes the row of column-wise weighted means and standard deviations for `X` @@ -448,7 +534,7 @@ def training_statistics( Returns ------- - Tuple of four elements of Optional[np.ndarray] + Tuple of four elements of Optional[Array] A tuple containing the row of column-wise weighted means for `X`, the row of column-wise weighted standard deviations for `X`, the row of column-wise weighted means for `Y`, and the row of column-wise weighted standard @@ -480,9 +566,22 @@ def training_statistics( return_Y_std=self.scale_Y and self.Y is not None, )[:-1] # Exclude the sum of training weights from the return tuple + def _as_scalar(self, x): + """ + Cast a scalar-valued result to the configured dtype. + + For the numpy backend this returns a NumPy scalar (preserving the historical + ``np.floating`` return types and byte-identical behavior). For the jax backend + it returns the value unchanged (already a ``jax.numpy`` value of the right + dtype), keeping the per-fold path trace-safe. + """ + if self.backend == "numpy": + return self.dtype(x) + return x + def _get_sum_w_train_and_num_nonzero_w_train( self, val_indices: npt.NDArray[np.int_] - ) -> Tuple[np.floating, np.floating]: + ) -> Tuple[Scalar, Scalar]: """ Returns a tuple containing the sum of weights in the training set and the number of non-zero weights in the training set. If `self.weights` is `None`, it returns @@ -502,16 +601,21 @@ def _get_sum_w_train_and_num_nonzero_w_train( make it impossible to compute either of training set means or standard deviations. """ + xp = self.xp if self.weights is None: sum_w_val = val_indices.size - sum_w_train = self.dtype(self.sum_w - sum_w_val) + sum_w_train = self._as_scalar(self.sum_w - sum_w_val) return (sum_w_train, sum_w_train) w_val = self.weights[val_indices] - sum_w_val = np.sum(w_val) - sum_w_train = self.dtype(self.sum_w - sum_w_val) - num_nonzero_w_val = np.count_nonzero(w_val) - num_nonzero_w_train = self.dtype(self.num_nonzero_w - num_nonzero_w_val) - if num_nonzero_w_train == 0: + sum_w_val = xp.sum(w_val) + sum_w_train = self._as_scalar(self.sum_w - sum_w_val) + num_nonzero_w_val = xp.count_nonzero(w_val) + num_nonzero_w_train = self._as_scalar(self.num_nonzero_w - num_nonzero_w_val) + # Validate eagerly (numpy, or concrete/eager jax). Under jax.jit/vmap tracing the + # input `val_indices` is a tracer (in both the weighted and unweighted paths), so + # we skip the data-dependent raise; degenerate folds are then expected to be + # rejected by a host-side pre-flight before vmap. + if not isinstance(val_indices, _TRACER_TYPES) and num_nonzero_w_train == 0: raise ValueError( "The number of non-zero weights in the training set must be " "greater than zero." @@ -521,18 +625,18 @@ def _get_sum_w_train_and_num_nonzero_w_train( def _compute_training_stats( self, val_indices: npt.NDArray[np.int_], - X_val: Optional[np.ndarray], - Y_val: Optional[np.ndarray], + X_val: Optional[Array], + Y_val: Optional[Array], return_X_mean: bool, return_X_std: bool, return_Y_mean: bool, return_Y_std: bool, ) -> Tuple[ - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.floating], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Scalar], ]: """ Computes the training set statistics. The training set corresponds @@ -572,7 +676,7 @@ def _compute_training_stats( Returns ------- - Tuple of Optional[np.ndarray] + Tuple of Optional[Array] A tuple containing the row of column-wise weighted means for `X`, the row of column-wise weighted standard deviations for `X`, the row of column-wise weighted means for `Y`, the row of column-wise weighted standard deviations @@ -586,27 +690,34 @@ def _compute_training_stats( and not return_Y_std ): return None, None, None, None, None + # Under jax.jit/vmap, `val_indices` is a tracer; data-dependent validity raises + # are then deferred to a host-side pre-flight (see `_get_sum_w_train_*` and + # `_compute_std_divisor`). The unweighted path derives its counts from static + # shapes, so it cannot rely on the count itself being a tracer. + traced = isinstance(val_indices, _TRACER_TYPES) sum_w_train, num_nonzero_w_train = ( self._get_sum_w_train_and_num_nonzero_w_train(val_indices) ) if return_X_mean or return_X_std: - sum_X_val = np.sum(X_val, axis=0, keepdims=True) + sum_X_val = self.xp.sum(X_val, axis=0, keepdims=True) sum_X_train = self._compute_train_mat_sum(sum_X_val, self.sum_X) X_train_mean = self._compute_training_mat_mean( sum_X_train, sum_w_train, ) if return_Y_mean or return_Y_std: - sum_Y_val = np.sum(Y_val, axis=0, keepdims=True) + sum_Y_val = self.xp.sum(Y_val, axis=0, keepdims=True) sum_Y_train = self._compute_train_mat_sum(sum_Y_val, self.sum_Y) Y_train_mean = self._compute_training_mat_mean( sum_Y_train, sum_w_train, ) if return_X_std or return_Y_std: - divisor = self._compute_std_divisor(sum_w_train, num_nonzero_w_train) + divisor = self._compute_std_divisor( + sum_w_train, num_nonzero_w_train, traced + ) if return_X_std: - sum_sq_X_val = np.sum(self.sq_X[val_indices], axis=0, keepdims=True) + sum_sq_X_val = self.xp.sum(self.sq_X[val_indices], axis=0, keepdims=True) sum_sq_X_train = self._compute_train_mat_sum(sum_sq_X_val, self.sum_sq_X) X_train_std = self._compute_training_mat_std( sum_sq_X_train, @@ -616,7 +727,7 @@ def _compute_training_stats( divisor, ) if return_Y_std: - sum_sq_Y_val = np.sum(self.sq_Y[val_indices], axis=0, keepdims=True) + sum_sq_Y_val = self.xp.sum(self.sq_Y[val_indices], axis=0, keepdims=True) sum_sq_Y_train = self._compute_train_mat_sum(sum_sq_Y_val, self.sum_sq_Y) Y_train_std = self._compute_training_mat_std( sum_sq_Y_train, @@ -636,12 +747,12 @@ def _compute_training_stats( def _training_matrices( self, return_XTX: bool, return_XTY: bool, val_indices: npt.NDArray[np.int_] ) -> Tuple[ - Union[np.ndarray, Tuple[np.ndarray, np.ndarray]], + Union[Array, Tuple[Array, Array]], Tuple[ - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], - Optional[np.ndarray], + Optional[Array], + Optional[Array], + Optional[Array], + Optional[Array], ], ]: r""" @@ -780,10 +891,10 @@ def _training_matrices( def _get_val_matrices( self, val_indices: npt.NDArray[np.int_], return_XTY: bool ) -> Tuple[ - np.ndarray, - np.ndarray, - Optional[np.ndarray], - Optional[np.ndarray], + Array, + Array, + Optional[Array], + Optional[Array], ]: """ Returns the validation set matrices for a given fold. @@ -824,16 +935,16 @@ def _get_val_matrices( def _training_kernel_matrix( self, - total_kernel_mat: np.ndarray, - X_val: np.ndarray, - mat2_val: np.ndarray, - X_train_mean: Optional[np.ndarray] = None, - mat2_train_mean: Optional[np.ndarray] = None, - X_train_std: Optional[np.ndarray] = None, - mat2_train_std: Optional[np.ndarray] = None, - sum_w_train: Optional[np.floating] = None, + total_kernel_mat: Array, + X_val: Array, + mat2_val: Array, + X_train_mean: Optional[Array] = None, + mat2_train_mean: Optional[Array] = None, + X_train_std: Optional[Array] = None, + mat2_train_std: Optional[Array] = None, + sum_w_train: Optional[Scalar] = None, center: bool = False, - ) -> np.ndarray: + ) -> Array: r""" Computes the training set kernel matrix for a given fold. @@ -893,9 +1004,9 @@ def _training_kernel_matrix( def _compute_train_mat_sum( self, - sum_mat_val: np.ndarray, - sum_mat: np.ndarray, - ) -> np.ndarray: + sum_mat_val: Array, + sum_mat: Array, + ) -> Array: """ Computes the row vector of column-wise sums of a matrix for a given fold. """ @@ -903,9 +1014,9 @@ def _compute_train_mat_sum( def _compute_training_mat_mean( self, - sum_mat_train: np.ndarray, - sum_w_train: np.floating, - ) -> np.ndarray: + sum_mat_train: Array, + sum_w_train: Scalar, + ) -> Array: """ Computes the row of column-wise means of a matrix for a given fold. @@ -925,8 +1036,8 @@ def _compute_training_mat_mean( return sum_mat_train / sum_w_train def _compute_std_divisor( - self, sum_w_train: np.floating, num_nonzero_w_train: np.floating - ) -> np.floating: + self, sum_w_train: Scalar, num_nonzero_w_train: Scalar, traced: bool = False + ) -> Scalar: """ Computes the divisor for the standard deviation calculation based on the number of samples in the training set and the number of non-zero weights. @@ -939,12 +1050,21 @@ def _compute_std_divisor( num_nonzero_w_train : int The number of non-zero weights in the training set. + traced : bool, default=False + Whether the computation is being traced by jax.jit/jax.vmap. When True, the + data-dependent degenerate-fold check is skipped (deferred to a host-side + pre-flight); a non-positive divisor then degrades gracefully via the clamp in + `_compute_training_mat_std`. + Returns ------- float The divisor for the standard deviation calculation. """ - if num_nonzero_w_train <= self.ddof: + # Validate eagerly (numpy, or concrete/eager jax). Under jax.jit/vmap tracing + # (`traced`, detected from the input `val_indices`) the check is deferred to a + # host-side pre-flight before vmap. + if not traced and num_nonzero_w_train <= self.ddof: raise ValueError( "The number of non-zero weights in the training set must be greater " "than `ddof`." @@ -953,12 +1073,12 @@ def _compute_std_divisor( def _compute_training_mat_std( self, - sum_sq_mat_train: np.ndarray, - mat_train_mean: np.ndarray, - sum_mat_train: np.ndarray, - sum_w_train: np.floating, - divisor: np.floating, - ) -> np.ndarray: + sum_sq_mat_train: Array, + mat_train_mean: Array, + sum_mat_train: Array, + sum_w_train: Scalar, + divisor: Scalar, + ) -> Array: r""" Computes the row of column-wise standard deviations of a matrix for a given fold. @@ -988,17 +1108,20 @@ def _compute_training_mat_std( Array of shape (1, K) or (1, M) The row of column-wise standard deviations of the training set matrix. """ + xp = self.xp mat_train_var = ( -2 * mat_train_mean * sum_mat_train + sum_w_train * mat_train_mean**2 + sum_sq_mat_train ) / divisor - mat_train_var[mat_train_var < 0] = 0 - mat_train_std = np.sqrt(mat_train_var) - mat_train_std[mat_train_std <= self.resolution] = 1 + # `xp.maximum`/`xp.where` instead of boolean-mask in-place assignment: identical + # results for numpy and trace-safe for jax (jit/vmap). + mat_train_var = xp.maximum(mat_train_var, 0) + mat_train_std = xp.sqrt(mat_train_var) + mat_train_std = xp.where(mat_train_std <= self.resolution, 1, mat_train_std) return mat_train_std - def _init_mat(self, mat: np.ndarray) -> np.ndarray: + def _init_mat(self, mat: Array) -> Array: """ Casts the matrix to the dtype specified in the constructor and reshapes it if the matrix is one-dimensional. @@ -1013,7 +1136,7 @@ def _init_mat(self, mat: np.ndarray) -> np.ndarray: Array of shape (N, K) or (N, M) or (N, 1) The initialized matrix. """ - mat = np.asarray(mat, dtype=self.dtype) + mat = self.xp.asarray(mat, dtype=self.dtype) if self.copy and mat.dtype == self.dtype: mat = mat.copy() if mat.ndim == 1: @@ -1055,7 +1178,7 @@ def _init_mats( if weights is not None: self.weights = self._init_mat(weights) - if np.any(self.weights < 0): + if bool(self.xp.any(self.weights < 0)): raise ValueError("Weights must be non-negative.") else: self.weights = None @@ -1092,22 +1215,22 @@ def _init_stats(self) -> None: """ if self.center_X or self.center_Y or self.scale_X or self.scale_Y: if self.weights is not None: - self.sum_w = np.sum(self.weights) - self.num_nonzero_w = np.count_nonzero(self.weights) + self.sum_w = self.xp.sum(self.weights) + self.num_nonzero_w = self.xp.count_nonzero(self.weights) else: self.sum_w = self.N self.num_nonzero_w = self.N if self.center_X or self.center_Y or self.scale_X: - self.sum_X = np.sum(self.WX, axis=0, keepdims=True) + self.sum_X = self.xp.sum(self.WX, axis=0, keepdims=True) if (self.center_X or self.center_Y or self.scale_Y) and self.Y is not None: - self.sum_Y = np.sum(self.WY, axis=0, keepdims=True) + self.sum_Y = self.xp.sum(self.WY, axis=0, keepdims=True) if self.scale_X: self.sq_X = self.WX * self.X - self.sum_sq_X = np.sum(self.sq_X, axis=0, keepdims=True) + self.sum_sq_X = self.xp.sum(self.sq_X, axis=0, keepdims=True) else: self.sum_sq_X = None if self.scale_Y and self.Y is not None: self.sq_Y = self.WY * self.Y - self.sum_sq_Y = np.sum(self.sq_Y, axis=0, keepdims=True) + self.sum_sq_Y = self.xp.sum(self.sq_Y, axis=0, keepdims=True) else: self.sum_sq_Y = None diff --git a/examples/training_matrices_jax.py b/examples/training_matrices_jax.py new file mode 100644 index 0000000..e9110d8 --- /dev/null +++ b/examples/training_matrices_jax.py @@ -0,0 +1,78 @@ +r""" +This file demonstrates the optional **JAX backend** of CVMatrix (``backend="jax"``). +With the JAX backend, the per-fold training matrices +:math:`\mathbf{X}^{\mathbf{T}}\mathbf{W}\mathbf{X}` and +:math:`\mathbf{X}^{\mathbf{T}}\mathbf{W}\mathbf{Y}` (with training-set centering/scaling +and weighting) are computed with ``jax.numpy``. Because each ``training_*`` call is a +pure function of the (closed-over) dataset-wide statistics and the validation indices, +it can be traced by ``jax.jit`` and -- most usefully -- batched over folds with +``jax.vmap`` to run all folds together on a CPU/GPU/TPU. + +The numerical results are identical to the default ``backend="numpy"``. + +Note: requires the optional JAX dependency, installed with ``pip install cvmatrix[jax]``. + +Author: Ole-Christian Galbo Engstrøm +E-mail: ocge@foss.dk +""" + +import jax +import jax.numpy as jnp +import numpy as np + +from cvmatrix import CVMatrix, Partitioner + +# Honor float64 (JAX defaults to float32). CVMatrix also enables this automatically when +# constructed with backend="jax" and a 64-bit dtype. +jax.config.update("jax_enable_x64", True) + + +if __name__ == "__main__": + rng = np.random.default_rng(42) + N, K, M = 100, 10, 3 + X = rng.uniform(size=(N, K)) + Y = rng.uniform(size=(N, M)) + weights = rng.uniform(size=(N,)) + 0.1 # non-negative + + # 5-fold cross-validation (equal-size folds -> a single vmap shape). + folds = np.arange(N) % 5 + + # Build a JAX-backed CVMatrix. The only change from the numpy backend is + # backend="jax"; the API is identical. + cvm = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, backend="jax" + ) + cvm.fit(X, Y, weights) + + # Partitioner does host-side fold/index bookkeeping (numpy). Stack the per-fold + # validation indices into a single (n_folds, fold_size) array and move it to the + # device once; jax.vmap then computes every fold's training matrices together. + p = Partitioner(folds) + val_index_batch = jnp.asarray( + np.stack([p.get_validation_indices(fold) for fold in p.folds_dict]) + ) + + # vmap (optionally under jit) the per-fold training-matrix computation over folds. + batched_training_XTX_XTY = jax.jit(jax.vmap(cvm.training_XTX_XTY)) + (XTWX, XTWY), (X_mean, X_std, Y_mean, Y_std) = batched_training_XTX_XTY( + val_index_batch + ) + + # The leading axis of each output indexes the folds. + print(f"Folds: {list(p.folds_dict.keys())}") + print(f"Batched training XTWX shape: {XTWX.shape} (n_folds, K, K)") + print(f"Batched training XTWY shape: {XTWY.shape} (n_folds, K, M)") + print(f"Batched training X mean shape: {X_mean.shape} (n_folds, 1, K)") + + # Cross-check the first fold against the numpy backend (identical results). + cvm_np = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, backend="numpy" + ) + cvm_np.fit(X, Y, weights) + first_fold = next(iter(p.folds_dict)) + (XTWX_np, XTWY_np), _ = cvm_np.training_XTX_XTY(p.get_validation_indices(first_fold)) + print( + "Max |jax - numpy| for fold " + f"{first_fold!r}: XTWX={np.max(np.abs(np.asarray(XTWX[0]) - XTWX_np)):.2e}, " + f"XTWY={np.max(np.abs(np.asarray(XTWY[0]) - XTWY_np)):.2e}" + ) diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 6054a26..0000000 --- a/poetry.lock +++ /dev/null @@ -1,87 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "numpy" -version = "2.4.0" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.11" -files = [ - {file = "numpy-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:316b2f2584682318539f0bcaca5a496ce9ca78c88066579ebd11fd06f8e4741e"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2718c1de8504121714234b6f8241d0019450353276c88b9453c9c3d92e101db"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:21555da4ec4a0c942520ead42c3b0dc9477441e085c42b0fbdd6a084869a6f6b"}, - {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:413aa561266a4be2d06cd2b9665e89d9f54c543f418773076a76adcf2af08bc7"}, - {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0feafc9e03128074689183031181fac0897ff169692d8492066e949041096548"}, - {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8fdfed3deaf1928fb7667d96e0567cdf58c2b370ea2ee7e586aa383ec2cb346"}, - {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e06a922a469cae9a57100864caf4f8a97a1026513793969f8ba5b63137a35d25"}, - {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:927ccf5cd17c48f801f4ed43a7e5673a2724bd2171460be3e3894e6e332ef83a"}, - {file = "numpy-2.4.0-cp311-cp311-win32.whl", hash = "sha256:882567b7ae57c1b1a0250208cc21a7976d8cbcc49d5a322e607e6f09c9e0bd53"}, - {file = "numpy-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b986403023c8f3bf8f487c2e6186afda156174d31c175f747d8934dfddf3479"}, - {file = "numpy-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:3f3096405acc48887458bbf9f6814d43785ac7ba2a57ea6442b581dedbc60ce6"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344"}, - {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6"}, - {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb"}, - {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63"}, - {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95"}, - {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6"}, - {file = "numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c"}, - {file = "numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98"}, - {file = "numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee"}, - {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e"}, - {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2"}, - {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a"}, - {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681"}, - {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475"}, - {file = "numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344"}, - {file = "numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d"}, - {file = "numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5"}, - {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3"}, - {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d"}, - {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3"}, - {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa"}, - {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c"}, - {file = "numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93"}, - {file = "numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4"}, - {file = "numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e"}, - {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51"}, - {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce"}, - {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f"}, - {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded"}, - {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059"}, - {file = "numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db"}, - {file = "numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e"}, - {file = "numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9"}, - {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9"}, - {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471"}, - {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544"}, - {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c"}, - {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac"}, - {file = "numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f"}, - {file = "numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4"}, - {file = "numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2f585f52b2baf07ff3356158d9268ea095e221371f1074fadea2f42544d58b4d"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32ed06d0fe9cae27d8fb5f400c63ccee72370599c75e683a6358dd3a4fb50aaf"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57c540ed8fb1f05cb997c6761cd56db72395b0d6985e90571ff660452ade4f98"}, - {file = "numpy-2.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a39fb973a726e63223287adc6dafe444ce75af952d711e400f3bf2b36ef55a7b"}, - {file = "numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934"}, -] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.11, <3.15" -content-hash = "cebd365999c19877d1f150434d37f379d33e6b0becd4c88c452ce71dfdf124d1" diff --git a/pyproject.toml b/pyproject.toml index cc49a10..72e57ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,27 +1,47 @@ -[tool.poetry] +[project] name = "cvmatrix" -version = "3.1.6" +version = "3.2.0" description = "Fast computation of possibly weighted and possibly centered/scaled training set kernel matrices in a cross-validation setting." -authors = ["Sm00thix "] -maintainers = ["Sm00thix "] +authors = [{ name = "Sm00thix", email = "oleemail@icloud.com" }] +maintainers = [{ name = "Sm00thix", email = "oleemail@icloud.com" }] license = "Apache-2.0" readme = "README.md" -homepage = "https://cvmatrix.readthedocs.io/en/latest/" -repository = "https://github.com/Sm00thix/CVMatrix" +requires-python = ">=3.11, <3.15" classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] +dependencies = [ + "numpy>=2.0.0,<3.0.0", +] + +[project.optional-dependencies] +# Optional JAX backend (backend="jax"): enables tracing the per-fold training-matrix +# computations under jax.jit/jax.vmap on CPU/GPU/TPU. Install with `cvmatrix[jax]`. +jax = ["jax>=0.4.0"] + +[project.urls] +Homepage = "https://cvmatrix.readthedocs.io/en/latest/" +Repository = "https://github.com/Sm00thix/CVMatrix" -[tool.poetry.dependencies] -python = ">=3.11, <3.15" -numpy = "^2.0.0" +# Development/test-only dependencies (PEP 735). Installed by `uv sync`. +[dependency-groups] +dev = [ + "pandas", + "pytest", + "pytest-cov", + "typeguard", + "ruff", +] [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["cvmatrix"] [tool.pytest.ini_options] addopts = [ @@ -30,4 +50,4 @@ addopts = [ "--cov-report=xml", "--cov-report=html", "--cov-report=term-missing", -] \ No newline at end of file +] diff --git a/tests/test_cvmatrix.py b/tests/test_cvmatrix.py index 5cdc929..3e067a6 100644 --- a/tests/test_cvmatrix.py +++ b/tests/test_cvmatrix.py @@ -59,6 +59,18 @@ class tests for equivalency between the naive, straight-forward algorithms # ones_weights = ones_weights[indices] # random_weights = random_weights[indices] + @pytest.fixture(params=["numpy", "jax"], autouse=True) + def _set_backend(self, request): + """ + Run every test with both the "numpy" and "jax" CVMatrix backends. The jax + parametrization is skipped if JAX is not installed. `fit_fast` builds the + CVMatrix model with `backend=self.backend`, so all equivalence and behavior + tests exercise both backends. + """ + if request.param == "jax": + pytest.importorskip("jax") + self.backend = request.param + def load_X(self) -> npt.NDArray[np.float64]: """ Loads the raw spectral data. @@ -286,7 +298,10 @@ def fit_fast( made. If `True` a copy is always made. If no copy is made, then external modifications to `X` or `Y` will result in undefined behavior. """ - fast = CVMatrix(center_X, center_Y, scale_X, scale_Y, ddof, dtype, copy) + fast = CVMatrix( + center_X, center_Y, scale_X, scale_Y, ddof, dtype, copy, + backend=getattr(self, "backend", "numpy"), + ) fast.fit(X, Y, weights) return fast @@ -559,6 +574,114 @@ def test_all_preprocessing_combinations(self): ) self.check_equivalent_matrices(naive, fast, p) + def test_jax_backend_requires_jax(self, monkeypatch): + """ + Tests that requesting backend="jax" raises ImportError with an install hint when + JAX is not installed. JAX absence is simulated by hiding it from `sys.modules`, + so this test is valid regardless of whether JAX is installed in the environment. + """ + monkeypatch.setitem(sys.modules, "jax", None) + monkeypatch.setitem(sys.modules, "jax.numpy", None) + with pytest.raises(ImportError, match="cvmatrix\\[jax\\]"): + CVMatrix(backend="jax") + + def test_invalid_backend(self): + """ + Tests that an unknown backend string raises ValueError (the sibling of the + ImportError path tested in `test_jax_backend_requires_jax`). Exercised via + `_resolve_backend` directly: the constructor's `Literal["numpy", "jax"]` hint is + intercepted by typeguard before the ValueError is reached, whereas + `_resolve_backend(backend: str)` accepts the str and reaches the real check. + """ + from cvmatrix.cvmatrix import _resolve_backend + + with pytest.raises(ValueError, match="Invalid backend"): + _resolve_backend("torch") + + def test_jax_jit_vmap_matches_numpy(self): + """ + Exercises the JAX backend under jax.jit + jax.vmap (the headline feature and the + trace-safety machinery: the deferred degenerate-fold checks and the xp.maximum/ + xp.where standard-deviation clamp all run under tracing here). Batches the per- + fold training_XTX_XTY over equal-size folds with jax.vmap and checks the results + match the eager numpy backend, for both unweighted and weighted folds. The + unweighted case specifically covers the path where the training-set count is a + static int rather than a tracer. + """ + if getattr(self, "backend", "numpy") != "jax": + pytest.skip("JAX-specific trace test; runs under the jax parametrization.") + pytest.importorskip("jax") + import jax + import jax.numpy as jnp + + X = self.load_X()[:, :20] + Y = self.load_Y(["Protein", "Moisture"]) + # Equal-size folds so jax.vmap sees a fixed (n_folds, fold_size) index batch. + n_folds = 5 + n = (X.shape[0] // n_folds) * n_folds + X, Y = X[:n], Y[:n] + folds = np.arange(n) % n_folds + p = Partitioner(folds) + val_index_batch = jnp.asarray( + np.stack([p.get_validation_indices(f) for f in p.folds_dict]) + ) + + for weights in (None, self.load_weights(random=True)[:n]): + cvm_jax = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, + ddof=1, backend="jax", + ) + cvm_jax.fit(X, Y, weights) + cvm_np = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, + ddof=1, backend="numpy", + ) + cvm_np.fit(X, Y, weights) + (XTWX_b, XTWY_b), (Xm_b, Xs_b, Ym_b, Ys_b) = jax.jit( + jax.vmap(cvm_jax.training_XTX_XTY) + )(val_index_batch) + for i, fold in enumerate(p.folds_dict): + (XTWX, XTWY), (Xm, Xs, Ym, Ys) = cvm_np.training_XTX_XTY( + p.get_validation_indices(fold) + ) + assert_allclose(np.asarray(XTWX_b[i]), XTWX, atol=1e-8, rtol=1e-8) + assert_allclose(np.asarray(XTWY_b[i]), XTWY, atol=1e-8, rtol=1e-8) + assert_allclose(np.asarray(Xm_b[i]), Xm, atol=1e-8, rtol=1e-8) + assert_allclose(np.asarray(Xs_b[i]), Xs, atol=1e-8, rtol=1e-8) + assert_allclose(np.asarray(Ym_b[i]), Ym, atol=1e-8, rtol=1e-8) + assert_allclose(np.asarray(Ys_b[i]), Ys, atol=1e-8, rtol=1e-8) + + def test_jax_trace_defers_degenerate_check(self): + """ + Under jax.jit/jax.vmap, the data-dependent degenerate-fold ValueError must be + skipped (deferred to a host-side pre-flight); eager execution must still raise. + This guards the UNWEIGHTED path specifically, where the training-set count is a + static int (not a tracer) and so the skip must key on the input `val_indices` + being a tracer rather than on the count. + """ + if getattr(self, "backend", "numpy") != "jax": + pytest.skip("JAX-specific trace test; runs under the jax parametrization.") + pytest.importorskip("jax") + import jax + import jax.numpy as jnp + + X = self.load_X()[:6, :4] + Y = self.load_Y(["Protein"])[:6] + cvm = CVMatrix( + center_X=True, center_Y=True, scale_X=True, scale_Y=True, + ddof=1, backend="jax", + ) + cvm.fit(X, Y, None) # unweighted + # A degenerate fold: validating on 5 of 6 rows leaves 1 training sample (<= ddof). + degenerate_val = np.arange(5) + # Eager (concrete) execution validates and raises. + with pytest.raises(ValueError, match="greater than `ddof`"): + cvm.training_XTX_XTY(degenerate_val) + # Under jit, val_indices is a tracer: the check is deferred, so tracing must + # complete without raising (the degenerate std degrades via the clamp). + (XTWX, _), _ = jax.jit(cvm.training_XTX_XTY)(jnp.asarray(degenerate_val)) + assert XTWX.shape == (4, 4) + def test_naive_hadamard_vs_matmul(self): """ Tests if the NaiveCVMatrix model gives the same result when using Hadamard @@ -1026,6 +1149,11 @@ def test_dtype(self): Tests that different dtypes can be used and that the output preserves the dtype. """ + if getattr(self, "backend", "numpy") == "jax": + pytest.skip( + "NumPy-specific dtype coverage (incl. float16/float128); the jax backend " + "supports only float32/float64." + ) X = np.array([1, 2, 3, 4, 5]) Y = np.array([5, 4, 3, 2, 1]) folds = np.array([0, 0, 1, 1, 2]) @@ -1080,6 +1208,11 @@ def test_copy(self): """ Tests that the copy parameter works as expected. """ + if getattr(self, "backend", "numpy") == "jax": + pytest.skip( + "`copy`/`np.shares_memory` are NumPy-specific; the jax backend always " + "transfers inputs to device arrays." + ) dtype = np.float64 X = np.array([1, 2, 3, 4, 5]).astype(dtype) Y = np.array([5, 4, 3, 2, 1]).astype(dtype) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..7d0e429 --- /dev/null +++ b/uv.lock @@ -0,0 +1,800 @@ +version = 1 +revision = 3 +requires-python = ">=3.11, <3.15" +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/91/0a7c28934e50d8ac9a7b117712d176f2953c3170bccced5eaacfa3e96175/coverage-7.14.3.tar.gz", hash = "sha256:1a7563a443f3d53fdeb040ec8c9f7466aed7ca3dc5891aa09d3ca3625fa4387f", size = 924398, upload-time = "2026-06-22T23:10:25.584Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/24/efb17eb94018dd3415d0e8a76a4786a866e8964aa9c50f033399d23939c2/coverage-7.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e574801e1d643561594aa021206c46d80b257e9853087090ba97bed8b0a509d3", size = 220501, upload-time = "2026-06-22T23:08:02.182Z" }, + { url = "https://files.pythonhosted.org/packages/76/93/32f1bfca6cdd34259c8af42820a034b7a28dfb44969a13ed38c17e0ba5b0/coverage-7.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f82b6bb7d75a2613e85d07cefa3a8c973d0544a8993337f6e2728e4a1e94c305", size = 221008, upload-time = "2026-06-22T23:08:03.701Z" }, + { url = "https://files.pythonhosted.org/packages/eb/88/0d0f974855ff905d15a64f7873d00bdc4182e2736267486c6634f4af293c/coverage-7.14.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a2335ea5fed26af2e831094964fa3f8fae60b45f7e37fcc2d3b615b2add3ad87", size = 251420, upload-time = "2026-06-22T23:08:05.211Z" }, + { url = "https://files.pythonhosted.org/packages/39/7f/117dd2ec65e4140576f8ef991d88220f9b806769f7a8c20e0550c0f924e2/coverage-7.14.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fbb8c3a98e779013786ae01d229662aeacbc77100efbd3f2f245219ace5af700", size = 253331, upload-time = "2026-06-22T23:08:06.672Z" }, + { url = "https://files.pythonhosted.org/packages/87/55/f0bd6d6538e3f16829fb8a44b6c0d2fe9da638bbfdd6a20f8b5da8f4fa81/coverage-7.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac082660de8f429ba0ea363595abb838998570b9a7546777c60f413ab902bbde", size = 255441, upload-time = "2026-06-22T23:08:08.208Z" }, + { url = "https://files.pythonhosted.org/packages/1e/98/aa71f7879019c846a8a9662579ea4484b0202cf1e252ffeed647075e7eca/coverage-7.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac012839ff7e396030f1e94e10553a431d14e4de2ab65cb3acb72bbd5628ca2", size = 257398, upload-time = "2026-06-22T23:08:09.749Z" }, + { url = "https://files.pythonhosted.org/packages/f3/4f/5fd367e59844190f5965015d7bee899e67a89d13eb2760118479bf836f2f/coverage-7.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5952f8c1bda2a5347154450379316e6dfa4d934d62ca35f6784451e6f55074fb", size = 251558, upload-time = "2026-06-22T23:08:11.37Z" }, + { url = "https://files.pythonhosted.org/packages/8f/de/5383a6ee5a6376701fe07d980fa8e4a66c0c377fead16712720340d701a3/coverage-7.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8cf0f2509acb4619e2471a1951089054dd58ebea7a912066d2ea56dd4c24ca4a", size = 253134, upload-time = "2026-06-22T23:08:13.04Z" }, + { url = "https://files.pythonhosted.org/packages/01/99/09542b1a99f788e3daec7f0fadc288821e71aca9ea298d51bfa1ba79fed5/coverage-7.14.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2e41fd3aab806770008279a93879b0924b16247e09ab537c043d08bbca53b4ab", size = 251195, upload-time = "2026-06-22T23:08:14.606Z" }, + { url = "https://files.pythonhosted.org/packages/02/9d/722fe8c13f0fbb064491b9e8656e56a606286792e5068c47ca1042e773e8/coverage-7.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f0a47095963cfe054e0df178daca95aec21e680d6076da807c3add28dfe920f7", size = 254959, upload-time = "2026-06-22T23:08:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/fb/58/943627179ff1d82da9e54d0a5b0bb907bb19cf19515599ccd921de50b469/coverage-7.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a090cbf9521e78ffdb2fcf448b72902afe9f5923ff6a12d5c0d0120200348af9", size = 250914, upload-time = "2026-06-22T23:08:18.03Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d4/803efcbf9ae5567454a0c71e983589529448e2704ee0da2dc0163d482f18/coverage-7.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d310baf69a4fbe8a098ce727e4808a34866ac718a6f759ae659cbd3221358bc", size = 251824, upload-time = "2026-06-22T23:08:19.704Z" }, + { url = "https://files.pythonhosted.org/packages/32/79/3f78ea9563132746eed5cecb75d2e576f9d8fec45a47242b5ae0950b82a3/coverage-7.14.3-cp311-cp311-win32.whl", hash = "sha256:74fdd718d88fe144f4579b8747873a07ec3f04cb837d5faec5a25d9e22fa31a8", size = 222594, upload-time = "2026-06-22T23:08:21.311Z" }, + { url = "https://files.pythonhosted.org/packages/85/22/9ebbc5a2ab42ac5d0eea1f48648629e1de9bbe41ec243ed6b93d55a5a53f/coverage-7.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:cc96aa922e21d4bc5d5ed3c915cef27dfcbc13686f47d5e378d647fbfba655a2", size = 223073, upload-time = "2026-06-22T23:08:23.318Z" }, + { url = "https://files.pythonhosted.org/packages/71/af/69d5fcc16cb555153f99cec5467922f226be0369f7335a9506856d2a7bd0/coverage-7.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:c66f9f9d4f1e9712eb9b1de5310f881d4e2188cfcba5065e1a8490f38687f2c4", size = 222617, upload-time = "2026-06-22T23:08:25.054Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b0/8a911f6ffe6974dac4df95b468ab9a2899d0e59f0f99a489afeec39f00bc/coverage-7.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d74ff26299c4879ce3a4d826f9d3d4d556fd285fde7bbce3c0ef5a8ab1cec24", size = 220672, upload-time = "2026-06-22T23:08:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/0fc0cb52538783dbbae0934b834f5a58fd5354380ee6cad4a07b15dc845d/coverage-7.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:96150a9cf3468ea20f0bc5d0e21b3df8972c31480ef90fa7614b773cc6429665", size = 221035, upload-time = "2026-06-22T23:08:28.372Z" }, + { url = "https://files.pythonhosted.org/packages/77/e2/421ccfbb48335ac49e93301478cf5d623b0c2bf1c0cadd8e2b2fc6c0c710/coverage-7.14.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:27d07a46500ba23515b838dbcf52512026af04090755cf6cc64166d88c9b9a1a", size = 252540, upload-time = "2026-06-22T23:08:30.226Z" }, + { url = "https://files.pythonhosted.org/packages/06/c2/05b8c890097c61a7f4406b35396b997a635200ded0339eda83dfbe526c5f/coverage-7.14.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:621e13c6108234d7960aaf5762ab5c3c00f33c30c15af06dcbff0c73bf112727", size = 255274, upload-time = "2026-06-22T23:08:31.876Z" }, + { url = "https://files.pythonhosted.org/packages/dc/be/b6d9efe447f8ba3c3c854195f326bd64c54b907d936cd2fdebf8767ec72e/coverage-7.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b60ca6d8af70473491a15a343cbabab2e8f9ea66a4376e81c7aa24876a6f977", size = 256389, upload-time = "2026-06-22T23:08:33.843Z" }, + { url = "https://files.pythonhosted.org/packages/d4/3c/f26e50acc429e608bc534ac06f0a3c169019c798178ec5e9de3dbc0df9c9/coverage-7.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c90a7cdd5e380e1ce02f19792e2ac2fbfbf177e35a27e69fd3e873b30d895c0c", size = 258648, upload-time = "2026-06-22T23:08:35.481Z" }, + { url = "https://files.pythonhosted.org/packages/9e/a2/01c1fabf816c8e1dae197e258edf878a3d3ddc86fbda34b76e5794277d8f/coverage-7.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5d788e5fd55347eef06ca0732c77d04a264de67e8ff24631270cdff3767a60cf", size = 252949, upload-time = "2026-06-22T23:08:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/89/c6/941166dd79c31fd44a13063780ae8d552eee0089a0a0930b9bdb7df554ed/coverage-7.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62c7f79db2851c95ef020e5d28b97afde3daf9f7febcd35b53e05638f729063f", size = 254310, upload-time = "2026-06-22T23:08:39.174Z" }, + { url = "https://files.pythonhosted.org/packages/10/31/80b1fd028201a961033ce95be3cd1e39e521b3762e6b4a1ac1616cb291e7/coverage-7.14.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:90f7608aeb5d9b60b523b9fb2a4ee1973867cc4865a3f26fe6c7577073b70205", size = 252453, upload-time = "2026-06-22T23:08:40.84Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/c3d9addd94c4b524f3f4af0232075f5fe7170ce99a1386edff803e5934db/coverage-7.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1e3b91f9c4740aeb571ecf82e5e8d8e4ab62d34fcb5a5d4e5baa38c6f7d2857c", size = 256522, upload-time = "2026-06-22T23:08:42.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/14/e5a0575f73795af3a7a9ae13dadf812e17d32422896839987dc3f86947e1/coverage-7.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c946099774a7699de03cbd0ff0a64e21aed4525eed9d959adde4afe6d15758ef", size = 252023, upload-time = "2026-06-22T23:08:44.243Z" }, + { url = "https://files.pythonhosted.org/packages/38/9b/9652ee531937ce3b8a63a8896885b2b4a2d56adc30e53c9540c666286d88/coverage-7.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16b206e521feb8b7133a45754643dead0538489cf8b783b90cf5f4e3299625fd", size = 253893, upload-time = "2026-06-22T23:08:46.113Z" }, + { url = "https://files.pythonhosted.org/packages/b1/05/42678841c8c38e4b08bdfc48269f5a16dfbf5806000fe6a89b4cece3c691/coverage-7.14.3-cp312-cp312-win32.whl", hash = "sha256:ea3169c7116eb6cdf7608c6c7da9ecfcb3da40688e3a510fac2d1d2bafd6dc35", size = 222734, upload-time = "2026-06-22T23:08:47.858Z" }, + { url = "https://files.pythonhosted.org/packages/df/87/07a4fcee55177a25f1b52331a8e92cf4f2c53b1a9c75ce2981fd59c684ad/coverage-7.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:7ea52fc08f007bcc494d4bb3df3851e95843d881860ba38fe2c64dc100db5e7d", size = 223266, upload-time = "2026-06-22T23:08:49.494Z" }, + { url = "https://files.pythonhosted.org/packages/aa/34/2b8b66a989282ea7b370beb49f50bab29470dc30bb0b03935b6b802782f7/coverage-7.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:8cec0ad652ec57790970d817490105bd917d783c2f7b38d6b58a0ca312e1a336", size = 222655, upload-time = "2026-06-22T23:08:51.766Z" }, + { url = "https://files.pythonhosted.org/packages/a9/83/7fefbf5df23ed2b7f489907564a7b34b9b07098128e12e0fdfa92626e456/coverage-7.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47968988b367990ae4ab17523790c38cd125e02c6bfd379b6022be2d40bdc38c", size = 220699, upload-time = "2026-06-22T23:08:53.522Z" }, + { url = "https://files.pythonhosted.org/packages/31/e6/38c3653ff6d56d704b29241362387ca824e38e15b76fdcb7096538195790/coverage-7.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0ee68f5c34812780f3a7063382c0a9fcbb99985b7ddcdcaa626e4f3fb2e0783a", size = 221068, upload-time = "2026-06-22T23:08:55.571Z" }, + { url = "https://files.pythonhosted.org/packages/20/86/4f5c45d51c5cd10a128933f0fd235393c9146abbfd2ce2dfa68b3267ead3/coverage-7.14.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fa9e5c6857a7e80fa22ace5cf3550ae392bbfc322f1d8dd2d2d5a8be38cec027", size = 252060, upload-time = "2026-06-22T23:08:57.464Z" }, + { url = "https://files.pythonhosted.org/packages/82/50/dfce42eff2cecabcd5a9bbad5489449c87db3415f408d23ffee417ce01f6/coverage-7.14.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98a0859b0e98e43e1178a9402e19c8127766b14f7109a374d976e5a62c0e5c73", size = 254657, upload-time = "2026-06-22T23:08:59.453Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d2/639ceb1bc8038fd0d66768278d5dc22df3391918b8278c2a21aa2602a531/coverage-7.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69918344541ed9c8368566c2adc03c0e33d4550d7faa87d1b35e49b6a3286ea9", size = 255892, upload-time = "2026-06-22T23:09:01.291Z" }, + { url = "https://files.pythonhosted.org/packages/8b/96/002094a10e113512500dc1e10430a449417e17b0f90f7d496bcb820208b7/coverage-7.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f300ac92cd4b570724c8ffbbd0c130fee298d2447f41d5a3abf58976fae1de", size = 258026, upload-time = "2026-06-22T23:09:03.017Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ec/286a5d2fad9c4bee59bd724feeb7d5bf8303c6c9200b51d1dd945a9c72b0/coverage-7.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11a7ec9f97ab950f4c5af62229befc7faf208fdbc0116d3902d7e306cf2c5abd", size = 252285, upload-time = "2026-06-22T23:09:04.773Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7d/a17753a0b12dd48d0d50f5fab079ad99d3be1eac790494d89f3a417ca0b9/coverage-7.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a571bd889cd36c5922ce8e42e059f9d37d02301531d11374afa4c87a578625d5", size = 254023, upload-time = "2026-06-22T23:09:06.513Z" }, + { url = "https://files.pythonhosted.org/packages/86/ef/a76c6ceba6a2c313f905310abf2701d534cada22d372db11731831e9e209/coverage-7.14.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de76caefc8deabb0dd1678b6a980be97d14c8d87e213ac194dbf8b09e96d63fb", size = 251989, upload-time = "2026-06-22T23:09:08.382Z" }, + { url = "https://files.pythonhosted.org/packages/d9/39/353013a75fec0fb49f7553519f9d52b4441e902e5178c93f38eb6c07cedb/coverage-7.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d20a15c622194234161535459affa8f7905830391c9ccfa060d495dbfe3a1c7f", size = 256144, upload-time = "2026-06-22T23:09:10.369Z" }, + { url = "https://files.pythonhosted.org/packages/29/0e/613878555d734def11c5b20a2701a15cb3781b9e9ea749da27c5f436e928/coverage-7.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b488bd4b23397db62e7a9459129d01ff06a846582a732efd24834b24a6ada498", size = 251808, upload-time = "2026-06-22T23:09:12.057Z" }, + { url = "https://files.pythonhosted.org/packages/af/76/359c058c9cfdcf1e8b107663881225b03b364a320017eda24a2a66e55102/coverage-7.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a3693b4153394d265f44fb855fdc80e72403024d4d6f91c4871b334d028e4e0", size = 253579, upload-time = "2026-06-22T23:09:13.858Z" }, + { url = "https://files.pythonhosted.org/packages/1d/d9/4ba2f060933a30ebe363cef9f67a365b0a317e580c0d5d9169d56a73ef1c/coverage-7.14.3-cp313-cp313-win32.whl", hash = "sha256:338b19131ab1a6b767b462bfcbaa692e7ae22f24463e39d49b02a83410ff6b37", size = 222741, upload-time = "2026-06-22T23:09:15.636Z" }, + { url = "https://files.pythonhosted.org/packages/76/e8/196ebc25d8f34c06d43a6e9c8513c9266ef8dbf3b5672beb1a00cf5e29fa/coverage-7.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:b3d77f7f196abdef7e01415de1bce09f216189e83e58159cfeef2b92d0464994", size = 223283, upload-time = "2026-06-22T23:09:17.478Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/51d2aac6417523a286f10fb25f09eb9518a84df9f1151e93ff6871f34849/coverage-7.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:e6230e688c7c3e65cedd41a774eb4ec221adc6bfee13768231015b702d5e4150", size = 222678, upload-time = "2026-06-22T23:09:19.7Z" }, + { url = "https://files.pythonhosted.org/packages/61/56/14e3b97facbfa1304dd19e676e26599ad359f04714bed32f7f1c5a88efdc/coverage-7.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:605ab2b566a22bd94834529d66d295c364aba84afd3e5498285c7a524017b1fc", size = 220741, upload-time = "2026-06-22T23:09:21.616Z" }, + { url = "https://files.pythonhosted.org/packages/12/1d/db378b5cca433b90b893f26dab728b280ddd89f272a1fdfed4aeaa05c686/coverage-7.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3c2134809e80fac091bfed18a6991b5a5eb5df5ae32b17ac4f4f99864b73dd7", size = 221068, upload-time = "2026-06-22T23:09:23.452Z" }, + { url = "https://files.pythonhosted.org/packages/47/f0/3f8421b20d9c4fcd39be9a8ca3c3fda8bc204b44efbd09fede153afd3e2f/coverage-7.14.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c02efd507227bde9969cab0db8f48890eb3b5dcad6afac57a4792df4133543ce", size = 252117, upload-time = "2026-06-22T23:09:25.458Z" }, + { url = "https://files.pythonhosted.org/packages/27/ca/59ea35fb99743549ec8b37eff141ece4431fea590c89e536ed8032ef45cf/coverage-7.14.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1bb93c2aa61d2a5b38f1526546d95cf4132cb681e541a337bf8dfd092be816e5", size = 254622, upload-time = "2026-06-22T23:09:27.523Z" }, + { url = "https://files.pythonhosted.org/packages/c8/25/ec6de51ae7493b92a1cf74d1b763121c29636759167e2a593ba4db5881e4/coverage-7.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f502e948e03e866538048bba081c075caaa62e5bda6ea5b7432e45f587eb462a", size = 255968, upload-time = "2026-06-22T23:09:29.43Z" }, + { url = "https://files.pythonhosted.org/packages/5d/05/c8bfc77823f42b4664fb25842f13b567022f6f84a4c83c8ecbb16734b7cb/coverage-7.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9973ef2463f8e6cfb61a6324126bb3e17d67a85f22f58d856e583ea2e3ca6501", size = 258284, upload-time = "2026-06-22T23:09:31.397Z" }, + { url = "https://files.pythonhosted.org/packages/f6/15/1d1b242027124a32b26ef01f82018b8c4ef34ef174aa6aeba7b1eeef48e8/coverage-7.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9be4e7d4c5ca0427889f8f9d614bd630c2be741b1de7699bca3b2b6c0e41003e", size = 252143, upload-time = "2026-06-22T23:09:33.256Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/d2a9842fd2a5d7d27f1ac851c043a734a494ad75402c5331db3da79ed691/coverage-7.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a574912f3bde4b0619f6e97d01aa590b70998859244793769eb3a6df78ee56d3", size = 253976, upload-time = "2026-06-22T23:09:35.351Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/e1600ddf7e226db5558bb5323d2186fff00f505c4b764643ec89ce5d8175/coverage-7.14.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e343fb086c9cd780b38622fea7c369acd64c1a0724312149b5d769c387a2b1f5", size = 251942, upload-time = "2026-06-22T23:09:37.313Z" }, + { url = "https://files.pythonhosted.org/packages/d9/2c/9159de64f9dd648e324328d588a44cfab1e331eb5259ce1141afe2a92dfb/coverage-7.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3c68df8e61f1e09633fefc7538297145623957a048534368c9d212782aa5e845", size = 256220, upload-time = "2026-06-22T23:09:39.165Z" }, + { url = "https://files.pythonhosted.org/packages/91/67/b7f536cc2c124f48e91b22fbb741d2261f4e3d310faf6f76007f47566e5d/coverage-7.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3e5b550a128419373c2f6cec28a244207013ef15f5cbcff6a5ca09d1dfaaf027", size = 251756, upload-time = "2026-06-22T23:09:41.056Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ec/f3718038e2d4860c715a55428377ca7f6c75872caf98cabd982e1d76967d/coverage-7.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2bfc4dd0a912329eccc7484a7d0b2a38032b38c40663b1e1ac595f10c457954b", size = 253413, upload-time = "2026-06-22T23:09:43.306Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a5/91f11efeef89b3cc9b30461128db15b0511ef813ab889a7b7ab636b3a497/coverage-7.14.3-cp314-cp314-win32.whl", hash = "sha256:0423d64c013057a06e70f070f073cec4b0cbc7d2b27f3c7007292f2ff1d52965", size = 222946, upload-time = "2026-06-22T23:09:45.261Z" }, + { url = "https://files.pythonhosted.org/packages/58/fd/98ac9f524d9ec378de831c034dbdeb544ca7ef7d2d9c9996daf232a037fd/coverage-7.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:92c22e19ce64ca3f2ad751f16f14df1468b4c231bd6af97185063a9c292a0cb3", size = 223436, upload-time = "2026-06-22T23:09:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a0/7cd612d650a772a0ae80144443406bf61981c896c3d57c9e6e79fb2cdbd1/coverage-7.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:41de778bd41780586e2b04912079c73089ab5d839624e28db3bdb26de638da92", size = 222861, upload-time = "2026-06-22T23:09:49.384Z" }, + { url = "https://files.pythonhosted.org/packages/55/57/017353fab573779c0d00448e47d102edd36c792f7b6f233a4d89a7a08384/coverage-7.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8427f370ca67db4c975d2a26acfc0e5783ca0b52444dbc50278ace0f35445949", size = 221474, upload-time = "2026-06-22T23:09:51.417Z" }, + { url = "https://files.pythonhosted.org/packages/69/92/90cf1f1a5c468a9c1b7ba2716e0e205293ad9b02f5f573a6de4318b15ba1/coverage-7.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8e88f335544a47e22ae2e45b344772925ec65166555c958720d5ed971880891", size = 221738, upload-time = "2026-06-22T23:09:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c0/4df964fa539f8399fd7679c09c472d73744de334686fd3f01e3a2465ce4e/coverage-7.14.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:beaab199b9e5ceaf5a225e16a9d4df136f2a1eae0a5c20de1e277c8a5225f388", size = 263101, upload-time = "2026-06-22T23:09:55.895Z" }, + { url = "https://files.pythonhosted.org/packages/06/76/e5d33b2576ae3bf2be2058cd1cae57774b61e400f2c3c58f3783dc2ffb4a/coverage-7.14.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ff255799f5a1676c71c1c32ec01fd043aa09d57b3d95764b24992757184784", size = 265225, upload-time = "2026-06-22T23:09:57.904Z" }, + { url = "https://files.pythonhosted.org/packages/61/d2/e52419afe391a39ba27fdefaf0737d8e34bf03faef6ab3b3006545bbd0d0/coverage-7.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:878832eaac515b62decfa76965aed558775f86bf1fc8cca76993c0c84ae31aed", size = 267643, upload-time = "2026-06-22T23:09:59.938Z" }, + { url = "https://files.pythonhosted.org/packages/58/7a/f2625d8d5006b6b20fba5afaef00b24a763fe96476ea798a3076cbc1f84e/coverage-7.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:611e62cb9386096d81b63e0a05330750268617231e7bd598e1fe77482a2c58a5", size = 268762, upload-time = "2026-06-22T23:10:01.943Z" }, + { url = "https://files.pythonhosted.org/packages/7d/bf/908024006bba57127354d74e938954b9c3cd765cc2e0412dc9c37b415cda/coverage-7.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:02c41de2a88011b893050fc9830267d927a50a215f7ad5ec17349db7090ccf26", size = 262208, upload-time = "2026-06-22T23:10:03.954Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/d4f9296441b909817442fdb26bd77a698f08272ec683a7394b00eb2e47a0/coverage-7.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:526ce9721116af23b1065089f0b75046fe521e7772ab94b641cd66b7a0421889", size = 265096, upload-time = "2026-06-22T23:10:05.936Z" }, + { url = "https://files.pythonhosted.org/packages/e8/da/4ae4f3f4e477b56a4ce1e5c48a35eff38a94b50130ce5bdc897024741cfc/coverage-7.14.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e4ed44705ca4bead6fc977a8b741f2145608289b33c8a9b42a95d0f15aedbf4d", size = 262699, upload-time = "2026-06-22T23:10:07.973Z" }, + { url = "https://files.pythonhosted.org/packages/d8/7a/6927148073ff32856d78baa77b4ddc07a9be7e90020f9db0661c4ca523a1/coverage-7.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2415902f385a23dcc4ccd26e0ba803249a169af6a930c003a4c715eeb9a5444e", size = 266433, upload-time = "2026-06-22T23:10:10.145Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a7/774f658dbe9c4c3f5daa86a87e0459ac3832e4e3cc67affe078547f727b9/coverage-7.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b75ee850fc2d7c831e883220c445b035f2224de2ba6103f1e56dbd237ab913f7", size = 261547, upload-time = "2026-06-22T23:10:12.191Z" }, + { url = "https://files.pythonhosted.org/packages/3d/14/a0c18c0376c43cbf973f43ef6ca20019c950597180e6396232f7b6a27102/coverage-7.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dc9b4e35e7c3920e925ba7f14886fd5fbe481232754624e832ddba66c7535635", size = 263859, upload-time = "2026-06-22T23:10:14.492Z" }, + { url = "https://files.pythonhosted.org/packages/10/ac/43a3d0f460af524b131a6191805bc5d18b806ab4e828fbf82e8c8c3af446/coverage-7.14.3-cp314-cp314t-win32.whl", hash = "sha256:7b27c822a8161afbe48e99f1adfb098d270ae7e0f7d7b0555ce110529bdb69cc", size = 223250, upload-time = "2026-06-22T23:10:16.758Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5f/d5e5c56b0712e96ce8f69fe7dbf229ff938b437bc50862743c8a0d2cea84/coverage-7.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:39e1dbbb6ff2c338e0196a482558a792a1de3aa64261196f5cdb3da016ad9cda", size = 224082, upload-time = "2026-06-22T23:10:19.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/35/947cbd5be1d3bcbbdc43d6791de8a56c6501903311d42915ae06a82815f0/coverage-7.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:68520c90babfa2d560eca6d497921ed3a4f469623bd709733124491b2aa8ef3f", size = 223400, upload-time = "2026-06-22T23:10:21.24Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e3/a0aa32bfa3a081951f60a23bc0e7b512891ef0eecda1153cf1d8ba36c6b1/coverage-7.14.3-py3-none-any.whl", hash = "sha256:fb7e18afb6e903c1a92401a2f0501ac277dca527bb9ca6fe1f691a8a0026a0e8", size = 212469, upload-time = "2026-06-22T23:10:23.405Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cvmatrix" +version = "3.2.0" +source = { editable = "." } +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] + +[package.optional-dependencies] +jax = [ + { name = "jax" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pandas" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, + { name = "typeguard" }, +] + +[package.metadata] +requires-dist = [ + { name = "jax", marker = "extra == 'jax'", specifier = ">=0.4.0" }, + { name = "numpy", specifier = ">=2.0.0,<3.0.0" }, +] +provides-extras = ["jax"] + +[package.metadata.requires-dev] +dev = [ + { name = "pandas" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, + { name = "typeguard" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jax" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaxlib" }, + { name = "ml-dtypes" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "opt-einsum" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/73/eb91d98fcadfa2cbcfdd4e417ab116e47eb20882acc5ee678e47c35d6b57/jax-0.10.2.tar.gz", hash = "sha256:bf77428a8c2e6904c4f46d5ab12aa5cfc6cad2179f07f7e4c0fc75ac86ef0639", size = 2775110, upload-time = "2026-06-17T23:44:57.818Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/82/5ab5211079a151b6f661529369c0c8e98ec64cabf5c0cf22a0a05af124d8/jax-0.10.2-py3-none-any.whl", hash = "sha256:724d73c4678d8b06f6a6ab4db1b8a2fea8cd4f1e2c2564f99601634ec7b8d1c6", size = 3219515, upload-time = "2026-06-17T23:42:41.259Z" }, +] + +[[package]] +name = "jaxlib" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ml-dtypes" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/2c/7038fc73154307389631b5b2dbe5ac529e1918eecc19a27e6644ad114bbf/jaxlib-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5a98873fc867623b81f2bee15d554b8edd6588a183d01fa50d21b1e3db96ff2b", size = 61429039, upload-time = "2026-06-17T23:43:44.858Z" }, + { url = "https://files.pythonhosted.org/packages/66/c6/d69a0a33046f84930b89387861c061996d5207671b35080898679ca9960a/jaxlib-0.10.2-cp311-cp311-manylinux_2_27_aarch64.whl", hash = "sha256:d44565dcfd1b4f60f76d911c6512118a8a4fc764bdef92663fecb8bfccd54f23", size = 81079180, upload-time = "2026-06-17T23:43:48.245Z" }, + { url = "https://files.pythonhosted.org/packages/e2/27/fb54e3265c0ffcb687f93e9fb761c589acebbe958c3fed1b2c74c3f0e782/jaxlib-0.10.2-cp311-cp311-manylinux_2_27_x86_64.whl", hash = "sha256:1faca3c5d4662cb4a6130a68105d68bb520764817e165d6eebfd6786c0d1f30f", size = 85448560, upload-time = "2026-06-17T23:43:51.724Z" }, + { url = "https://files.pythonhosted.org/packages/21/bc/31fbb3d892c3cb97c73af9226eca63d60d8e224017145bdb6871d1d24da6/jaxlib-0.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:e7a9214e6b0b9e0825d905573d1bbf2253c20e9d7464a63e085b60519975553f", size = 65867603, upload-time = "2026-06-17T23:43:54.939Z" }, + { url = "https://files.pythonhosted.org/packages/ca/93/ee9cc8743191544f65d26ab7eeb82d65968fe60905662d1a5554d056654b/jaxlib-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47bb7c011515ea862be7e8313f40f9c56cbec09dc98a0fcb5016785fcd454c01", size = 61434612, upload-time = "2026-06-17T23:43:57.808Z" }, + { url = "https://files.pythonhosted.org/packages/11/06/8cc36021bf74d617c312eeed94c280282bb1bcbb32b63f2a42b10ae41575/jaxlib-0.10.2-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:53b72977ae582c03a9e8e1cdee1efbf8ebc1418270965b0e69eade57acf40331", size = 81085366, upload-time = "2026-06-17T23:44:01.067Z" }, + { url = "https://files.pythonhosted.org/packages/48/17/38b718af2353dba7753300871e83fbb64a88a772e12727ae27373ab675ce/jaxlib-0.10.2-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:fe88ec443714c4379968b6c109f9fa617c7ad19b802828e4d7bf861cd66da4b7", size = 85467828, upload-time = "2026-06-17T23:44:04.238Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c2/d41d13826ebdfe62e56cd87ba70fab3bb9fcbea4a6c9086739a91667e5bf/jaxlib-0.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:4b08f5fbc596b83f76308181863996f93d901d1f09cfd4e130a65c1998e1b371", size = 65900139, upload-time = "2026-06-17T23:44:07.476Z" }, + { url = "https://files.pythonhosted.org/packages/c2/68/eaa4cebe253359196a8e80a33b242959e27d8d2a6ae3d09339f21da2acb8/jaxlib-0.10.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4df530afa354a22dc1747a5d560640450cbb895d49889338a3f58c76a4c76c8e", size = 61434805, upload-time = "2026-06-17T23:44:10.511Z" }, + { url = "https://files.pythonhosted.org/packages/25/c1/4b884ea5962b6beb3c0f93742db54246bbf8b3274e48b0aca47908e454be/jaxlib-0.10.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:45b28b0238697ab74bbcf20411aafb6db42acc31836cc2fd711e5cf056bf9556", size = 81084260, upload-time = "2026-06-17T23:44:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/4ee28c65861605945223145fbcd3c9362ec2255ddf7d917574e205548c82/jaxlib-0.10.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:9e4818b4a8756fd3918766ca2aa5342125809f4f08a6fe46026d4386e7c23644", size = 85467706, upload-time = "2026-06-17T23:44:17.471Z" }, + { url = "https://files.pythonhosted.org/packages/79/54/9918b0f77a25a1299818c0610305ca2bea38ed90584f4489b60357e2dd39/jaxlib-0.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:c75d6f1df1c9cff08e110b4a21c79560fdc502f4288972d6b117d25dafd44352", size = 65897894, upload-time = "2026-06-17T23:44:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/56/5b/70df11da52a8b1a826184cccc05a3fec8aed76058a980021873fba3069cb/jaxlib-0.10.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4c202d8ff7c1f3b5049dbd8f1e30e52759cd4e0a5835f0b3c7ae076a05818e28", size = 61564746, upload-time = "2026-06-17T23:44:24.421Z" }, + { url = "https://files.pythonhosted.org/packages/23/5c/184a648ea5db6c8b1a08fc5784c157b4c557255e009fb56091393df3c6de/jaxlib-0.10.2-cp313-cp313t-manylinux_2_27_aarch64.whl", hash = "sha256:b7b029bb95d981566750475b9719a9d6b66ed5dd2748851667899b6cfe075299", size = 81204888, upload-time = "2026-06-17T23:44:27.57Z" }, + { url = "https://files.pythonhosted.org/packages/6c/5c/539596a55265711d74147913278bcdc38412980be7d74d9c9d860297c486/jaxlib-0.10.2-cp313-cp313t-manylinux_2_27_x86_64.whl", hash = "sha256:e8b126097d609b0c6e6786e89f6dd6978adc02ebd5f63a1c61293fbac7821305", size = 85583810, upload-time = "2026-06-17T23:44:30.962Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0d/27471ec9f1d04674f6e62de809412371e097aed3eca7d9483e677c54c214/jaxlib-0.10.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:72eba28b12fee02616fa42aa4b881b4ab62d7757c7843c462401d3fb34a27be4", size = 61446097, upload-time = "2026-06-17T23:44:34.196Z" }, + { url = "https://files.pythonhosted.org/packages/af/c8/941a7f7f37510f51290a5bd1a413aeef977fb8ba8adc0cfe8391233a764c/jaxlib-0.10.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:f18f56fee90699cfba9b6627045a7a299702cb0e2af82ce180d9a6a7c8048093", size = 81096546, upload-time = "2026-06-17T23:44:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/69/77/ac054882c220872512df28d16aeb648fe0e651efbb5be4fd7c4817fd88b0/jaxlib-0.10.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:ca34f363197fb0ac4082582ca755007910369e33f8a8ba3d35ed94b71070107d", size = 85472993, upload-time = "2026-06-17T23:44:40.904Z" }, + { url = "https://files.pythonhosted.org/packages/0d/7d/c592d1fa69c210be0d2743fffc598dfc2f54efa9671c5f6f5d1e151c6f4a/jaxlib-0.10.2-cp314-cp314-win_amd64.whl", hash = "sha256:99818b0a18adc0b899abf4873795e8d65169441d87ab2e5cbb228e73d0f25808", size = 68376553, upload-time = "2026-06-17T23:44:44.968Z" }, + { url = "https://files.pythonhosted.org/packages/54/9b/91b00ec74985d29708b50420b4103c1f651c8f1c253d4fcb49d1bbb532cd/jaxlib-0.10.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fc62997fce8831819551a2a5469a818169b09582b5b648c102d11ac7205bb812", size = 61564620, upload-time = "2026-06-17T23:44:48.217Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c7/49d2b19c3b3105c30e1d3af2062e82e1977fb239d3dc3cbb583ef676dda7/jaxlib-0.10.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:a24d6e3cba263978293eae8b41330d5ccf24d6cdd1a6bcd4e82aff34e767620d", size = 81206365, upload-time = "2026-06-17T23:44:51.419Z" }, + { url = "https://files.pythonhosted.org/packages/bf/99/006cedf443f4a01f2088651facce79b2105bfb4905bfe9162eb0920a6dfb/jaxlib-0.10.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:5a2ac7aed7c4e661f67600bbcdec9e589151c1efec91f4cdb8d484af1a45c895", size = 85584458, upload-time = "2026-06-17T23:44:55.377Z" }, +] + +[[package]] +name = "ml-dtypes" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/5e/712092cfe7e5eb667b8ad9ca7c54442f21ed7ca8979745f1000e24cf8737/ml_dtypes-0.5.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6c7ecb74c4bd71db68a6bea1edf8da8c34f3d9fe218f038814fd1d310ac76c90", size = 679734, upload-time = "2025-11-17T22:31:39.223Z" }, + { url = "https://files.pythonhosted.org/packages/4f/cf/912146dfd4b5c0eea956836c01dcd2fce6c9c844b2691f5152aca196ce4f/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc11d7e8c44a65115d05e2ab9989d1e045125d7be8e05a071a48bc76eb6d6040", size = 5056165, upload-time = "2025-11-17T22:31:41.071Z" }, + { url = "https://files.pythonhosted.org/packages/a9/80/19189ea605017473660e43762dc853d2797984b3c7bf30ce656099add30c/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19b9a53598f21e453ea2fbda8aa783c20faff8e1eeb0d7ab899309a0053f1483", size = 5034975, upload-time = "2025-11-17T22:31:42.758Z" }, + { url = "https://files.pythonhosted.org/packages/b4/24/70bd59276883fdd91600ca20040b41efd4902a923283c4d6edcb1de128d2/ml_dtypes-0.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:7c23c54a00ae43edf48d44066a7ec31e05fdc2eee0be2b8b50dd1903a1db94bb", size = 210742, upload-time = "2025-11-17T22:31:44.068Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c9/64230ef14e40aa3f1cb254ef623bf812735e6bec7772848d19131111ac0d/ml_dtypes-0.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:557a31a390b7e9439056644cb80ed0735a6e3e3bb09d67fd5687e4b04238d1de", size = 160709, upload-time = "2025-11-17T22:31:46.557Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b8/3c70881695e056f8a32f8b941126cf78775d9a4d7feba8abcb52cb7b04f2/ml_dtypes-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a174837a64f5b16cab6f368171a1a03a27936b31699d167684073ff1c4237dac", size = 676927, upload-time = "2025-11-17T22:31:48.182Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/428ef6881782e5ebb7eca459689448c0394fa0a80bea3aa9262cba5445ea/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7f7c643e8b1320fd958bf098aa7ecf70623a42ec5154e3be3be673f4c34d900", size = 5028464, upload-time = "2025-11-17T22:31:50.135Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cb/28ce52eb94390dda42599c98ea0204d74799e4d8047a0eb559b6fd648056/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ad459e99793fa6e13bd5b7e6792c8f9190b4e5a1b45c63aba14a4d0a7f1d5ff", size = 5009002, upload-time = "2025-11-17T22:31:52.001Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f0/0cfadd537c5470378b1b32bd859cf2824972174b51b873c9d95cfd7475a5/ml_dtypes-0.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:c1a953995cccb9e25a4ae19e34316671e4e2edaebe4cf538229b1fc7109087b7", size = 212222, upload-time = "2025-11-17T22:31:53.742Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/9acc86985bfad8f2c2d30291b27cd2bb4c74cea08695bd540906ed744249/ml_dtypes-0.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:9bad06436568442575beb2d03389aa7456c690a5b05892c471215bfd8cf39460", size = 160793, upload-time = "2025-11-17T22:31:55.358Z" }, + { url = "https://files.pythonhosted.org/packages/d9/a1/4008f14bbc616cfb1ac5b39ea485f9c63031c4634ab3f4cf72e7541f816a/ml_dtypes-0.5.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c760d85a2f82e2bed75867079188c9d18dae2ee77c25a54d60e9cc79be1bc48", size = 676888, upload-time = "2025-11-17T22:31:56.907Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b7/dff378afc2b0d5a7d6cd9d3209b60474d9819d1189d347521e1688a60a53/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce756d3a10d0c4067172804c9cc276ba9cc0ff47af9078ad439b075d1abdc29b", size = 5036993, upload-time = "2025-11-17T22:31:58.497Z" }, + { url = "https://files.pythonhosted.org/packages/eb/33/40cd74219417e78b97c47802037cf2d87b91973e18bb968a7da48a96ea44/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:533ce891ba774eabf607172254f2e7260ba5f57bdd64030c9a4fcfbd99815d0d", size = 5010956, upload-time = "2025-11-17T22:31:59.931Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8b/200088c6859d8221454825959df35b5244fa9bdf263fd0249ac5fb75e281/ml_dtypes-0.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:f21c9219ef48ca5ee78402d5cc831bd58ea27ce89beda894428bc67a52da5328", size = 212224, upload-time = "2025-11-17T22:32:01.349Z" }, + { url = "https://files.pythonhosted.org/packages/8f/75/dfc3775cb36367816e678f69a7843f6f03bd4e2bcd79941e01ea960a068e/ml_dtypes-0.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:35f29491a3e478407f7047b8a4834e4640a77d2737e0b294d049746507af5175", size = 160798, upload-time = "2025-11-17T22:32:02.864Z" }, + { url = "https://files.pythonhosted.org/packages/4f/74/e9ddb35fd1dd43b1106c20ced3f53c2e8e7fc7598c15638e9f80677f81d4/ml_dtypes-0.5.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:304ad47faa395415b9ccbcc06a0350800bc50eda70f0e45326796e27c62f18b6", size = 702083, upload-time = "2025-11-17T22:32:04.08Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/667060b0aed1aa63166b22897fdf16dca9eb704e6b4bbf86848d5a181aa7/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a0df4223b514d799b8a1629c65ddc351b3efa833ccf7f8ea0cf654a61d1e35d", size = 5354111, upload-time = "2025-11-17T22:32:05.546Z" }, + { url = "https://files.pythonhosted.org/packages/40/49/0f8c498a28c0efa5f5c95a9e374c83ec1385ca41d0e85e7cf40e5d519a21/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531eff30e4d368cb6255bc2328d070e35836aa4f282a0fb5f3a0cd7260257298", size = 5366453, upload-time = "2025-11-17T22:32:07.115Z" }, + { url = "https://files.pythonhosted.org/packages/8c/27/12607423d0a9c6bbbcc780ad19f1f6baa2b68b18ce4bddcdc122c4c68dc9/ml_dtypes-0.5.4-cp313-cp313t-win_amd64.whl", hash = "sha256:cb73dccfc991691c444acc8c0012bee8f2470da826a92e3a20bb333b1a7894e6", size = 225612, upload-time = "2025-11-17T22:32:08.615Z" }, + { url = "https://files.pythonhosted.org/packages/e5/80/5a5929e92c72936d5b19872c5fb8fc09327c1da67b3b68c6a13139e77e20/ml_dtypes-0.5.4-cp313-cp313t-win_arm64.whl", hash = "sha256:3bbbe120b915090d9dd1375e4684dd17a20a2491ef25d640a908281da85e73f1", size = 164145, upload-time = "2025-11-17T22:32:09.782Z" }, + { url = "https://files.pythonhosted.org/packages/72/4e/1339dc6e2557a344f5ba5590872e80346f76f6cb2ac3dd16e4666e88818c/ml_dtypes-0.5.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2b857d3af6ac0d39db1de7c706e69c7f9791627209c3d6dedbfca8c7e5faec22", size = 673781, upload-time = "2025-11-17T22:32:11.364Z" }, + { url = "https://files.pythonhosted.org/packages/04/f9/067b84365c7e83bda15bba2b06c6ca250ce27b20630b1128c435fb7a09aa/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:805cef3a38f4eafae3a5bf9ebdcdb741d0bcfd9e1bd90eb54abd24f928cd2465", size = 5036145, upload-time = "2025-11-17T22:32:12.783Z" }, + { url = "https://files.pythonhosted.org/packages/c6/bb/82c7dcf38070b46172a517e2334e665c5bf374a262f99a283ea454bece7c/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14a4fd3228af936461db66faccef6e4f41c1d82fcc30e9f8d58a08916b1d811f", size = 5010230, upload-time = "2025-11-17T22:32:14.38Z" }, + { url = "https://files.pythonhosted.org/packages/e9/93/2bfed22d2498c468f6bcd0d9f56b033eaa19f33320389314c19ef6766413/ml_dtypes-0.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:8c6a2dcebd6f3903e05d51960a8058d6e131fe69f952a5397e5dbabc841b6d56", size = 221032, upload-time = "2025-11-17T22:32:15.763Z" }, + { url = "https://files.pythonhosted.org/packages/76/a3/9c912fe6ea747bb10fe2f8f54d027eb265db05dfb0c6335e3e063e74e6e8/ml_dtypes-0.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:5a0f68ca8fd8d16583dfa7793973feb86f2fbb56ce3966daf9c9f748f52a2049", size = 163353, upload-time = "2025-11-17T22:32:16.932Z" }, + { url = "https://files.pythonhosted.org/packages/cd/02/48aa7d84cc30ab4ee37624a2fd98c56c02326785750cd212bc0826c2f15b/ml_dtypes-0.5.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:bfc534409c5d4b0bf945af29e5d0ab075eae9eecbb549ff8a29280db822f34f9", size = 702085, upload-time = "2025-11-17T22:32:18.175Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e7/85cb99fe80a7a5513253ec7faa88a65306be071163485e9a626fce1b6e84/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2314892cdc3fcf05e373d76d72aaa15fda9fb98625effa73c1d646f331fcecb7", size = 5355358, upload-time = "2025-11-17T22:32:19.7Z" }, + { url = "https://files.pythonhosted.org/packages/79/2b/a826ba18d2179a56e144aef69e57fb2ab7c464ef0b2111940ee8a3a223a2/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d2ffd05a2575b1519dc928c0b93c06339eb67173ff53acb00724502cda231cf", size = 5366332, upload-time = "2025-11-17T22:32:21.193Z" }, + { url = "https://files.pythonhosted.org/packages/84/44/f4d18446eacb20ea11e82f133ea8f86e2bf2891785b67d9da8d0ab0ef525/ml_dtypes-0.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4381fe2f2452a2d7589689693d3162e876b3ddb0a832cde7a414f8e1adf7eab1", size = 236612, upload-time = "2025-11-17T22:32:22.579Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3f/3d42e9a78fe5edf792a83c074b13b9b770092a4fbf3462872f4303135f09/ml_dtypes-0.5.4-cp314-cp314t-win_arm64.whl", hash = "sha256:11942cbf2cf92157db91e5022633c0d9474d4dfd813a909383bd23ce828a4b7d", size = 168825, upload-time = "2025-11-17T22:32:23.766Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/49/ec46835a70be8fa6446c495126ac84fdb28cb2558e1620ffb87a10c8b64c/numpy-2.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", size = 16969194, upload-time = "2026-05-18T23:33:13.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0d/f5957185c0ee2f3e12f78715aa9e3b353fd83633316c8532b38faa37e3f6/numpy-2.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", size = 14964111, upload-time = "2026-05-18T23:33:17.795Z" }, + { url = "https://files.pythonhosted.org/packages/ad/40/40a40ee0ddf7ceb782c49af278894b686e586d65d8c1889c8b5da01a3d7d/numpy-2.4.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", size = 5469159, upload-time = "2026-05-18T23:33:20.654Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/f9a8046535cb21deae82f8d03de9617e08882d274fad2539630761888228/numpy-2.4.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", size = 6798936, upload-time = "2026-05-18T23:33:22.987Z" }, + { url = "https://files.pythonhosted.org/packages/33/a8/6fa8c1a345a8c85dbb21932c447bee07c30a2c2a3f31e369c0a84b300147/numpy-2.4.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", size = 15966692, upload-time = "2026-05-18T23:33:26.62Z" }, + { url = "https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", size = 16918164, upload-time = "2026-05-18T23:33:29.955Z" }, + { url = "https://files.pythonhosted.org/packages/c5/80/3615be3313f7e7696609bc194b9f0101da809df79e859bdb84e0cd043f46/numpy-2.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", size = 17322877, upload-time = "2026-05-18T23:33:34.724Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ac/a691e0fe2675e370d0e08ff905adc49a1c8830e8cae03efe4477e92cd55d/numpy-2.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6", size = 18651487, upload-time = "2026-05-18T23:33:38.217Z" }, + { url = "https://files.pythonhosted.org/packages/15/a7/9bc1cd626d7bf6869bfedf27b91b6ab5dd607758bf8e959d6fa80c6a59cb/numpy-2.4.6-cp311-cp311-win32.whl", hash = "sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8", size = 6233945, upload-time = "2026-05-18T23:33:41.331Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", size = 12608406, upload-time = "2026-05-18T23:33:44.131Z" }, + { url = "https://files.pythonhosted.org/packages/27/83/140f85a466595a16382996a1bf06b2b54bcd597488921b0c9daaeeda72af/numpy-2.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577", size = 10479528, upload-time = "2026-05-18T23:33:50.725Z" }, + { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, + { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, + { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, + { url = "https://files.pythonhosted.org/packages/de/12/b422cc84439adc0d00de605bf4a308890ae5c26f2c71fbd73e5d08fbb0dd/numpy-2.4.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", size = 16847511, upload-time = "2026-05-18T23:36:50.673Z" }, + { url = "https://files.pythonhosted.org/packages/44/53/f481bef68011740f8849418d82db07230e825013f31f4eef5ba5b805316a/numpy-2.4.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7", size = 14889064, upload-time = "2026-05-18T23:36:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/42ed575c10ced8af951d426bc4e1f8aff16fd851db33f067036215a7f860/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", size = 5394157, upload-time = "2026-05-18T23:36:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ef/f66cc724fcc36c1e364c67f51ae9146090b8b584f27d58b97fdae3edd737/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", size = 6708728, upload-time = "2026-05-18T23:36:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/9c/c531f2293b91265d8b48e9b329f54fdd7ffae73cb4134ea10cca4237e9cc/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", size = 15798374, upload-time = "2026-05-18T23:37:02.674Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b0/413077f6b1153ed3cba361401c6783bbad6114804a000cc22eb71c13e190/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", size = 16747286, upload-time = "2026-05-18T23:37:06.327Z" }, + { url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263, upload-time = "2026-05-18T23:37:09.715Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/05/3d27272d30698dc0ecb7fdfaa41ad70303b444f81722bb99bce1d818638a/numpy-2.5.0.tar.gz", hash = "sha256:5a129578019311b6e56bdd714250f19b518f7dceeeb8d1af5490f4942d3f891c", size = 20652461, upload-time = "2026-06-21T20:57:51.95Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/0a/11486d02add7b1384dff7374d124b1cfbb0ee864dcc9f6a2c0380638cf84/numpy-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:489780423903667933b4ed6197b6ec3b75ea5dd17d1d8f0f38d798feb6921561", size = 16789987, upload-time = "2026-06-21T20:56:16.657Z" }, + { url = "https://files.pythonhosted.org/packages/55/b2/285f48640a181947b4587a3766d21ec1eaa7fea833d4b49957e09da467a2/numpy-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ece55976ced6bca95a03ae2839e2e5ccffe8eb6a3e7022415645eb154a81e4e6", size = 11760322, upload-time = "2026-06-21T20:56:19.813Z" }, + { url = "https://files.pythonhosted.org/packages/dd/67/b032db1eb03ca30d16eda3b0c22aaa615338b9263c2fd559d0f29451aca4/numpy-2.5.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:c83b664b0e6eee9594fa920cf0639d8af796606d3fad6cc70180c87e4b97c7be", size = 5319605, upload-time = "2026-06-21T20:56:22.173Z" }, + { url = "https://files.pythonhosted.org/packages/b9/83/03fc7300c7c6b6c84c487b1dc80d322817b95fbd1f4dd57a85e23b7198de/numpy-2.5.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bf80333980bf37f523341ddd72c783f39d6829ec7736b9eb99086388a2d52cc2", size = 6653628, upload-time = "2026-06-21T20:56:23.914Z" }, + { url = "https://files.pythonhosted.org/packages/82/49/2ec21730bc63ccfda829323f7040a8ed4715b3852ce658689cf74ee96a8c/numpy-2.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1a4874217b36d5ac8fc876f52e39df56f8182c88463e9e2dceabf7ca8b7efb8", size = 15153691, upload-time = "2026-06-21T20:56:25.631Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/f4a3d0637692c49da8ef99d72d52526f92e0a8d6ac4f0ca9f31441b9d9ea/numpy-2.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaa760137137e8d3c920d27927748215b56014f92667dc9b6c27dfc61249255a", size = 16660066, upload-time = "2026-06-21T20:56:28.009Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2f/c354ec86d1f3f5c19649463b0d39652e160736e5b0a4cd18dff0576715c4/numpy-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7174ce8265fc7f7417d171c9ea8fe905220748893ea67a2a7abe726ec331c4b0", size = 16514638, upload-time = "2026-06-21T20:56:30.26Z" }, + { url = "https://files.pythonhosted.org/packages/06/34/43efdcb319988648580f93c11f1ae82cf7e2faa74925e98e454ae3aa95f8/numpy-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b8c3daaf99de52415d20b42f8e8155c78642cb04207d02f9d317a0dcf1b3fb54", size = 18419647, upload-time = "2026-06-21T20:56:32.41Z" }, + { url = "https://files.pythonhosted.org/packages/71/e2/f5d1676b1d7fb682eb5e9a1641e7ebd2414b3216c370661d1029778908b4/numpy-2.5.0-cp312-cp312-win32.whl", hash = "sha256:6206db0af545d73d068add6d992279145f158428d1da6cc49adc4b630c5d6ee5", size = 6056688, upload-time = "2026-06-21T20:56:34.657Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7c/48f115d1c58a34032facebcd51fdf2d02df2c51d4a46a81dd1197bb2ea6b/numpy-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:6f2d6873e2940c860a309d21e25b1e69af6aaffdd80aa056b04c16380db1c4f2", size = 12419237, upload-time = "2026-06-21T20:56:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/86/26/2e0882f4044d1b1a1b63e875151fb2393389032022a8b7f5657a7996d3b2/numpy-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:a55e1eb2bca2cfd17a16b213c99dfc8502d47b0d494224d2122277d0400935ca", size = 10339912, upload-time = "2026-06-21T20:56:38.733Z" }, + { url = "https://files.pythonhosted.org/packages/8a/33/07675aaad7f26ea013d5e884d9a0d784b79c6bd7566c333f5a52fa3c610b/numpy-2.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:520e6b8be0a4b65840ac8090d4f51cef4bed66e2b0894d5a520f099adc24a9b2", size = 16784890, upload-time = "2026-06-21T20:56:40.799Z" }, + { url = "https://files.pythonhosted.org/packages/85/4b/953118a730ee3b35e28645e0eb4cf9beec5bdbb954e1ac2f5fcefba6bbc3/numpy-2.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:146b81cdd3967fdb6beca8ba25f00c58741d8f3cbd797f55af0fbe0bfec3469c", size = 11754584, upload-time = "2026-06-21T20:56:43.094Z" }, + { url = "https://files.pythonhosted.org/packages/44/9b/56dd530c367c74ae17411027cea4135ca57e1e0583bf5594cee18bd83217/numpy-2.5.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:126b88d95e8ff9b00c9e717aa540469f21d6180162f84c0caec51b16215d49cd", size = 5313904, upload-time = "2026-06-21T20:56:45.503Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b0/bcd672edad27ecca7da1f7bb0ce72cd1706a4f2d79ae94990afc97c13e1c/numpy-2.5.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d4313cef1594c5ce46c31b6e54e918338f63f16ee9322304e8c9114d6d81c8bd", size = 6648504, upload-time = "2026-06-21T20:56:47.567Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/15cdfcbd30a1544a46c9e487a00df331c4672450216538705a9e51fa6710/numpy-2.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:750fb097caf26fa878746d9d119f6f9da12dedcbff1eea966c3e3447647c4a9e", size = 15150086, upload-time = "2026-06-21T20:56:49.352Z" }, + { url = "https://files.pythonhosted.org/packages/32/4e/8d7656ccaab3e81e97258b8a9bc5f0c8502513a92fb4ceb0a2cbfebc17bf/numpy-2.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3893adc2dc7c0412ba76777db55a049215d99c9aa3113003be8f49f4f1290ab9", size = 16647250, upload-time = "2026-06-21T20:56:51.542Z" }, + { url = "https://files.pythonhosted.org/packages/3c/81/97060281b602ed07f21b12f4ec409eac1f75a2f91fbc829ed8b2becf3ad4/numpy-2.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:835e454dd99b238cdc5a3f63bce2371296f5ebc53ca1e0f8e6ddbb6d92a29aab", size = 16512864, upload-time = "2026-06-21T20:56:55.401Z" }, + { url = "https://files.pythonhosted.org/packages/33/ab/4496208146911f8d8ddb54f68a972aafa6c8d44babcb2ea03b0e5cc87c9d/numpy-2.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f9836778081a0a3c02a6a21493f3e9f5b311f8d2541934f31f05583dc999ea4", size = 18408407, upload-time = "2026-06-21T20:56:57.75Z" }, + { url = "https://files.pythonhosted.org/packages/d4/9f/a4df67c181e4ee8b467aa3332dc2db10fd5c515136831302f3ca48bc0a01/numpy-2.5.0-cp313-cp313-win32.whl", hash = "sha256:0b525be4744b60bb0557ac872d53ef07d085b5f39622bc579c98d3809d05b988", size = 6054431, upload-time = "2026-06-21T20:57:00.016Z" }, + { url = "https://files.pythonhosted.org/packages/30/53/491e1c47c55b62ccc6a63c1c5b8635c73fc2258dddeb9bda27cae4a0ae96/numpy-2.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:44353e2878930039db472b99dc353d749826e4010bd4d2a7f835e94a97a5c748", size = 12414420, upload-time = "2026-06-21T20:57:01.815Z" }, + { url = "https://files.pythonhosted.org/packages/eb/4a/25c2906f541e9d9f4c5769764db732e6627be91a13f4724fa10634d77db4/numpy-2.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:48f54b00711f83a5f796b70c518e8c2b3c5848dda03a54911f23eb68519b9b60", size = 10339533, upload-time = "2026-06-21T20:57:03.961Z" }, + { url = "https://files.pythonhosted.org/packages/86/ad/abc44aaceaf7b17ee1edde2bbb4458da591bc79574cffff50c4bb35f00d1/numpy-2.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f27582c55ba4c750b7c58c8faf021d2cd9324a662b466229db8a417b41368af9", size = 16783807, upload-time = "2026-06-21T20:57:06.253Z" }, + { url = "https://files.pythonhosted.org/packages/5d/39/b72e168daf9c00fb20c9fc996d00437ccecdef3102387775d29d7a62576d/numpy-2.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:28e7137057d551e4a83c4ae414e3451f50568409db7569aacc7f9811ee06a446", size = 11765215, upload-time = "2026-06-21T20:57:08.547Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a0/8400a9c0e3625182347593f5e1f57da9a617a534794805c8df5518154ddc/numpy-2.5.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e1da54b53e75cd9fcfc23efcc7edab2c6aecf97b6037566d8a0fe804af8ec57c", size = 5324493, upload-time = "2026-06-21T20:57:11.012Z" }, + { url = "https://files.pythonhosted.org/packages/f6/8c/0d104deaa0401c93395a629ec902891618a2eff76d19229139cb5a887bfc/numpy-2.5.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:694d8f74e156f7fd01179f1aa8faa2f648ab6ae0f70b6c3fe57a03249aea2303", size = 6645211, upload-time = "2026-06-21T20:57:12.919Z" }, + { url = "https://files.pythonhosted.org/packages/6a/d9/4a4a628c812750363786afc3d33492709a5cd64b215469c16b0f6c7bb811/numpy-2.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a7569a7b53c77716f036bb28cb1c91f166a26ec7d9502cd1e4bdfe502fdec22", size = 15166004, upload-time = "2026-06-21T20:57:14.717Z" }, + { url = "https://files.pythonhosted.org/packages/a0/5e/2a902317d7fc4aa93236e80c932662dadfc459b323d758329e01775125e1/numpy-2.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a0433bd4086ebd462960cf375e19195bb07b53dc1d87dd5fcf47ad78576f03", size = 16650797, upload-time = "2026-06-21T20:57:16.906Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a0/a0090e6329f4ca5992c07847bb579c5259a19953dc57255bb08793142ffb/numpy-2.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:929f0c79ac38bcbd7154fe631dc907abfeddbcc5027a896bd1f7767323271e7a", size = 16524647, upload-time = "2026-06-21T20:57:19.165Z" }, + { url = "https://files.pythonhosted.org/packages/5e/7d/6caf27734c42b65837e7461ed0dbbd6b6fc835060c9714ec59d673bb383a/numpy-2.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cc4f247a47bbf070bfd70be53ccdcf47b800af563535e7bbe172322197c30e21", size = 18411841, upload-time = "2026-06-21T20:57:21.638Z" }, + { url = "https://files.pythonhosted.org/packages/13/dc/26edadbd812536769a82c2e9e002234e33feb5da43061d47a044f6d309b7/numpy-2.5.0-cp314-cp314-win32.whl", hash = "sha256:5dc71423499fab3f46f7a7201155ade1669ea101f2f429d332df9e72f8161731", size = 6106361, upload-time = "2026-06-21T20:57:23.844Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9e/4dd1459282229a72d92dece2ae9138e5cac94a72263a7ceb48f37434c925/numpy-2.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:ebb81d9d5443e0309d6c54894c3fbed74ad7da0714352a67b6d773cd189eae73", size = 12551749, upload-time = "2026-06-21T20:57:25.945Z" }, + { url = "https://files.pythonhosted.org/packages/05/a7/6bc6384c080b86c7f6c85c5bc5b540b24f4f679cd144791d99574e90d462/numpy-2.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:3b94d0d0deceebfad3e67ae5c0e5eb87371e8f7a0581cd04a779928c2450cf1e", size = 10617072, upload-time = "2026-06-21T20:57:28.175Z" }, + { url = "https://files.pythonhosted.org/packages/86/6b/4a2b71d66ada5608ae02b63f150dfad520f6940721cb7f029ad270befc0e/numpy-2.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:22f3d43e362d650bc39db1f17851302874a148ca95ba6981c1dfb5fa6862f35b", size = 11881067, upload-time = "2026-06-21T20:57:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b2/d365eb40a20efb49d67e9feb90494ed8511282ee1f5fa16006675c65397d/numpy-2.5.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:243563efb4cd7528a264567e9fd206c87826457322521d06206a00bfa316c927", size = 5440290, upload-time = "2026-06-21T20:57:32.193Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5e/e9c03188de5f9b767e46a8fe988bcfd3efad066a4a3fda8b9cb11a93f895/numpy-2.5.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:84881d825ca75249b189bbee875fcfe3238aa5c479e6100893cda566e8e86826", size = 6748371, upload-time = "2026-06-21T20:57:33.933Z" }, + { url = "https://files.pythonhosted.org/packages/fd/1d/68c186a38a5027bae2c4ddd5ea681fdaf8b4d30fb7301def6d8ad270390f/numpy-2.5.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cda12aa4779d42b8771180aba759c96f527d43446d8f380ab59e2b35e8489efd", size = 15214643, upload-time = "2026-06-21T20:57:35.677Z" }, + { url = "https://files.pythonhosted.org/packages/8c/67/73f67b7c7e20635baae9c4c3ead4ae7326a005900297a6110971abd62eb5/numpy-2.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c0121101093d2bd74981b10f8837d78e794a8ff57834eb27179f49e1ba11ac6", size = 16690128, upload-time = "2026-06-21T20:57:38.159Z" }, + { url = "https://files.pythonhosted.org/packages/eb/05/d4c1fb0c46d02a27d6b2b8b319a78c90937acec8631c1641874670b31e6f/numpy-2.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d371c92cfa09da00022f501ab67fafaea813d752eb30ac44336d45b1e5b0268a", size = 16577902, upload-time = "2026-06-21T20:57:40.447Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1d/771c797d50fa26e4888989cccf1d50ee51f530d4e455ad2692dcb64fa711/numpy-2.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9990713e9c38154c6861e7547f1e3fc7a87e75ff09bab24ef1cc81d81c2835e9", size = 18452814, upload-time = "2026-06-21T20:57:42.875Z" }, + { url = "https://files.pythonhosted.org/packages/e8/46/52fc0d2a68d7643f0f149eeea5a5d8ea2a3507056ac8afa83c9212606e8b/numpy-2.5.0-cp314-cp314t-win32.whl", hash = "sha256:edadfbd4794b1086c0d822f81863e8a68fc129d132fd0bb9e31e955d7fbbbdb7", size = 6253168, upload-time = "2026-06-21T20:57:45.101Z" }, + { url = "https://files.pythonhosted.org/packages/2a/be/6c8d1118b5f13b2881dc095d5b345de19c6638b8959c17409b6eff84c8aa/numpy-2.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f7e5fa4382967ae6548bd2f174219afb908e294b0d5f625af01166edd5f7d9aa", size = 12736286, upload-time = "2026-06-21T20:57:46.935Z" }, + { url = "https://files.pythonhosted.org/packages/fd/6a/d3a169aaf8536cf228d56a09e04bcb713a2fe4410d4e2105b9419b5a9c89/numpy-2.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:016623417bb330d719d579daf2d6b9a01ddc52e41a9ed61a47f39fde46dcd865", size = 10686451, upload-time = "2026-06-21T20:57:49.313Z" }, +] + +[[package]] +name = "opt-einsum" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/b9/2ac072041e899a52f20cf9510850ff58295003aa75525e58343591b0cbfb/opt_einsum-3.4.0.tar.gz", hash = "sha256:96ca72f1b886d148241348783498194c577fa30a8faac108586b14f1ba4473ac", size = 63004, upload-time = "2024-09-26T14:33:24.483Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/cd/066e86230ae37ed0be70aae89aabf03ca8d9f39c8aea0dec8029455b5540/opt_einsum-3.4.0-py3-none-any.whl", hash = "sha256:69bb92469f86a1565195ece4ac0323943e83477171b91d24c35afe028a90d7cd", size = 71932, upload-time = "2024-09-26T14:33:23.039Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/16/b5c76b838fd9bf6ce84d3a53346b8874ec05c5f0040d75ef2c320100cd2a/pandas-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:455f6f8139d4282188f526868dbc3c828470e88a3d9d59a891bd46a455f21b98", size = 10338495, upload-time = "2026-05-11T18:52:11.558Z" }, + { url = "https://files.pythonhosted.org/packages/5a/b0/a4ffc4ae74d2d822200dcc46898987d8eb6032d1e2b219cae39da6f5cbcc/pandas-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4e15135e2ee5df1063313e2425ceef8ac0f4ae775893815b0923651b806a5639", size = 9938250, upload-time = "2026-05-11T18:52:17.005Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b2/3323601a52caee42c019e370090ca4544b241437240ca04f786cce82b0cf/pandas-3.0.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05f1f1752b8533ea03f7f39a9c15b1a058d067bb48f4748948e7a8691e0510f2", size = 10770558, upload-time = "2026-05-11T18:52:19.865Z" }, + { url = "https://files.pythonhosted.org/packages/32/f1/bbecd2f867b97abebe0f9b53d750f862251b40337e061b36676ded3d920f/pandas-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a1e45c80cceb3b4a21bc5939d52e8cbd8d9b7305309219d59e9754d9ce09e27", size = 11274611, upload-time = "2026-05-11T18:52:22.622Z" }, + { url = "https://files.pythonhosted.org/packages/7f/4f/eafabf2d5fae5adf143b4d18d3706c5efdc368a7c4eb1ee8a3eddabbd0f6/pandas-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:14da8316da4d0c5a77618425996bfb1248ca87fc2c1486e6fde4652bd18b5824", size = 11784670, upload-time = "2026-05-11T18:52:25.4Z" }, + { url = "https://files.pythonhosted.org/packages/49/44/1eb20389301b57b19cc099a1c2f662501f72f08a65f912d05822613c1532/pandas-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a55066a0505dae0ba2b50a46637db34b46f9094c65c5d4800794ef6335010938", size = 12353708, upload-time = "2026-05-11T18:52:28.139Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/c321f13b5ba1819fc8dca456c7fce578da2dcfecff1abbf0eaddf8406c0f/pandas-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6674ab18ad8c57802867264b00e15e7bb904700cdd9046e3b2fa1fce237439ea", size = 9907609, upload-time = "2026-05-11T18:52:30.982Z" }, + { url = "https://files.pythonhosted.org/packages/53/85/1b7f563ebc6357c27233a02a96b589bcce1fa9c6eb89fb4f0e56421d277e/pandas-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:5cc09a68b3120e0f54870dede8287a7bb1fa463907e4fcec1ea77cab6179bf7a", size = 9165596, upload-time = "2026-05-11T18:52:33.334Z" }, + { url = "https://files.pythonhosted.org/packages/24/f1/392f8c5bfc16f66a0d2d41561c01627c228fe7ed2a0d056ef11315042570/pandas-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09", size = 10357846, upload-time = "2026-05-11T18:52:36.143Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3d/b16412745651e855f357e5e66930248688378853a6e2698a214e331fba1f/pandas-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4", size = 9899550, upload-time = "2026-05-11T18:52:38.976Z" }, + { url = "https://files.pythonhosted.org/packages/31/a8/fa2535168fffcedf67f4f6de28d2dd903a747ca7c8ea6989451aaeb3a92f/pandas-3.0.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c", size = 10412965, upload-time = "2026-05-11T18:52:41.915Z" }, + { url = "https://files.pythonhosted.org/packages/65/b6/09b01cdbc15224e2850365192d17b7bdebb8bdbd8780ed221fcdf0d9a515/pandas-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9", size = 10894600, upload-time = "2026-05-11T18:52:45.02Z" }, + { url = "https://files.pythonhosted.org/packages/c9/a4/2eb28f2fccb4ced4a2c79ab2a5dee9ade1ebf44922ebad6fea158c9f95d4/pandas-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf", size = 11422824, upload-time = "2026-05-11T18:52:48.058Z" }, + { url = "https://files.pythonhosted.org/packages/f8/45/830bb57f533a4604b355e07edcb8ea18cf88b5f94e5fca92f27052d7c597/pandas-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c", size = 11950889, upload-time = "2026-05-11T18:52:50.905Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c5/fc1b368f303087d20e8c9bf3d6ceb186263cfac0ade735cd938538bea839/pandas-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc", size = 9755463, upload-time = "2026-05-11T18:52:53.386Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/fda8f9705b1b09c6ebe14bfc0fa0e4ec8584d54ea673628f157ff55131af/pandas-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49", size = 9066158, upload-time = "2026-05-11T18:52:56.038Z" }, + { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" }, + { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" }, + { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" }, + { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" }, + { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" }, + { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" }, + { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" }, + { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" }, + { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" }, + { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" }, + { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" }, + { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" }, + { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" }, + { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" }, + { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" }, + { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" }, + { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" }, + { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, + { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, + { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, + { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, + { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", size = 31613675, upload-time = "2026-02-23T00:16:00.13Z" }, + { url = "https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", size = 28162057, upload-time = "2026-02-23T00:16:09.456Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", size = 20334032, upload-time = "2026-02-23T00:16:17.358Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e6/cef1cf3557f0c54954198554a10016b6a03b2ec9e22a4e1df734936bd99c/scipy-1.17.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", size = 22709533, upload-time = "2026-02-23T00:16:25.791Z" }, + { url = "https://files.pythonhosted.org/packages/4d/60/8804678875fc59362b0fb759ab3ecce1f09c10a735680318ac30da8cd76b/scipy-1.17.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", size = 33062057, upload-time = "2026-02-23T00:16:36.931Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", size = 35349300, upload-time = "2026-02-23T00:16:49.108Z" }, + { url = "https://files.pythonhosted.org/packages/b4/3d/7ccbbdcbb54c8fdc20d3b6930137c782a163fa626f0aef920349873421ba/scipy-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", size = 35127333, upload-time = "2026-02-23T00:17:01.293Z" }, + { url = "https://files.pythonhosted.org/packages/e8/19/f926cb11c42b15ba08e3a71e376d816ac08614f769b4f47e06c3580c836a/scipy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", size = 37741314, upload-time = "2026-02-23T00:17:12.576Z" }, + { url = "https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", size = 36607512, upload-time = "2026-02-23T00:17:23.424Z" }, + { url = "https://files.pythonhosted.org/packages/68/7f/bdd79ceaad24b671543ffe0ef61ed8e659440eb683b66f033454dcee90eb/scipy-1.17.1-cp311-cp311-win_arm64.whl", hash = "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", size = 24599248, upload-time = "2026-02-23T00:17:34.561Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, + { url = "https://files.pythonhosted.org/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017, upload-time = "2026-02-23T00:18:21.502Z" }, + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682, upload-time = "2026-02-23T00:19:07.67Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340, upload-time = "2026-02-23T00:19:12.024Z" }, + { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, + { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, + { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, + { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, + { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, + { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, + { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, + { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, + { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, + { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, + { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, + { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, +] + +[[package]] +name = "scipy" +version = "1.18.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/19/ca10ead60b0acc80b2b833c2c4a4f2ff753d0f58b811f70d911c7e94a25c/scipy-1.18.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:7bd21faaf5a1a3b2eff922d02db5f191b99a6518db9078a8fb23169f6d22259a", size = 31056519, upload-time = "2026-06-19T14:59:45.203Z" }, + { url = "https://files.pythonhosted.org/packages/96/72/1e6442a00cd2924d361aa1b642ab6373ec35c6fabf311a760be9f76e0f13/scipy-1.18.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:265915e79107de9f946b855e50d7470d5893ec3f54b342e1aa6201cbdcd8bb6b", size = 28681889, upload-time = "2026-06-19T14:59:48.103Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2d/11dd93d21e147a73ba22bd75c0b9208d3a2e0ec76d53170ce7d9029b1015/scipy-1.18.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9ab7b758be6940954a713ee466e2043e9f6e2ed965c1fce5c91039f4be3d90a9", size = 20423580, upload-time = "2026-06-19T14:59:50.665Z" }, + { url = "https://files.pythonhosted.org/packages/9c/01/93552f75e0d2a7dd115a45e59209c51e8d514daff02fc887d2623be06fe1/scipy-1.18.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:97b6cddaaee0a779ef6b5ca83c9604b27cc16b2b8fc22c142652df8793319fb8", size = 23054441, upload-time = "2026-06-19T14:59:53.564Z" }, + { url = "https://files.pythonhosted.org/packages/3c/23/21f5e703643d66f21faa6b4c73195bfcad70c55efcb4f1ab327cd7c4101a/scipy-1.18.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:52a96e21517c7292375c0e27dd796a811f03fcea5fd4d108fdfea8145dcf17ab", size = 33968720, upload-time = "2026-06-19T14:59:56.415Z" }, + { url = "https://files.pythonhosted.org/packages/dd/aa/1b939f6c67ed68635bb538e6752d3dacc02f66535182e939a89581a44e9c/scipy-1.18.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f55797419e16e7f30cf88ffb3113ce0467f00cfe3f70d5c281730b21769bfc2", size = 35287115, upload-time = "2026-06-19T14:59:59.411Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ff/eec46be7e9234208f801062b53e1983085eddebd693f6c9bfb03b459830d/scipy-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ad033410e2e0672ffdc1042110cef20e1c46f8fd0616cee1d44d8d58fad8fc11", size = 35577989, upload-time = "2026-06-19T15:00:02.235Z" }, + { url = "https://files.pythonhosted.org/packages/84/ca/210d4759c7210bb7d269437421959b39a33434e2776b60c5cb8a763bb30a/scipy-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a55985d54c769c872e64b7f4c8a81cc30ef700cc04296abbbf3705439c126de", size = 37421717, upload-time = "2026-06-19T15:00:05.102Z" }, + { url = "https://files.pythonhosted.org/packages/2b/54/9a9edb45345bd6744da5ddfb6628e5d5185920494c6a67ec45b6381004cb/scipy-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:71ccc8faa2dd16ac310233203474a8b5cb67f10dedd54a3116d34943f4b19132", size = 36597428, upload-time = "2026-06-19T15:00:08.112Z" }, + { url = "https://files.pythonhosted.org/packages/99/0e/33f32a2a58987e26aec0f7df252cbbad1e90ae77bdbc76f40dd4ed0cf0ea/scipy-1.18.0-cp312-cp312-win_arm64.whl", hash = "sha256:d88363fd9d8fbd3511bd273f1a49efb2a540773ddf92a91d57498ce7dd7f3e76", size = 24351481, upload-time = "2026-06-19T15:00:11.103Z" }, + { url = "https://files.pythonhosted.org/packages/05/52/9c0136c2de7ae0779b7b366447766cec6d9f0702c56bb8ffeb04c8fd3af4/scipy-1.18.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:09143f676d157d9f546d663504ef9c1becb819824f1afc018814176411942446", size = 31036107, upload-time = "2026-06-19T15:00:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/02/73/0291a64843270f4efb86cdcf2ee0f2048631b65ec6b405398b2b4dbf11bf/scipy-1.18.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5efe260f69417b97ddae455bfb5a95e8359f7f66ad7fa9522a60feb66f169520", size = 28663303, upload-time = "2026-06-19T15:00:16.819Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0f/10ffa0b697a572f4e0d48b92a88895d366422f019f723e7e14a84c050dac/scipy-1.18.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:68363b7eaacd8b5dd426df56d782cc156468ac79a127a1b87ca597d6e2e82197", size = 20404960, upload-time = "2026-06-19T15:00:19.635Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d2/e896cea21ba8edd6c81d4c55b1ffcc717e79698dcbebf9641b4cfb4c6622/scipy-1.18.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:c5557d8be5da8e41353fcd4d21491fdbab83b062fc579e94dc09a7c8ab4f669b", size = 23034074, upload-time = "2026-06-19T15:00:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b2/e83ea34279a52c03374477c74006256ec78df65fc877baa4617d6de1d202/scipy-1.18.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0d13bca67c096d89fb95ced0d8921807300fce0275643aef9533cc63a0773468", size = 33942038, upload-time = "2026-06-19T15:00:24.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/af/e8fe5fb136f51e2b01678b92cb4106d10d8cd68ec147ead2e7cb0ac75398/scipy-1.18.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a46f9273dbd0eb1cefba61c9b8648b4dfe3cbc14a080176f9a73e44b8336dc7f", size = 35266390, upload-time = "2026-06-19T15:00:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/3a/49/2c5cbb907b56695fc67517811d1db234dfd83381a84814ec220aded2794d/scipy-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5aba46108853ddfc77906b6557aac839d2b52e900c1d72a1180adaaab58d265f", size = 35551324, upload-time = "2026-06-19T15:00:31.014Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/eda39f7a2d306ff0ffc574afd13c0bbb6d10a603d9a413998ee269487a80/scipy-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b6f758e35f12757b5d95c00bc6de2438e229c2664b7a92e96f205959d9f2dfa4", size = 37404785, upload-time = "2026-06-19T15:00:34.072Z" }, + { url = "https://files.pythonhosted.org/packages/b7/d2/ae881ee28d014f38e0ccbfd974a06a919ba9af34f1f74bf42b5301891d63/scipy-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1afac4a847207c7ff8efd321734a50b06d0280b3b2a2c0fc2f413101747ad7c7", size = 36554943, upload-time = "2026-06-19T15:00:36.903Z" }, + { url = "https://files.pythonhosted.org/packages/70/3a/21154e2d54eb3639c6bf4dbae2e531c68356bfe95990daa30df33b30d556/scipy-1.18.0-cp313-cp313-win_arm64.whl", hash = "sha256:c5dbddf60e58c2312316d097271a8e73d40eaf2eabfa4d95ed7d3695bbf2ce7b", size = 24350911, upload-time = "2026-06-19T15:00:40.062Z" }, + { url = "https://files.pythonhosted.org/packages/78/b5/915a19b3de2f7430062b509653563db1633ddbb6f021b06731521115d4e2/scipy-1.18.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4c256ee70c0d1a8a2ace807e199ccd4e3f57037433842abb3fb36bc17eaa9578", size = 31036253, upload-time = "2026-06-19T15:00:43.216Z" }, + { url = "https://files.pythonhosted.org/packages/d7/88/b72def7262e150d16be13fca37a96481138d624e700340bc3362a7588929/scipy-1.18.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:2ef3abc54a4ffc53765374b0d5728532dfdd2585ed23f6b11c206a1f0b1b9af8", size = 28673758, upload-time = "2026-06-19T15:00:46.663Z" }, + { url = "https://files.pythonhosted.org/packages/91/02/2e636a61a525632c373cf6a9c24442a3ffb79e364d38e98b32042964ac32/scipy-1.18.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2a6af57bd9e4a75d70e4117e78a1bbee84f79ae3fbb6d0111005d6ebcc4cb8d", size = 20415514, upload-time = "2026-06-19T15:00:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/2135974442f6aba159d9d39d774a1c8cb19947016725d69fecc685df45bf/scipy-1.18.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:3f1ac564d3bf6c03d861d2cd87a1bea0da2887136f7fb1bf519c05a8971452d6", size = 23034398, upload-time = "2026-06-19T15:00:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e6/ba89ec5abf6ee9257c0d1ec985573f3ae32742c24bc03e016388a40b1b15/scipy-1.18.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40395a5fcd1abee49a5c7aaa98c29db393eedc835138560a588c47ec16156690", size = 33998032, upload-time = "2026-06-19T15:00:54.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/bc41eb19b0fd0db868f4132920879019318d80cc522ad8f2bca4611af808/scipy-1.18.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ca01e8ae69f1b18e9a58d91afead31be3cef0dd905a10249dac559ee15460a0", size = 35283333, upload-time = "2026-06-19T15:00:58.152Z" }, + { url = "https://files.pythonhosted.org/packages/53/a4/cbdeef6eb3830a8462a9d4ada814de5fc984345cc9ecf17cbec51a036f1e/scipy-1.18.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7a7f3b01647384dbc3a711e8c6778e0aabbe93959249fef5c7393396bcac0867", size = 35610216, upload-time = "2026-06-19T15:01:01.155Z" }, + { url = "https://files.pythonhosted.org/packages/80/4d/b2b82502b65f661d1b789c1665dcdf315d5f12194e06fc0b37946294ebae/scipy-1.18.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6aa94e78ec192a30063a5e72e561c28af769dc311190b24fe91774eff1969709", size = 37418960, upload-time = "2026-06-19T15:01:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/902d836831474b0ab5a37d16404f7bc5fafd9efba632890e271ba952635f/scipy-1.18.0-cp314-cp314-win_amd64.whl", hash = "sha256:2d8bbdc6c817f5b4006a54d799d4f5bab6f910193cbb9a1ff310833d4d270f61", size = 37288845, upload-time = "2026-06-19T15:01:07.822Z" }, + { url = "https://files.pythonhosted.org/packages/b6/43/8d73b337a3bdb14daa0314f0434210747c02d79d729ce1777574a817dcf6/scipy-1.18.0-cp314-cp314-win_arm64.whl", hash = "sha256:18e9575f1569b2c54174e6159d32942e03731177f63dce7975f0a0c88d102f5b", size = 24988971, upload-time = "2026-06-19T15:01:11.076Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b4/f11918b0508a2787031a0499a03fbe3546f3bb5ca05d01038c45b278c09a/scipy-1.18.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f351e0dd702687d12a402b867a1b4146a256923e1c38317cbc472f6372b94707", size = 31399325, upload-time = "2026-06-19T15:01:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d1/1f287b57c0ff0ee5185dff3946d92c8017d39b0e431f0ae79a3ff1859512/scipy-1.18.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7c7a51b33ce387193c97f228320cf8e87361daa1bba750638677729598b3e677", size = 29092110, upload-time = "2026-06-19T15:01:16.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1a/7b74eb6c392fdcb27d414c0e7558a6d0231eb3b6d73571f479bb81ea8794/scipy-1.18.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:84031d7b052a54fae2f8632e0ec802073d385476eb9a63079bce6e23ef9283d4", size = 20833811, upload-time = "2026-06-19T15:01:20.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ad/f3941716320a7b9cb4d68734a903b45fe16eff5fb7da7e16f2e619304979/scipy-1.18.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:56abf29a7c067dde59be8b9a22d606a4ea1b2f2a4b756d9d903c62818f5dacce", size = 23396644, upload-time = "2026-06-19T15:01:23.364Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/1446b62ffe07f9719b7d9b1b6a4e05a772833ae8f441fe4c22c34c9b250f/scipy-1.18.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ad44305cfa24b1ba5803cbbebf033590ccbac1aa5d612d727b785325ab408b0", size = 34079318, upload-time = "2026-06-19T15:01:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/b87da667098bb470fa30c7011b0ba351ee976dd395c78798c66e941665a3/scipy-1.18.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945c1761b93f38d7f99ae81ae80c63e621471608c7eeead563f6df025585cd58", size = 35324320, upload-time = "2026-06-19T15:01:28.881Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a1/c7932f91909759b0267f75fdea34e91309f96b895757534b76a90b6b4344/scipy-1.18.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a4441f15d620578772a49e5ab48c0ee1f7a0220e387110283062729136b2553", size = 35699541, upload-time = "2026-06-19T15:01:31.968Z" }, + { url = "https://files.pythonhosted.org/packages/f7/86/5185061a1fcc41d18c5dc2463969b3a3964b31d9ac67b2fb05d4c7ff7670/scipy-1.18.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9aac6192fac56bf2ca534389d24623f07b39ff83317d58287285e7fbd622ff76", size = 37472480, upload-time = "2026-06-19T15:01:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/31/8e/f04c68e39919a010d34f2ee1367fd705b0a25a02f609d755f0bfbc0a15fc/scipy-1.18.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e40baea28ae7f5475c779741e2d90b1247c78531207b49c7030e698ff81cee3f", size = 37365390, upload-time = "2026-06-19T15:01:38.091Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typeguard" +version = "4.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/1c/dfba5c4633cafc4c701f237d2ba63b416805047fd6d96aab4cfc40969f98/typeguard-4.5.2.tar.gz", hash = "sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423", size = 80240, upload-time = "2026-05-14T12:59:40.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl", hash = "sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf", size = 36748, upload-time = "2026-05-14T12:59:39.473Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, +]