interpn 0.6.2__tar.gz → 0.6.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {interpn-0.6.2 → interpn-0.6.4}/.github/workflows/release-python.yml +4 -8
- {interpn-0.6.2 → interpn-0.6.4}/.github/workflows/release-rust.yml +0 -1
- {interpn-0.6.2 → interpn-0.6.4}/.github/workflows/test-python.yml +8 -2
- {interpn-0.6.2 → interpn-0.6.4}/CHANGELOG.md +34 -0
- {interpn-0.6.2 → interpn-0.6.4}/Cargo.lock +13 -13
- {interpn-0.6.2 → interpn-0.6.4}/Cargo.toml +3 -3
- interpn-0.6.4/PKG-INFO +227 -0
- {interpn-0.6.2 → interpn-0.6.4}/benches/bench.rs +67 -36
- {interpn-0.6.2 → interpn-0.6.4}/benches/bench_cpu.py +56 -2
- {interpn-0.6.2 → interpn-0.6.4}/benches/bench_mem.py +12 -8
- {interpn-0.6.2 → interpn-0.6.4}/docs/1d_quality_of_fit_Rectilinear.svg +147 -147
- {interpn-0.6.2 → interpn-0.6.4}/docs/1d_quality_of_fit_Regular.svg +144 -144
- {interpn-0.6.2 → interpn-0.6.4}/docs/2d_quality_of_fit_Rectilinear.svg +247 -247
- {interpn-0.6.2 → interpn-0.6.4}/docs/2d_quality_of_fit_Regular.svg +244 -244
- {interpn-0.6.2 → interpn-0.6.4}/docs/3d_throughput_vs_nobs.svg +507 -401
- {interpn-0.6.2 → interpn-0.6.4}/docs/3d_throughput_vs_nobs_prealloc.svg +509 -403
- {interpn-0.6.2 → interpn-0.6.4}/docs/4d_throughput_vs_nobs.svg +513 -400
- {interpn-0.6.2 → interpn-0.6.4}/docs/4d_throughput_vs_nobs_prealloc.svg +522 -402
- interpn-0.6.4/docs/nearest_quality_of_fit.svg +6053 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/perf.md +5 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/throughput_vs_dims_1000_obs.svg +332 -230
- {interpn-0.6.2 → interpn-0.6.4}/docs/throughput_vs_dims_1_obs.svg +298 -210
- interpn-0.6.4/examples/nearest_comparison.py +120 -0
- {interpn-0.6.2 → interpn-0.6.4}/pyproject.toml +10 -8
- interpn-0.6.4/scripts/pgo-profiles/pgo.profdata +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/profile_workload.py +6 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/__init__.py +4 -0
- interpn-0.6.4/src/interpn/nearest_rectilinear.py +198 -0
- interpn-0.6.4/src/interpn/nearest_regular.py +213 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/raw.py +8 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/lib.rs +23 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/multicubic/rectilinear.rs +2 -15
- {interpn-0.6.2 → interpn-0.6.4}/src/multicubic/regular.rs +2 -15
- {interpn-0.6.2 → interpn-0.6.4}/src/multilinear/rectilinear.rs +3 -16
- {interpn-0.6.2 → interpn-0.6.4}/src/multilinear/rectilinear_recursive.rs +1 -1
- {interpn-0.6.2 → interpn-0.6.4}/src/multilinear/regular.rs +3 -20
- {interpn-0.6.2 → interpn-0.6.4}/src/multilinear/regular_recursive.rs +1 -1
- interpn-0.6.4/src/nearest/mod.rs +8 -0
- interpn-0.6.4/src/nearest/rectilinear.rs +392 -0
- interpn-0.6.4/src/nearest/regular.rs +418 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/python.rs +67 -1
- interpn-0.6.4/test/test_nearest_rectilinear.py +71 -0
- interpn-0.6.4/test/test_nearest_regular.py +81 -0
- {interpn-0.6.2 → interpn-0.6.4}/uv.lock +308 -110
- interpn-0.6.2/PKG-INFO +0 -30
- interpn-0.6.2/scripts/pgo-profiles/pgo.profdata +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/.cargo/config.toml +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/.github/workflows/test-rust.yml +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/.gitignore +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/.readthedocs.yml +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/LICENSE-APACHE +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/LICENSE-MIT +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/README.md +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/API_Docs.md +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/index.md +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/ram_vs_dims.svg +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/docs/requirements.txt +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/examples/cubic_comparison.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/mkdocs.yml +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/distr_pgo.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/distr_pgo_install.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/distr_pgo_profile.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/native_pgo.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/native_pgo_install.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/scripts/native_pgo_profile.sh +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/multicubic_rectilinear.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/multicubic_regular.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/multilinear_rectilinear.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/multilinear_regular.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/py.typed +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/interpn/serialization.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/multicubic/mod.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/multicubic/rectilinear_recursive.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/multicubic/regular_recursive.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/multilinear/mod.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/one_dim/hold.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/one_dim/linear.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/one_dim/mod.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/testing.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/src/utils.rs +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_docs.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_examples.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_multicubic_rectilinear.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_multicubic_regular.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_multilinear_rectilinear.py +0 -0
- {interpn-0.6.2 → interpn-0.6.4}/test/test_multilinear_regular.py +0 -0
|
@@ -6,18 +6,14 @@
|
|
|
6
6
|
name: release-python
|
|
7
7
|
|
|
8
8
|
on:
|
|
9
|
-
push:
|
|
10
|
-
branches:
|
|
11
|
-
- main
|
|
12
9
|
workflow_dispatch:
|
|
13
10
|
|
|
14
11
|
permissions:
|
|
15
12
|
contents: read
|
|
16
13
|
|
|
17
14
|
jobs:
|
|
18
|
-
|
|
19
|
-
uses: ./.github/workflows/
|
|
20
|
-
secrets: inherit
|
|
15
|
+
test_python:
|
|
16
|
+
uses: ./.github/workflows/test-python.yml
|
|
21
17
|
|
|
22
18
|
linux:
|
|
23
19
|
runs-on: ${{ matrix.platform.runner }}
|
|
@@ -124,7 +120,7 @@ jobs:
|
|
|
124
120
|
strategy:
|
|
125
121
|
matrix:
|
|
126
122
|
platform:
|
|
127
|
-
- runner: macos-
|
|
123
|
+
- runner: macos-15-intel
|
|
128
124
|
target: x86_64
|
|
129
125
|
- runner: macos-14
|
|
130
126
|
target: aarch64
|
|
@@ -163,7 +159,7 @@ jobs:
|
|
|
163
159
|
name: Release
|
|
164
160
|
runs-on: ubuntu-latest
|
|
165
161
|
# if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
|
|
166
|
-
needs: [
|
|
162
|
+
needs: [test_python, linux, musllinux, windows, macos, sdist]
|
|
167
163
|
permissions:
|
|
168
164
|
# Use to sign the release artifacts
|
|
169
165
|
id-token: write
|
|
@@ -11,7 +11,13 @@ jobs:
|
|
|
11
11
|
strategy:
|
|
12
12
|
matrix:
|
|
13
13
|
target: [x86_64]
|
|
14
|
-
python-version:
|
|
14
|
+
python-version:
|
|
15
|
+
- "3.9"
|
|
16
|
+
- "3.10"
|
|
17
|
+
- "3.11"
|
|
18
|
+
- "3.12"
|
|
19
|
+
- "3.13"
|
|
20
|
+
- "3.14"
|
|
15
21
|
steps:
|
|
16
22
|
- uses: actions/checkout@v3
|
|
17
23
|
- name: Install uv
|
|
@@ -42,7 +48,7 @@ jobs:
|
|
|
42
48
|
- runner: windows-latest
|
|
43
49
|
- runner: ubuntu-latest
|
|
44
50
|
- runner: ubuntu-24.04-arm # aarch64
|
|
45
|
-
- runner: macos-
|
|
51
|
+
- runner: macos-15-intel # x86_64
|
|
46
52
|
- runner: macos-14 # aarch64
|
|
47
53
|
python-version: ["3.9"]
|
|
48
54
|
steps:
|
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.4 2025-10-24
|
|
4
|
+
|
|
5
|
+
Implement N-dimensional nearest-neighbor interpolation on regular and rectilinear grids.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* Rust
|
|
10
|
+
* Add `nearest` module with regular- and rectilinear- grid methods in up to 6 dimensions
|
|
11
|
+
* Reduce code duplication for fixed-dim array indexing
|
|
12
|
+
* Update pyo3 and numpy rust deps
|
|
13
|
+
* Python
|
|
14
|
+
* Add bindings, tests, benchmarks, and quality-of-fit plots for `NearestRegular` and `NearestRectilinear`
|
|
15
|
+
* Update PGO profile data to include new functions
|
|
16
|
+
|
|
17
|
+
## 0.6.3 2025-10-22
|
|
18
|
+
|
|
19
|
+
Unpin max supported python version due to use of stable ABI3,
|
|
20
|
+
along with a host of other improvements to packaging and actions workflows.
|
|
21
|
+
|
|
22
|
+
### New Contributors
|
|
23
|
+
|
|
24
|
+
* [Clément Robert](https://github.com/neutrinoceros) contributed PRs 30,32,33,36 making up all the substantial changes in this release. Thanks, Clément!
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
* Python
|
|
29
|
+
* Unpin max python version
|
|
30
|
+
* Roll forward pydantic version for python 3.14 compatibility
|
|
31
|
+
* Update package metadata
|
|
32
|
+
* Add python 3.14 to test matrix
|
|
33
|
+
* Workflows
|
|
34
|
+
* Reconfigure from single-contributor to commons-project by segmenting release workflows to be dispatched manually only
|
|
35
|
+
* Update python release workflow to depend on test-python instead of release-rust to support separate releases
|
|
36
|
+
|
|
3
37
|
## 0.6.2 2025-10-20
|
|
4
38
|
|
|
5
39
|
Add optional use of fused multiply-add, enabled for python distributions.
|
|
@@ -221,7 +221,7 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
|
|
221
221
|
|
|
222
222
|
[[package]]
|
|
223
223
|
name = "interpn"
|
|
224
|
-
version = "0.6.
|
|
224
|
+
version = "0.6.4"
|
|
225
225
|
dependencies = [
|
|
226
226
|
"criterion",
|
|
227
227
|
"crunchy",
|
|
@@ -355,9 +355,9 @@ dependencies = [
|
|
|
355
355
|
|
|
356
356
|
[[package]]
|
|
357
357
|
name = "numpy"
|
|
358
|
-
version = "0.
|
|
358
|
+
version = "0.27.0"
|
|
359
359
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
360
|
-
checksum = "
|
|
360
|
+
checksum = "0fa24ffc88cf9d43f7269d6b6a0d0a00010924a8cc90604a21ef9c433b66998d"
|
|
361
361
|
dependencies = [
|
|
362
362
|
"libc",
|
|
363
363
|
"ndarray",
|
|
@@ -444,9 +444,9 @@ dependencies = [
|
|
|
444
444
|
|
|
445
445
|
[[package]]
|
|
446
446
|
name = "pyo3"
|
|
447
|
-
version = "0.
|
|
447
|
+
version = "0.27.1"
|
|
448
448
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
449
|
-
checksum = "
|
|
449
|
+
checksum = "37a6df7eab65fc7bee654a421404947e10a0f7085b6951bf2ea395f4659fb0cf"
|
|
450
450
|
dependencies = [
|
|
451
451
|
"indoc",
|
|
452
452
|
"libc",
|
|
@@ -461,9 +461,9 @@ dependencies = [
|
|
|
461
461
|
|
|
462
462
|
[[package]]
|
|
463
463
|
name = "pyo3-build-config"
|
|
464
|
-
version = "0.
|
|
464
|
+
version = "0.27.1"
|
|
465
465
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
466
|
-
checksum = "
|
|
466
|
+
checksum = "f77d387774f6f6eec64a004eac0ed525aab7fa1966d94b42f743797b3e395afb"
|
|
467
467
|
dependencies = [
|
|
468
468
|
"python3-dll-a",
|
|
469
469
|
"target-lexicon",
|
|
@@ -471,9 +471,9 @@ dependencies = [
|
|
|
471
471
|
|
|
472
472
|
[[package]]
|
|
473
473
|
name = "pyo3-ffi"
|
|
474
|
-
version = "0.
|
|
474
|
+
version = "0.27.1"
|
|
475
475
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
476
|
-
checksum = "
|
|
476
|
+
checksum = "2dd13844a4242793e02df3e2ec093f540d948299a6a77ea9ce7afd8623f542be"
|
|
477
477
|
dependencies = [
|
|
478
478
|
"libc",
|
|
479
479
|
"pyo3-build-config",
|
|
@@ -481,9 +481,9 @@ dependencies = [
|
|
|
481
481
|
|
|
482
482
|
[[package]]
|
|
483
483
|
name = "pyo3-macros"
|
|
484
|
-
version = "0.
|
|
484
|
+
version = "0.27.1"
|
|
485
485
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
486
|
-
checksum = "
|
|
486
|
+
checksum = "eaf8f9f1108270b90d3676b8679586385430e5c0bb78bb5f043f95499c821a71"
|
|
487
487
|
dependencies = [
|
|
488
488
|
"proc-macro2",
|
|
489
489
|
"pyo3-macros-backend",
|
|
@@ -493,9 +493,9 @@ dependencies = [
|
|
|
493
493
|
|
|
494
494
|
[[package]]
|
|
495
495
|
name = "pyo3-macros-backend"
|
|
496
|
-
version = "0.
|
|
496
|
+
version = "0.27.1"
|
|
497
497
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
498
|
-
checksum = "
|
|
498
|
+
checksum = "70a3b2274450ba5288bc9b8c1b69ff569d1d61189d4bff38f8d22e03d17f932b"
|
|
499
499
|
dependencies = [
|
|
500
500
|
"heck",
|
|
501
501
|
"proc-macro2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "interpn"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.4"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
authors = ["James Logan <jlogan03@gmail.com>"]
|
|
6
6
|
license = "MIT OR Apache-2.0"
|
|
@@ -20,8 +20,8 @@ num-traits = { version = "0.2.19", default-features = false, features = ["libm"]
|
|
|
20
20
|
crunchy = { version = "0.2.4", default-features = false, features = ["limit_256"] }
|
|
21
21
|
|
|
22
22
|
# Python bindings
|
|
23
|
-
pyo3 = { version = "0.
|
|
24
|
-
numpy = { version = "0.
|
|
23
|
+
pyo3 = { version = "0.27.1", features = ["extension-module", "abi3-py39", "generate-import-lib"], optional = true }
|
|
24
|
+
numpy = { version = "0.27.0", optional = true }
|
|
25
25
|
|
|
26
26
|
# Test-only utils
|
|
27
27
|
itertools = { version = "0.14.0", optional = true }
|
interpn-0.6.4/PKG-INFO
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: interpn
|
|
3
|
+
Version: 0.6.4
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
+
Requires-Dist: numpy>=2
|
|
8
|
+
Requires-Dist: pydantic>=2.12
|
|
9
|
+
Requires-Dist: pytest>=8.4.2 ; extra == 'test'
|
|
10
|
+
Requires-Dist: pytest-cov>=7.0.0 ; extra == 'test'
|
|
11
|
+
Requires-Dist: ruff>=0.13.3 ; extra == 'test'
|
|
12
|
+
Requires-Dist: pyright==1.1.337 ; extra == 'test'
|
|
13
|
+
Requires-Dist: mktestdocs>=0.2.1 ; extra == 'test'
|
|
14
|
+
Requires-Dist: scipy>=1.11.4 ; extra == 'test'
|
|
15
|
+
Requires-Dist: matplotlib>=3.8 ; extra == 'test'
|
|
16
|
+
Requires-Dist: scipy>=1.11.4 ; extra == 'bench'
|
|
17
|
+
Requires-Dist: matplotlib>=3.8 ; extra == 'bench'
|
|
18
|
+
Requires-Dist: memory-profiler>=0.61.0 ; extra == 'bench'
|
|
19
|
+
Requires-Dist: mkdocs>=1.5.3 ; extra == 'doc'
|
|
20
|
+
Requires-Dist: mkdocstrings-python>=1.7.5 ; extra == 'doc'
|
|
21
|
+
Requires-Dist: mkdocs-material>=9.4.10 ; extra == 'doc'
|
|
22
|
+
Provides-Extra: test
|
|
23
|
+
Provides-Extra: bench
|
|
24
|
+
Provides-Extra: doc
|
|
25
|
+
License-File: LICENSE-MIT
|
|
26
|
+
License-File: LICENSE-APACHE
|
|
27
|
+
Summary: N-dimensional interpolation/extrapolation methods
|
|
28
|
+
Home-Page: https://github.com/jlogan03/interpn/
|
|
29
|
+
Author-email: James Logan <jlogan03@gmail.com>
|
|
30
|
+
License-Expression: MIT OR Apache-2.0
|
|
31
|
+
Requires-Python: >=3.9
|
|
32
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
33
|
+
Project-URL: repository, https://github.com/jlogan03/interpn
|
|
34
|
+
Project-URL: documentation, https://interpn.readthedocs.io/
|
|
35
|
+
|
|
36
|
+
# InterpN
|
|
37
|
+
|
|
38
|
+
[Repo](https://github.com/jlogan03/interpn) |
|
|
39
|
+
[Python Docs](https://interpnpy.readthedocs.io/en/latest/) |
|
|
40
|
+
[Rust Docs](https://docs.rs/interpn/latest/interpn/)
|
|
41
|
+
|
|
42
|
+
N-dimensional interpolation/extrapolation methods, no-std and no-alloc compatible,
|
|
43
|
+
prioritizing correctness, performance, and compatiblity with memory-constrained environments.
|
|
44
|
+
|
|
45
|
+
Available as a rust crate and python library.
|
|
46
|
+
|
|
47
|
+
These methods perform zero allocation when evaluated (except, optionally, for the output).
|
|
48
|
+
Because of this, they have minimal per-call overhead, and are particularly
|
|
49
|
+
effective when examining small numbers of observation points. See the
|
|
50
|
+
[performance](https://interpnpy.readthedocs.io/en/latest/perf/) page for detailed benchmarks.
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
| Feature →<br>↓ Interpolant Method | Regular<br>Grid | Rectilinear<br>Grid | Json<br>Serialization |
|
|
55
|
+
|-----------------------------------|-----------------|---------------------|-----------------------|
|
|
56
|
+
| Linear | ✅ | ✅ | ✅ |
|
|
57
|
+
| Cubic | ✅ | ✅ | ✅ |
|
|
58
|
+
|
|
59
|
+
The methods provided here, while more limited in scope than scipy's,
|
|
60
|
+
|
|
61
|
+
* are significantly faster under most conditions
|
|
62
|
+
* use almost no RAM (and perform no heap allocations at all)
|
|
63
|
+
* produce significantly improved floating-point error (by several orders of magnitude)
|
|
64
|
+
* are json-serializable using Pydantic
|
|
65
|
+
* can also be used easily in web and embedded applications via the Rust library
|
|
66
|
+
* are permissively licensed
|
|
67
|
+
|
|
68
|
+

|
|
69
|
+
|
|
70
|
+
See [here](https://interpnpy.readthedocs.io/en/latest/perf/) for more info about quality-of-fit, throughput, and memory usage.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install interpn
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Profile-Guided Optimization
|
|
79
|
+
|
|
80
|
+
To build the extension with profile-guided optimization using pre-built profiles, do `sh ./scripts/pgo_install.sh`.
|
|
81
|
+
You can also generate your own PGO profiles like `sh ./scripts/pgo_profile.sh`.
|
|
82
|
+
after installing these extra compiler dependencies:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
rustup component add llvm-tools-preview
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Rust Examples
|
|
89
|
+
|
|
90
|
+
### Regular Grid
|
|
91
|
+
```rust
|
|
92
|
+
use interpn::{multilinear, multicubic};
|
|
93
|
+
|
|
94
|
+
// Define a grid
|
|
95
|
+
let x = [1.0_f64, 2.0, 3.0, 4.0];
|
|
96
|
+
let y = [0.0_f64, 1.0, 2.0, 3.0];
|
|
97
|
+
|
|
98
|
+
// Grid input for rectilinear method
|
|
99
|
+
let grids = &[&x[..], &y[..]];
|
|
100
|
+
|
|
101
|
+
// Grid input for regular grid method
|
|
102
|
+
let dims = [x.len(), y.len()];
|
|
103
|
+
let starts = [x[0], y[0]];
|
|
104
|
+
let steps = [x[1] - x[0], y[1] - y[0]];
|
|
105
|
+
|
|
106
|
+
// Values at grid points
|
|
107
|
+
let z = [2.0; 16];
|
|
108
|
+
|
|
109
|
+
// Observation points to interpolate/extrapolate
|
|
110
|
+
let xobs = [0.0_f64, 5.0];
|
|
111
|
+
let yobs = [-1.0, 3.0];
|
|
112
|
+
let obs = [&xobs[..], &yobs[..]];
|
|
113
|
+
|
|
114
|
+
// Storage for output
|
|
115
|
+
let mut out = [0.0; 2];
|
|
116
|
+
|
|
117
|
+
// Do interpolation
|
|
118
|
+
multilinear::regular::interpn(&dims, &starts, &steps, &z, &obs, &mut out);
|
|
119
|
+
multicubic::regular::interpn(&dims, &starts, &steps, &z, false, &obs, &mut out);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Rectilinear Grid
|
|
123
|
+
```rust
|
|
124
|
+
use interpn::{multilinear, multicubic};
|
|
125
|
+
|
|
126
|
+
// Define a grid
|
|
127
|
+
let x = [1.0_f64, 2.0, 3.0, 4.0];
|
|
128
|
+
let y = [0.0_f64, 1.0, 2.0, 3.0];
|
|
129
|
+
|
|
130
|
+
// Grid input for rectilinear method
|
|
131
|
+
let grids = &[&x[..], &y[..]];
|
|
132
|
+
|
|
133
|
+
// Values at grid points
|
|
134
|
+
let z = [2.0; 16];
|
|
135
|
+
|
|
136
|
+
// Points to interpolate/extrapolate
|
|
137
|
+
let xobs = [0.0_f64, 5.0];
|
|
138
|
+
let yobs = [-1.0, 3.0];
|
|
139
|
+
let obs = [&xobs[..], &yobs[..]];
|
|
140
|
+
|
|
141
|
+
// Storage for output
|
|
142
|
+
let mut out = [0.0; 2];
|
|
143
|
+
|
|
144
|
+
// Do interpolation
|
|
145
|
+
multilinear::rectilinear::interpn(grids, &z, &obs, &mut out).unwrap();
|
|
146
|
+
multicubic::rectilinear::interpn(grids, &z, false, &obs, &mut out).unwrap();
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Python Examples
|
|
150
|
+
|
|
151
|
+
### Available Methods
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import interpn
|
|
155
|
+
import numpy as np
|
|
156
|
+
|
|
157
|
+
# Build grid
|
|
158
|
+
x = np.linspace(0.0, 10.0, 5)
|
|
159
|
+
y = np.linspace(20.0, 30.0, 4)
|
|
160
|
+
grids = [x, y]
|
|
161
|
+
|
|
162
|
+
xgrid, ygrid = np.meshgrid(x, y, indexing="ij")
|
|
163
|
+
zgrid = (xgrid + 2.0 * ygrid) # Values at grid points
|
|
164
|
+
|
|
165
|
+
# Grid inputs for true regular grid
|
|
166
|
+
dims = [x.size, y.size]
|
|
167
|
+
starts = np.array([x[0], y[0]])
|
|
168
|
+
steps = np.array([x[1] - x[0], y[1] - y[0]])
|
|
169
|
+
|
|
170
|
+
# Initialize different interpolators
|
|
171
|
+
# Call like `linear_regular.eval([xs, ys])`
|
|
172
|
+
linear_regular = interpn.MultilinearRegular.new(dims, starts, steps, zgrid)
|
|
173
|
+
cubic_regular = interpn.MulticubicRegular.new(dims, starts, steps, zgrid)
|
|
174
|
+
linear_rectilinear = interpn.MultilinearRectilinear.new(grids, zgrid)
|
|
175
|
+
cubic_rectilinear = interpn.MulticubicRectilinear.new(grids, zgrid)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Multilinear Interpolation
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
import interpn
|
|
182
|
+
import numpy as np
|
|
183
|
+
|
|
184
|
+
# Build grid
|
|
185
|
+
x = np.linspace(0.0, 10.0, 5)
|
|
186
|
+
y = np.linspace(20.0, 30.0, 4)
|
|
187
|
+
|
|
188
|
+
xgrid, ygrid = np.meshgrid(x, y, indexing="ij")
|
|
189
|
+
zgrid = (xgrid + 2.0 * ygrid) # Values at grid points
|
|
190
|
+
|
|
191
|
+
# Grid inputs for true regular grid
|
|
192
|
+
dims = [x.size, y.size]
|
|
193
|
+
starts = np.array([x[0], y[0]])
|
|
194
|
+
steps = np.array([x[1] - x[0], y[1] - y[0]])
|
|
195
|
+
|
|
196
|
+
# Observation points pointed back at the grid
|
|
197
|
+
obs = [xgrid.flatten(), ygrid.flatten()]
|
|
198
|
+
|
|
199
|
+
# Initialize
|
|
200
|
+
interpolator = interpn.MultilinearRegular.new(dims, starts, steps, zgrid.flatten())
|
|
201
|
+
|
|
202
|
+
# Interpolate
|
|
203
|
+
out = interpolator.eval(obs)
|
|
204
|
+
|
|
205
|
+
# Check result
|
|
206
|
+
assert np.allclose(out, zgrid.flatten(), rtol=1e-13)
|
|
207
|
+
|
|
208
|
+
# Serialize and deserialize
|
|
209
|
+
roundtrip_interpolator = interpn.MultilinearRegular.model_validate_json(
|
|
210
|
+
interpolator.model_dump_json()
|
|
211
|
+
)
|
|
212
|
+
out2 = roundtrip_interpolator.eval(obs)
|
|
213
|
+
|
|
214
|
+
# Check result from roundtrip serialized/deserialized interpolator
|
|
215
|
+
assert np.all(out == out2)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# License
|
|
220
|
+
|
|
221
|
+
Licensed under either of
|
|
222
|
+
|
|
223
|
+
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
224
|
+
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
225
|
+
|
|
226
|
+
at your option.
|
|
227
|
+
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
use criterion::*;
|
|
4
4
|
use gridgen::*;
|
|
5
5
|
use interpn::{
|
|
6
|
-
Linear1D, LinearHoldLast1D, MultilinearRegular,
|
|
7
|
-
multilinear,
|
|
6
|
+
Linear1D, LinearHoldLast1D, MultilinearRegular, NearestRectilinear, NearestRegular,
|
|
7
|
+
RectilinearGrid1D, RegularGrid1D, multicubic, multilinear, nearest,
|
|
8
8
|
one_dim::{
|
|
9
9
|
Interp1D,
|
|
10
10
|
hold::{Left1D, Nearest1D},
|
|
@@ -135,6 +135,70 @@ macro_rules! bench_interp_specific {
|
|
|
135
135
|
},
|
|
136
136
|
);
|
|
137
137
|
|
|
138
|
+
$group.bench_with_input(
|
|
139
|
+
BenchmarkId::new(
|
|
140
|
+
format!(
|
|
141
|
+
"Nearest Regular {}x{}D, {}",
|
|
142
|
+
$gridsize, $ndims, scan_or_shuffle
|
|
143
|
+
),
|
|
144
|
+
$size,
|
|
145
|
+
),
|
|
146
|
+
$size,
|
|
147
|
+
|b, &size| {
|
|
148
|
+
let (grids, z) = gen_grid($ndims, $gridsize, 0.0);
|
|
149
|
+
let m: usize = ((size as f64).powf(1.0 / ($ndims as f64)) + 2.0) as usize;
|
|
150
|
+
let gridobs_t = match $kind {
|
|
151
|
+
Kind::Interp => gen_interp_obs_grid(&grids, m, true),
|
|
152
|
+
Kind::Extrap => gen_extrap_obs_grid(&grids, m, true),
|
|
153
|
+
};
|
|
154
|
+
let obs: Vec<&[f64]> = gridobs_t.iter().map(|x| &x[..size]).collect();
|
|
155
|
+
let mut out = vec![0.0; size];
|
|
156
|
+
|
|
157
|
+
let dims = [$gridsize; $ndims];
|
|
158
|
+
let mut starts = [0.0; $ndims];
|
|
159
|
+
let mut steps = [0.0; $ndims];
|
|
160
|
+
(0..$ndims).for_each(|i| starts[i] = grids[i][0]);
|
|
161
|
+
(0..$ndims).for_each(|i| steps[i] = grids[i][1] - grids[i][0]);
|
|
162
|
+
|
|
163
|
+
b.iter(|| {
|
|
164
|
+
black_box({
|
|
165
|
+
nearest::regular::interpn(&dims, &starts, &steps, &z, &obs[..], &mut out)
|
|
166
|
+
.unwrap()
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
$group.bench_with_input(
|
|
173
|
+
BenchmarkId::new(
|
|
174
|
+
format!(
|
|
175
|
+
"Nearest Rectilinear {}x{}D, {}",
|
|
176
|
+
$gridsize, $ndims, scan_or_shuffle
|
|
177
|
+
),
|
|
178
|
+
$size,
|
|
179
|
+
),
|
|
180
|
+
$size,
|
|
181
|
+
|b, &size| {
|
|
182
|
+
let (grids, z) = gen_grid($ndims, $gridsize, 1e-3);
|
|
183
|
+
|
|
184
|
+
let m: usize = ((size as f64).powf(1.0 / ($ndims as f64)) + 2.0) as usize;
|
|
185
|
+
let gridobs_t = match $kind {
|
|
186
|
+
Kind::Interp => gen_interp_obs_grid(&grids, m, true),
|
|
187
|
+
Kind::Extrap => gen_extrap_obs_grid(&grids, m, true),
|
|
188
|
+
};
|
|
189
|
+
let obs: Vec<&[f64]> = gridobs_t.iter().map(|x| &x[..size]).collect();
|
|
190
|
+
let mut out = vec![0.0; size];
|
|
191
|
+
|
|
192
|
+
let gridslice: Vec<&[f64]> = grids.iter().map(|x| &x[..]).collect();
|
|
193
|
+
|
|
194
|
+
b.iter(|| {
|
|
195
|
+
black_box(
|
|
196
|
+
nearest::rectilinear::interpn(&gridslice, &z, &obs, &mut out).unwrap(),
|
|
197
|
+
)
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
);
|
|
201
|
+
|
|
138
202
|
$group.bench_with_input(
|
|
139
203
|
BenchmarkId::new(
|
|
140
204
|
format!(
|
|
@@ -426,41 +490,8 @@ fn bench_interp(c: &mut Criterion) {
|
|
|
426
490
|
}
|
|
427
491
|
}
|
|
428
492
|
|
|
429
|
-
fn bench_extrap(c: &mut Criterion) {
|
|
430
|
-
//
|
|
431
|
-
// Shuffled (un-ordered observation points)
|
|
432
|
-
//
|
|
433
|
-
for gridsize in [10] {
|
|
434
|
-
let mut group = c.benchmark_group(format!("Extrap_1D_Shuffled_{gridsize}-grid"));
|
|
435
|
-
for size in [1, 100, 1_000_000].iter() {
|
|
436
|
-
group.throughput(Throughput::Elements(*size as u64));
|
|
437
|
-
bench_interp_specific!(group, 1, gridsize, size, Kind::Extrap);
|
|
438
|
-
}
|
|
439
|
-
group.finish();
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
for gridsize in [10] {
|
|
443
|
-
let mut group = c.benchmark_group(format!("Extrap_2D_Shuffled_{gridsize}-grid"));
|
|
444
|
-
for size in [1, 100, 1_000_000].iter() {
|
|
445
|
-
group.throughput(Throughput::Elements(*size as u64));
|
|
446
|
-
bench_interp_specific!(group, 2, gridsize, size, Kind::Extrap);
|
|
447
|
-
}
|
|
448
|
-
group.finish();
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
for gridsize in [10] {
|
|
452
|
-
let mut group = c.benchmark_group(format!("Extrap_3D_Shuffled_{gridsize}-grid"));
|
|
453
|
-
for size in [1, 100, 1_000_000].iter() {
|
|
454
|
-
group.throughput(Throughput::Elements(*size as u64));
|
|
455
|
-
bench_interp_specific!(group, 3, gridsize, size, Kind::Extrap);
|
|
456
|
-
}
|
|
457
|
-
group.finish();
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
493
|
criterion_group!(benches_interp, bench_interp);
|
|
462
|
-
|
|
463
|
-
criterion_main!(benches_interp, benches_extrap,);
|
|
494
|
+
criterion_main!(benches_interp);
|
|
464
495
|
|
|
465
496
|
mod randn {
|
|
466
497
|
use rand::Rng;
|