interpn 0.6.3__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.
Files changed (85) hide show
  1. {interpn-0.6.3 → interpn-0.6.4}/CHANGELOG.md +14 -0
  2. {interpn-0.6.3 → interpn-0.6.4}/Cargo.lock +13 -13
  3. {interpn-0.6.3 → interpn-0.6.4}/Cargo.toml +3 -3
  4. {interpn-0.6.3 → interpn-0.6.4}/PKG-INFO +1 -1
  5. {interpn-0.6.3 → interpn-0.6.4}/benches/bench.rs +67 -36
  6. {interpn-0.6.3 → interpn-0.6.4}/benches/bench_cpu.py +56 -2
  7. {interpn-0.6.3 → interpn-0.6.4}/benches/bench_mem.py +12 -8
  8. {interpn-0.6.3 → interpn-0.6.4}/docs/1d_quality_of_fit_Rectilinear.svg +147 -147
  9. {interpn-0.6.3 → interpn-0.6.4}/docs/1d_quality_of_fit_Regular.svg +144 -144
  10. {interpn-0.6.3 → interpn-0.6.4}/docs/2d_quality_of_fit_Rectilinear.svg +247 -247
  11. {interpn-0.6.3 → interpn-0.6.4}/docs/2d_quality_of_fit_Regular.svg +244 -244
  12. {interpn-0.6.3 → interpn-0.6.4}/docs/3d_throughput_vs_nobs.svg +507 -401
  13. {interpn-0.6.3 → interpn-0.6.4}/docs/3d_throughput_vs_nobs_prealloc.svg +509 -403
  14. {interpn-0.6.3 → interpn-0.6.4}/docs/4d_throughput_vs_nobs.svg +513 -400
  15. {interpn-0.6.3 → interpn-0.6.4}/docs/4d_throughput_vs_nobs_prealloc.svg +522 -402
  16. interpn-0.6.4/docs/nearest_quality_of_fit.svg +6053 -0
  17. {interpn-0.6.3 → interpn-0.6.4}/docs/perf.md +5 -0
  18. {interpn-0.6.3 → interpn-0.6.4}/docs/throughput_vs_dims_1000_obs.svg +332 -230
  19. {interpn-0.6.3 → interpn-0.6.4}/docs/throughput_vs_dims_1_obs.svg +298 -210
  20. interpn-0.6.4/examples/nearest_comparison.py +120 -0
  21. {interpn-0.6.3 → interpn-0.6.4}/pyproject.toml +1 -1
  22. interpn-0.6.4/scripts/pgo-profiles/pgo.profdata +0 -0
  23. {interpn-0.6.3 → interpn-0.6.4}/scripts/profile_workload.py +6 -0
  24. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/__init__.py +4 -0
  25. interpn-0.6.4/src/interpn/nearest_rectilinear.py +198 -0
  26. interpn-0.6.4/src/interpn/nearest_regular.py +213 -0
  27. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/raw.py +8 -0
  28. {interpn-0.6.3 → interpn-0.6.4}/src/lib.rs +23 -0
  29. {interpn-0.6.3 → interpn-0.6.4}/src/multicubic/rectilinear.rs +2 -15
  30. {interpn-0.6.3 → interpn-0.6.4}/src/multicubic/regular.rs +2 -15
  31. {interpn-0.6.3 → interpn-0.6.4}/src/multilinear/rectilinear.rs +3 -16
  32. {interpn-0.6.3 → interpn-0.6.4}/src/multilinear/rectilinear_recursive.rs +1 -1
  33. {interpn-0.6.3 → interpn-0.6.4}/src/multilinear/regular.rs +3 -20
  34. {interpn-0.6.3 → interpn-0.6.4}/src/multilinear/regular_recursive.rs +1 -1
  35. interpn-0.6.4/src/nearest/mod.rs +8 -0
  36. interpn-0.6.4/src/nearest/rectilinear.rs +392 -0
  37. interpn-0.6.4/src/nearest/regular.rs +418 -0
  38. {interpn-0.6.3 → interpn-0.6.4}/src/python.rs +67 -1
  39. interpn-0.6.4/test/test_nearest_rectilinear.py +71 -0
  40. interpn-0.6.4/test/test_nearest_regular.py +81 -0
  41. {interpn-0.6.3 → interpn-0.6.4}/uv.lock +1 -1
  42. interpn-0.6.3/scripts/pgo-profiles/pgo.profdata +0 -0
  43. {interpn-0.6.3 → interpn-0.6.4}/.cargo/config.toml +0 -0
  44. {interpn-0.6.3 → interpn-0.6.4}/.github/workflows/release-python.yml +0 -0
  45. {interpn-0.6.3 → interpn-0.6.4}/.github/workflows/release-rust.yml +0 -0
  46. {interpn-0.6.3 → interpn-0.6.4}/.github/workflows/test-python.yml +0 -0
  47. {interpn-0.6.3 → interpn-0.6.4}/.github/workflows/test-rust.yml +0 -0
  48. {interpn-0.6.3 → interpn-0.6.4}/.gitignore +0 -0
  49. {interpn-0.6.3 → interpn-0.6.4}/.readthedocs.yml +0 -0
  50. {interpn-0.6.3 → interpn-0.6.4}/LICENSE-APACHE +0 -0
  51. {interpn-0.6.3 → interpn-0.6.4}/LICENSE-MIT +0 -0
  52. {interpn-0.6.3 → interpn-0.6.4}/README.md +0 -0
  53. {interpn-0.6.3 → interpn-0.6.4}/docs/API_Docs.md +0 -0
  54. {interpn-0.6.3 → interpn-0.6.4}/docs/index.md +0 -0
  55. {interpn-0.6.3 → interpn-0.6.4}/docs/ram_vs_dims.svg +0 -0
  56. {interpn-0.6.3 → interpn-0.6.4}/docs/requirements.txt +0 -0
  57. {interpn-0.6.3 → interpn-0.6.4}/examples/cubic_comparison.py +0 -0
  58. {interpn-0.6.3 → interpn-0.6.4}/mkdocs.yml +0 -0
  59. {interpn-0.6.3 → interpn-0.6.4}/scripts/distr_pgo.sh +0 -0
  60. {interpn-0.6.3 → interpn-0.6.4}/scripts/distr_pgo_install.sh +0 -0
  61. {interpn-0.6.3 → interpn-0.6.4}/scripts/distr_pgo_profile.sh +0 -0
  62. {interpn-0.6.3 → interpn-0.6.4}/scripts/native_pgo.sh +0 -0
  63. {interpn-0.6.3 → interpn-0.6.4}/scripts/native_pgo_install.sh +0 -0
  64. {interpn-0.6.3 → interpn-0.6.4}/scripts/native_pgo_profile.sh +0 -0
  65. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/multicubic_rectilinear.py +0 -0
  66. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/multicubic_regular.py +0 -0
  67. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/multilinear_rectilinear.py +0 -0
  68. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/multilinear_regular.py +0 -0
  69. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/py.typed +0 -0
  70. {interpn-0.6.3 → interpn-0.6.4}/src/interpn/serialization.py +0 -0
  71. {interpn-0.6.3 → interpn-0.6.4}/src/multicubic/mod.rs +0 -0
  72. {interpn-0.6.3 → interpn-0.6.4}/src/multicubic/rectilinear_recursive.rs +0 -0
  73. {interpn-0.6.3 → interpn-0.6.4}/src/multicubic/regular_recursive.rs +0 -0
  74. {interpn-0.6.3 → interpn-0.6.4}/src/multilinear/mod.rs +0 -0
  75. {interpn-0.6.3 → interpn-0.6.4}/src/one_dim/hold.rs +0 -0
  76. {interpn-0.6.3 → interpn-0.6.4}/src/one_dim/linear.rs +0 -0
  77. {interpn-0.6.3 → interpn-0.6.4}/src/one_dim/mod.rs +0 -0
  78. {interpn-0.6.3 → interpn-0.6.4}/src/testing.rs +0 -0
  79. {interpn-0.6.3 → interpn-0.6.4}/src/utils.rs +0 -0
  80. {interpn-0.6.3 → interpn-0.6.4}/test/test_docs.py +0 -0
  81. {interpn-0.6.3 → interpn-0.6.4}/test/test_examples.py +0 -0
  82. {interpn-0.6.3 → interpn-0.6.4}/test/test_multicubic_rectilinear.py +0 -0
  83. {interpn-0.6.3 → interpn-0.6.4}/test/test_multicubic_regular.py +0 -0
  84. {interpn-0.6.3 → interpn-0.6.4}/test/test_multilinear_rectilinear.py +0 -0
  85. {interpn-0.6.3 → interpn-0.6.4}/test/test_multilinear_regular.py +0 -0
@@ -1,5 +1,19 @@
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
+
3
17
  ## 0.6.3 2025-10-22
4
18
 
5
19
  Unpin max supported python version due to use of stable ABI3,
@@ -221,7 +221,7 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
221
221
 
222
222
  [[package]]
223
223
  name = "interpn"
224
- version = "0.6.2"
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.26.0"
358
+ version = "0.27.0"
359
359
  source = "registry+https://github.com/rust-lang/crates.io-index"
360
- checksum = "9b2dba356160b54f5371b550575b78130a54718b4c6e46b3f33a6da74a27e78b"
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.26.0"
447
+ version = "0.27.1"
448
448
  source = "registry+https://github.com/rust-lang/crates.io-index"
449
- checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383"
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.26.0"
464
+ version = "0.27.1"
465
465
  source = "registry+https://github.com/rust-lang/crates.io-index"
466
- checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f"
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.26.0"
474
+ version = "0.27.1"
475
475
  source = "registry+https://github.com/rust-lang/crates.io-index"
476
- checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105"
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.26.0"
484
+ version = "0.27.1"
485
485
  source = "registry+https://github.com/rust-lang/crates.io-index"
486
- checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded"
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.26.0"
496
+ version = "0.27.1"
497
497
  source = "registry+https://github.com/rust-lang/crates.io-index"
498
- checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf"
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.2"
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.26.0", features = ["extension-module", "abi3-py39", "generate-import-lib"], optional = true }
24
- numpy = { version = "0.26.0", optional = true }
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 }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: interpn
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -3,8 +3,8 @@
3
3
  use criterion::*;
4
4
  use gridgen::*;
5
5
  use interpn::{
6
- Linear1D, LinearHoldLast1D, MultilinearRegular, RectilinearGrid1D, RegularGrid1D, multicubic,
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
- criterion_group!(benches_extrap, bench_extrap);
463
- criterion_main!(benches_interp, benches_extrap,);
494
+ criterion_main!(benches_interp);
464
495
 
465
496
  mod randn {
466
497
  use rand::Rng;
@@ -14,6 +14,8 @@ from interpn import (
14
14
  MultilinearRegular,
15
15
  MulticubicRegular,
16
16
  MulticubicRectilinear,
17
+ NearestRegular,
18
+ NearestRectilinear,
17
19
  )
18
20
 
19
21
  # Toggle SciPy/NumPy baselines via environment for PGO workloads.
@@ -85,6 +87,8 @@ def bench_4_dims_1_obs():
85
87
  cubic_rectilinear_interpn = MulticubicRectilinear.new(
86
88
  grids, zgrid, linearize_extrapolation=True
87
89
  )
90
+ nearest_regular_interpn = NearestRegular.new(dims, starts, steps, zgrid)
91
+ nearest_rectilinear_interpn = NearestRectilinear.new(grids, zgrid)
88
92
 
89
93
  # Preallocate output for potential perf advantage
90
94
  # Allocate at eval for 1:1 comparison with Scipy
@@ -98,6 +102,10 @@ def bench_4_dims_1_obs():
98
102
  "InterpN MulticubicRectilinear": lambda p: cubic_rectilinear_interpn.eval(
99
103
  p, out
100
104
  ),
105
+ "InterpN NearestRegular": lambda p: nearest_regular_interpn.eval(p, out),
106
+ "InterpN NearestRectilinear": lambda p: nearest_rectilinear_interpn.eval(
107
+ p, out
108
+ ),
101
109
  "numpy interp": lambda p: np.interp(p[0], grids[0], zgrid), # 1D only
102
110
  }
103
111
 
@@ -111,6 +119,8 @@ def bench_4_dims_1_obs():
111
119
  "InterpN MultilinearRectilinear": points_interpn,
112
120
  "InterpN MulticubicRegular": points_interpn,
113
121
  "InterpN MulticubicRectilinear": points_interpn,
122
+ "InterpN NearestRegular": points_interpn,
123
+ "InterpN NearestRectilinear": points_interpn,
114
124
  "numpy interp": points_interpn,
115
125
  }
116
126
 
@@ -139,6 +149,8 @@ def bench_4_dims_1_obs():
139
149
  "InterpN MultilinearRectilinear": points_interpn1,
140
150
  "InterpN MulticubicRegular": points_interpn1,
141
151
  "InterpN MulticubicRectilinear": points_interpn1,
152
+ "InterpN NearestRegular": points_interpn1,
153
+ "InterpN NearestRectilinear": points_interpn1,
142
154
  "numpy interp": points_interpn1,
143
155
  }
144
156
 
@@ -167,6 +179,8 @@ def bench_4_dims_1_obs():
167
179
  "InterpN MultilinearRectilinear": points_interpn2,
168
180
  "InterpN MulticubicRegular": points_interpn2,
169
181
  "InterpN MulticubicRectilinear": points_interpn2,
182
+ "InterpN NearestRegular": points_interpn2,
183
+ "InterpN NearestRectilinear": points_interpn2,
170
184
  "numpy interp": points_interpn2,
171
185
  }
172
186
 
@@ -198,6 +212,8 @@ def bench_4_dims_1_obs():
198
212
  "InterpN MultilinearRectilinear": points_interpn3,
199
213
  "InterpN MulticubicRegular": points_interpn3,
200
214
  "InterpN MulticubicRectilinear": points_interpn3,
215
+ "InterpN NearestRegular": points_interpn3,
216
+ "InterpN NearestRectilinear": points_interpn3,
201
217
  "numpy interp": points_interpn3,
202
218
  }
203
219
 
@@ -245,6 +261,8 @@ def bench_3_dims_n_obs_unordered():
245
261
  cubic_rectilinear_interpn = MulticubicRectilinear.new(
246
262
  grids, zgrid, linearize_extrapolation=True
247
263
  )
264
+ nearest_regular_interpn = NearestRegular.new(dims, starts, steps, zgrid)
265
+ nearest_rectilinear_interpn = NearestRectilinear.new(grids, zgrid)
248
266
 
249
267
  throughputs = {
250
268
  "Scipy RegularGridInterpolator Linear": [],
@@ -253,6 +271,8 @@ def bench_3_dims_n_obs_unordered():
253
271
  "InterpN MultilinearRectilinear": [],
254
272
  "InterpN MulticubicRegular": [],
255
273
  "InterpN MulticubicRectilinear": [],
274
+ "InterpN NearestRegular": [],
275
+ "InterpN NearestRectilinear": [],
256
276
  }
257
277
  # ns = np.logspace(0, 5, 10, base=10)
258
278
  # ns = [int(x) for x in ns]
@@ -291,6 +311,12 @@ def bench_3_dims_n_obs_unordered():
291
311
  "InterpN MulticubicRectilinear": lambda p: cubic_rectilinear_interpn.eval(
292
312
  p, out
293
313
  ),
314
+ "InterpN NearestRegular": lambda p: nearest_regular_interpn.eval(
315
+ p, out
316
+ ),
317
+ "InterpN NearestRectilinear": lambda p: nearest_rectilinear_interpn.eval(
318
+ p, out
319
+ ),
294
320
  }
295
321
 
296
322
  # Interpolation in random order
@@ -303,6 +329,8 @@ def bench_3_dims_n_obs_unordered():
303
329
  "InterpN MultilinearRectilinear": points_interpn,
304
330
  "InterpN MulticubicRegular": points_interpn,
305
331
  "InterpN MulticubicRectilinear": points_interpn,
332
+ "InterpN NearestRegular": points_interpn,
333
+ "InterpN NearestRectilinear": points_interpn,
306
334
  }
307
335
 
308
336
  for name, func in interps.items():
@@ -322,6 +350,8 @@ def bench_3_dims_n_obs_unordered():
322
350
  "InterpN MultilinearRectilinear": "Linear",
323
351
  "InterpN MulticubicRegular": "Cubic",
324
352
  "InterpN MulticubicRectilinear": "Cubic",
353
+ "InterpN NearestRegular": "Linear",
354
+ "InterpN NearestRectilinear": "Linear",
325
355
  }
326
356
 
327
357
  linestyles = ["dotted", "-", "--", "-.", (0, (3, 1, 1, 1, 1, 1))]
@@ -394,6 +424,8 @@ def bench_4_dims_n_obs_unordered():
394
424
  cubic_rectilinear_interpn = MulticubicRectilinear.new(
395
425
  grids, zgrid, linearize_extrapolation=True
396
426
  )
427
+ nearest_regular_interpn = NearestRegular.new(dims, starts, steps, zgrid)
428
+ nearest_rectilinear_interpn = NearestRectilinear.new(grids, zgrid)
397
429
 
398
430
  throughputs = {
399
431
  "Scipy RegularGridInterpolator Linear": [],
@@ -402,6 +434,8 @@ def bench_4_dims_n_obs_unordered():
402
434
  "InterpN MultilinearRectilinear": [],
403
435
  "InterpN MulticubicRegular": [],
404
436
  "InterpN MulticubicRectilinear": [],
437
+ "InterpN NearestRegular": [],
438
+ "InterpN NearestRectilinear": [],
405
439
  }
406
440
  # ns = np.logspace(0, 4, 40, base=10)
407
441
  # ns = [int(x) for x in ns]
@@ -438,6 +472,12 @@ def bench_4_dims_n_obs_unordered():
438
472
  "InterpN MulticubicRectilinear": lambda p: cubic_rectilinear_interpn.eval(
439
473
  p, out
440
474
  ),
475
+ "InterpN NearestRegular": lambda p: nearest_regular_interpn.eval(
476
+ p, out
477
+ ),
478
+ "InterpN NearestRectilinear": lambda p: nearest_rectilinear_interpn.eval(
479
+ p, out
480
+ ),
441
481
  }
442
482
 
443
483
  # Interpolation in random order
@@ -450,6 +490,8 @@ def bench_4_dims_n_obs_unordered():
450
490
  "InterpN MultilinearRectilinear": points_interpn,
451
491
  "InterpN MulticubicRegular": points_interpn,
452
492
  "InterpN MulticubicRectilinear": points_interpn,
493
+ "InterpN NearestRegular": points_interpn,
494
+ "InterpN NearestRectilinear": points_interpn,
453
495
  }
454
496
 
455
497
  for name, func in interps.items():
@@ -467,6 +509,8 @@ def bench_4_dims_n_obs_unordered():
467
509
  "InterpN MultilinearRectilinear": "Linear",
468
510
  "InterpN MulticubicRegular": "Cubic",
469
511
  "InterpN MulticubicRectilinear": "Cubic",
512
+ "InterpN NearestRegular": "Linear",
513
+ "InterpN NearestRectilinear": "Linear",
470
514
  }
471
515
 
472
516
  linestyles = ["dotted", "-", "--", "-.", (0, (3, 1, 1, 1, 1, 1))]
@@ -518,6 +562,8 @@ def bench_throughput_vs_dims():
518
562
  "InterpN MultilinearRectilinear": [],
519
563
  "InterpN MulticubicRegular": [],
520
564
  "InterpN MulticubicRectilinear": [],
565
+ "InterpN NearestRegular": [],
566
+ "InterpN NearestRectilinear": [],
521
567
  "Scipy RectBivariateSpline Cubic": [], # Move to end to order plots
522
568
  "Numpy Interp": [],
523
569
  }
@@ -548,6 +594,8 @@ def bench_throughput_vs_dims():
548
594
  cubic_rectilinear_interpn = MulticubicRectilinear.new(
549
595
  grids, zgrid, linearize_extrapolation=True
550
596
  )
597
+ nearest_regular_interpn = NearestRegular.new(dims, starts, steps, zgrid)
598
+ nearest_rectilinear_interpn = NearestRectilinear.new(grids, zgrid)
551
599
 
552
600
  m = max(int(float(nobs) ** (1.0 / ndims) + 2), 2)
553
601
 
@@ -570,6 +618,8 @@ def bench_throughput_vs_dims():
570
618
  "InterpN MultilinearRectilinear": rectilinear_interpn.eval,
571
619
  "InterpN MulticubicRegular": cubic_regular_interpn.eval,
572
620
  "InterpN MulticubicRectilinear": cubic_rectilinear_interpn.eval,
621
+ "InterpN NearestRegular": nearest_regular_interpn.eval,
622
+ "InterpN NearestRectilinear": nearest_rectilinear_interpn.eval,
573
623
  }
574
624
 
575
625
  if ndims == 1:
@@ -594,6 +644,8 @@ def bench_throughput_vs_dims():
594
644
  "InterpN MultilinearRectilinear": points_interpn,
595
645
  "InterpN MulticubicRegular": points_interpn,
596
646
  "InterpN MulticubicRectilinear": points_interpn,
647
+ "InterpN NearestRegular": points_interpn,
648
+ "InterpN NearestRectilinear": points_interpn,
597
649
  "Numpy Interp": points_interpn,
598
650
  }
599
651
 
@@ -617,11 +669,13 @@ def bench_throughput_vs_dims():
617
669
  "InterpN MultilinearRectilinear": "Linear",
618
670
  "InterpN MulticubicRegular": "Cubic",
619
671
  "InterpN MulticubicRectilinear": "Cubic",
672
+ "InterpN NearestRegular": "Linear",
673
+ "InterpN NearestRectilinear": "Linear",
620
674
  "Numpy Interp": "Linear",
621
675
  }
622
676
 
623
- linestyles = ["dotted", "-", "--", "-.", (0, (3, 1, 1, 1, 1, 1))]
624
- alpha = [0.5, 1.0, 1.0, 1.0, 1.0]
677
+ linestyles = ["dotted", "-", "--", "-.", (0, (3, 1, 1, 1, 1, 1)), ":"]
678
+ alpha = [0.5, 1.0, 1.0, 1.0, 1.0, 1.0]
625
679
 
626
680
  _fig, axes = plt.subplots(1, 2, figsize=(12, 4.5), sharey=True)
627
681
  plt.suptitle(
@@ -16,6 +16,8 @@ from interpn import (
16
16
  MultilinearRegular,
17
17
  MulticubicRegular,
18
18
  MulticubicRectilinear,
19
+ NearestRegular,
20
+ NearestRectilinear,
19
21
  )
20
22
 
21
23
 
@@ -27,6 +29,8 @@ def bench_eval_mem_vs_dims():
27
29
  "InterpN MultilinearRectilinear": [],
28
30
  "InterpN MulticubicRegular": [],
29
31
  "InterpN MulticubicRectilinear": [],
32
+ "InterpN NearestRegular": [],
33
+ "InterpN NearestRectilinear": [],
30
34
  }
31
35
  ndims_to_test = [x for x in range(1, 9)]
32
36
  for ndims in ndims_to_test:
@@ -97,14 +101,14 @@ def bench_eval_mem_vs_dims():
97
101
  mems = memory_usage((func, (p,), {}), interval=1e-9, backend="psutil")
98
102
  usages[name].append(max(mems))
99
103
 
100
- kinds = {
101
- "Scipy RegularGridInterpolator Linear": "Linear",
102
- "Scipy RegularGridInterpolator Cubic": "Cubic",
103
- "InterpN MultilinearRegular": "Linear",
104
- "InterpN MultilinearRectilinear": "Linear",
105
- "InterpN MulticubicRegular": "Cubic",
106
- "InterpN MulticubicRectilinear": "Cubic",
107
- }
104
+ kinds = {
105
+ "Scipy RegularGridInterpolator Linear": "Linear",
106
+ "Scipy RegularGridInterpolator Cubic": "Cubic",
107
+ "InterpN MultilinearRegular": "Linear",
108
+ "InterpN MultilinearRectilinear": "Linear",
109
+ "InterpN MulticubicRegular": "Cubic",
110
+ "InterpN MulticubicRectilinear": "Cubic",
111
+ }
108
112
 
109
113
  linestyles = ["dotted", "-", "--", "-.", (0, (3, 1, 1, 1, 1, 1))]
110
114
  alpha = [0.5, 1.0, 1.0, 1.0, 1.0]