convinterp 0.1.0__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.
@@ -0,0 +1,5 @@
1
+ # Compile for the processor of this machine, including its fused multiply-add (FMA) instruction.
2
+ # Fine for local development and benchmarks; published wheels will need a portable baseline
3
+ # instead (a decision for later).
4
+ [build]
5
+ rustflags = ["-C", "target-cpu=native", "-C", "symbol-mangling-version=v0"]
@@ -0,0 +1,186 @@
1
+ # Generated by maturin v1.15.0 (maturin generate-ci github), then adapted for convinterp:
2
+ # - RUSTFLAGS per platform: a portable CPU baseline instead of .cargo/config.toml's target-cpu=native
3
+ # (x86-64-v3 on x86_64: AVX2 and FMA, every Intel and AMD processor since about 2015)
4
+ # - 64-bit platforms only, all with hardware fused multiply-add
5
+ # - trusted publishing to PyPI: no stored token
6
+ name: CI
7
+
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ - master
13
+ tags:
14
+ - '*'
15
+ pull_request:
16
+ workflow_dispatch:
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ linux:
23
+ runs-on: ${{ matrix.platform.runner }}
24
+ strategy:
25
+ matrix:
26
+ platform:
27
+ - runner: ubuntu-22.04
28
+ target: x86_64
29
+ rustflags: -C target-cpu=x86-64-v3
30
+ - runner: ubuntu-22.04
31
+ target: aarch64
32
+ rustflags: -C symbol-mangling-version=v0
33
+ steps:
34
+ - uses: actions/checkout@v6
35
+ - uses: actions/setup-python@v6
36
+ with:
37
+ python-version: "3.9"
38
+ - name: Build wheels
39
+ uses: PyO3/maturin-action@v1
40
+ env:
41
+ RUSTFLAGS: ${{ matrix.platform.rustflags }}
42
+ with:
43
+ target: ${{ matrix.platform.target }}
44
+ args: --release --out dist --find-interpreter
45
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
46
+ manylinux: auto
47
+ - name: Upload wheels
48
+ uses: actions/upload-artifact@v6
49
+ with:
50
+ name: wheels-linux-${{ matrix.platform.target }}
51
+ path: dist
52
+
53
+ musllinux:
54
+ runs-on: ${{ matrix.platform.runner }}
55
+ strategy:
56
+ matrix:
57
+ platform:
58
+ - runner: ubuntu-22.04
59
+ target: x86_64
60
+ rustflags: -C target-cpu=x86-64-v3
61
+ - runner: ubuntu-22.04
62
+ target: aarch64
63
+ rustflags: -C symbol-mangling-version=v0
64
+ steps:
65
+ - uses: actions/checkout@v6
66
+ - uses: actions/setup-python@v6
67
+ with:
68
+ python-version: "3.9"
69
+ - name: Build wheels
70
+ uses: PyO3/maturin-action@v1
71
+ env:
72
+ RUSTFLAGS: ${{ matrix.platform.rustflags }}
73
+ with:
74
+ target: ${{ matrix.platform.target }}
75
+ args: --release --out dist --find-interpreter
76
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
77
+ manylinux: musllinux_1_2
78
+ - name: Upload wheels
79
+ uses: actions/upload-artifact@v6
80
+ with:
81
+ name: wheels-musllinux-${{ matrix.platform.target }}
82
+ path: dist
83
+
84
+ windows:
85
+ runs-on: ${{ matrix.platform.runner }}
86
+ strategy:
87
+ matrix:
88
+ platform:
89
+ - runner: windows-latest
90
+ target: x64
91
+ python_arch: x64
92
+ rustflags: -C target-cpu=x86-64-v3
93
+ - runner: windows-11-arm
94
+ target: aarch64
95
+ python_arch: arm64
96
+ rustflags: -C symbol-mangling-version=v0
97
+ steps:
98
+ - uses: actions/checkout@v6
99
+ - uses: actions/setup-python@v6
100
+ with:
101
+ python-version: "3.13"
102
+ architecture: ${{ matrix.platform.python_arch }}
103
+ - name: Build wheels
104
+ uses: PyO3/maturin-action@v1
105
+ env:
106
+ RUSTFLAGS: ${{ matrix.platform.rustflags }}
107
+ with:
108
+ target: ${{ matrix.platform.target }}
109
+ args: --release --out dist --find-interpreter
110
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
111
+ - name: Upload wheels
112
+ uses: actions/upload-artifact@v6
113
+ with:
114
+ name: wheels-windows-${{ matrix.platform.target }}
115
+ path: dist
116
+
117
+ macos:
118
+ runs-on: ${{ matrix.platform.runner }}
119
+ strategy:
120
+ matrix:
121
+ platform:
122
+ - runner: macos-15-intel
123
+ target: x86_64
124
+ rustflags: -C target-cpu=x86-64-v3
125
+ - runner: macos-latest
126
+ target: aarch64
127
+ rustflags: -C symbol-mangling-version=v0
128
+ steps:
129
+ - uses: actions/checkout@v6
130
+ - uses: actions/setup-python@v6
131
+ with:
132
+ python-version: "3.9"
133
+ - name: Build wheels
134
+ uses: PyO3/maturin-action@v1
135
+ env:
136
+ RUSTFLAGS: ${{ matrix.platform.rustflags }}
137
+ with:
138
+ target: ${{ matrix.platform.target }}
139
+ args: --release --out dist --find-interpreter
140
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
141
+ - name: Upload wheels
142
+ uses: actions/upload-artifact@v6
143
+ with:
144
+ name: wheels-macos-${{ matrix.platform.target }}
145
+ path: dist
146
+
147
+ sdist:
148
+ runs-on: ubuntu-latest
149
+ steps:
150
+ - uses: actions/checkout@v6
151
+ - name: Build sdist
152
+ uses: PyO3/maturin-action@v1
153
+ with:
154
+ command: sdist
155
+ args: --out dist
156
+ - name: Upload sdist
157
+ uses: actions/upload-artifact@v6
158
+ with:
159
+ name: wheels-sdist
160
+ path: dist
161
+
162
+ release:
163
+ name: Release
164
+ runs-on: ubuntu-latest
165
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
166
+ needs: [linux, musllinux, windows, macos, sdist]
167
+ permissions:
168
+ # Used for trusted publishing to PyPI and to sign the release artifacts
169
+ id-token: write
170
+ # Used to upload release artifacts
171
+ contents: write
172
+ # Used to generate artifact attestation
173
+ attestations: write
174
+ steps:
175
+ - uses: actions/download-artifact@v7
176
+ - name: Generate artifact attestation
177
+ uses: actions/attest@v4
178
+ with:
179
+ subject-path: 'wheels-*/*'
180
+ - name: Install uv
181
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
182
+ uses: astral-sh/setup-uv@v7
183
+ - name: Publish to PyPI
184
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
185
+ # trusted publishing: uv authenticates with the id-token GitHub issues to this job
186
+ run: uv publish 'wheels-*/*'
@@ -0,0 +1,11 @@
1
+ # Rust build output
2
+ target/
3
+ # Python virtual environment and caches
4
+ .venv/
5
+ __pycache__/
6
+ .pytest_cache/
7
+ # compiled extension module and its debug symbols (rebuilt by maturin develop)
8
+ *.pyd
9
+ *.pdb
10
+ *.so
11
+ check_python.py
@@ -0,0 +1,254 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "bytemuck"
13
+ version = "1.25.2"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
16
+
17
+ [[package]]
18
+ name = "convinterp"
19
+ version = "0.1.0"
20
+ dependencies = [
21
+ "numpy",
22
+ "pyo3",
23
+ "wide",
24
+ ]
25
+
26
+ [[package]]
27
+ name = "heck"
28
+ version = "0.5.0"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
31
+
32
+ [[package]]
33
+ name = "libc"
34
+ version = "0.2.189"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
37
+
38
+ [[package]]
39
+ name = "matrixmultiply"
40
+ version = "0.3.11"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "3f607c237553f086e7043417a51df26b2eb899d3caff94e6a67592ff992fedc7"
43
+ dependencies = [
44
+ "autocfg",
45
+ "rawpointer",
46
+ ]
47
+
48
+ [[package]]
49
+ name = "ndarray"
50
+ version = "0.17.2"
51
+ source = "registry+https://github.com/rust-lang/crates.io-index"
52
+ checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d"
53
+ dependencies = [
54
+ "matrixmultiply",
55
+ "num-complex",
56
+ "num-integer",
57
+ "num-traits",
58
+ "portable-atomic",
59
+ "portable-atomic-util",
60
+ "rawpointer",
61
+ ]
62
+
63
+ [[package]]
64
+ name = "num-complex"
65
+ version = "0.4.6"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
68
+ dependencies = [
69
+ "num-traits",
70
+ ]
71
+
72
+ [[package]]
73
+ name = "num-integer"
74
+ version = "0.1.47"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b"
77
+ dependencies = [
78
+ "num-traits",
79
+ ]
80
+
81
+ [[package]]
82
+ name = "num-traits"
83
+ version = "0.2.19"
84
+ source = "registry+https://github.com/rust-lang/crates.io-index"
85
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
86
+ dependencies = [
87
+ "autocfg",
88
+ ]
89
+
90
+ [[package]]
91
+ name = "numpy"
92
+ version = "0.29.0"
93
+ source = "registry+https://github.com/rust-lang/crates.io-index"
94
+ checksum = "6a5b15d63a5ff39e378daed0e1340d3a5964703ea9712eb09a0dc66fade996f4"
95
+ dependencies = [
96
+ "libc",
97
+ "ndarray",
98
+ "num-complex",
99
+ "num-integer",
100
+ "num-traits",
101
+ "pyo3",
102
+ "pyo3-build-config",
103
+ "rustc-hash",
104
+ ]
105
+
106
+ [[package]]
107
+ name = "once_cell"
108
+ version = "1.21.4"
109
+ source = "registry+https://github.com/rust-lang/crates.io-index"
110
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
111
+
112
+ [[package]]
113
+ name = "portable-atomic"
114
+ version = "1.15.0"
115
+ source = "registry+https://github.com/rust-lang/crates.io-index"
116
+ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
117
+
118
+ [[package]]
119
+ name = "portable-atomic-util"
120
+ version = "0.2.8"
121
+ source = "registry+https://github.com/rust-lang/crates.io-index"
122
+ checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715"
123
+ dependencies = [
124
+ "portable-atomic",
125
+ ]
126
+
127
+ [[package]]
128
+ name = "proc-macro2"
129
+ version = "1.0.107"
130
+ source = "registry+https://github.com/rust-lang/crates.io-index"
131
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
132
+ dependencies = [
133
+ "unicode-ident",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "pyo3"
138
+ version = "0.29.2"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b"
141
+ dependencies = [
142
+ "libc",
143
+ "once_cell",
144
+ "portable-atomic",
145
+ "pyo3-build-config",
146
+ "pyo3-ffi",
147
+ "pyo3-macros",
148
+ ]
149
+
150
+ [[package]]
151
+ name = "pyo3-build-config"
152
+ version = "0.29.2"
153
+ source = "registry+https://github.com/rust-lang/crates.io-index"
154
+ checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"
155
+ dependencies = [
156
+ "target-lexicon",
157
+ ]
158
+
159
+ [[package]]
160
+ name = "pyo3-ffi"
161
+ version = "0.29.2"
162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
163
+ checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327"
164
+ dependencies = [
165
+ "libc",
166
+ "pyo3-build-config",
167
+ ]
168
+
169
+ [[package]]
170
+ name = "pyo3-macros"
171
+ version = "0.29.2"
172
+ source = "registry+https://github.com/rust-lang/crates.io-index"
173
+ checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c"
174
+ dependencies = [
175
+ "proc-macro2",
176
+ "pyo3-macros-backend",
177
+ "quote",
178
+ "syn",
179
+ ]
180
+
181
+ [[package]]
182
+ name = "pyo3-macros-backend"
183
+ version = "0.29.2"
184
+ source = "registry+https://github.com/rust-lang/crates.io-index"
185
+ checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952"
186
+ dependencies = [
187
+ "heck",
188
+ "proc-macro2",
189
+ "quote",
190
+ "syn",
191
+ ]
192
+
193
+ [[package]]
194
+ name = "quote"
195
+ version = "1.0.47"
196
+ source = "registry+https://github.com/rust-lang/crates.io-index"
197
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
198
+ dependencies = [
199
+ "proc-macro2",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "rawpointer"
204
+ version = "0.2.1"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
207
+
208
+ [[package]]
209
+ name = "rustc-hash"
210
+ version = "2.1.3"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
213
+
214
+ [[package]]
215
+ name = "safe_arch"
216
+ version = "1.2.0"
217
+ source = "registry+https://github.com/rust-lang/crates.io-index"
218
+ checksum = "42c6efa15875e6ecb39ca61fb0b0c1a40b84fac5a5ffe71eef7d1000c8eb3f5f"
219
+ dependencies = [
220
+ "bytemuck",
221
+ ]
222
+
223
+ [[package]]
224
+ name = "syn"
225
+ version = "2.0.119"
226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
227
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
228
+ dependencies = [
229
+ "proc-macro2",
230
+ "quote",
231
+ "unicode-ident",
232
+ ]
233
+
234
+ [[package]]
235
+ name = "target-lexicon"
236
+ version = "0.13.5"
237
+ source = "registry+https://github.com/rust-lang/crates.io-index"
238
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
239
+
240
+ [[package]]
241
+ name = "unicode-ident"
242
+ version = "1.0.26"
243
+ source = "registry+https://github.com/rust-lang/crates.io-index"
244
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
245
+
246
+ [[package]]
247
+ name = "wide"
248
+ version = "1.7.1"
249
+ source = "registry+https://github.com/rust-lang/crates.io-index"
250
+ checksum = "d920ac99c3c8edce110cb8d07dbb324d6d026011dce85b1e9355b70f0adacc4f"
251
+ dependencies = [
252
+ "bytemuck",
253
+ "safe_arch",
254
+ ]
@@ -0,0 +1,23 @@
1
+ # The Rust package. Cargo is Rust's build tool and package manager, like Julia's Pkg.
2
+ [package]
3
+ name = "convinterp"
4
+ version = "0.1.0"
5
+ edition = "2021" # the Rust language edition (a stable set of language rules)
6
+ description = "Rust core of convinterp: high-order convolution interpolation on uniform grids"
7
+ license = "MIT"
8
+ repository = "https://github.com/NikoBiele/convinterp"
9
+ readme = "README.md"
10
+
11
+ [lib]
12
+ name = "_core" # the compiled module; Python imports it as convinterp._core
13
+ crate-type = ["cdylib"] # build a shared library that Python can load
14
+
15
+ [dependencies]
16
+ pyo3 = "0.29" # Rust ↔ Python bindings
17
+ numpy = "0.29" # NumPy arrays in Rust (must match the PyO3 version)
18
+ wide = "1.7" # explicit SIMD: f64x4 is four doubles in one vector register
19
+
20
+ # Release builds (maturin develop --release, and the published wheels)
21
+ [profile.release]
22
+ lto = true # link-time optimization: optimize across crates (pyo3, wide, ndarray)
23
+ codegen-units = 1 # compile as one unit, so the optimizer sees the whole crate at once
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nikolaj Maack Bielefeld
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.4
2
+ Name: convinterp
3
+ Version: 0.1.0
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Science/Research
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Rust
8
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
9
+ Requires-Dist: numpy
10
+ Requires-Dist: pytest ; extra == 'test'
11
+ Requires-Dist: juliacall ; extra == 'test'
12
+ Provides-Extra: test
13
+ License-File: LICENSE
14
+ Summary: High-order convolution interpolation and derivatives on uniform grids in any dimension, with a Rust core
15
+ Keywords: interpolation,convolution,derivatives,numerical methods,scientific computing
16
+ Author: Nikolaj Maack Bielefeld
17
+ License-Expression: MIT
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
20
+ Project-URL: Homepage, https://convinterp.org
21
+ Project-URL: Julia package, https://github.com/NikoBiele/ConvolutionInterpolations.jl
22
+ Project-URL: Repository, https://github.com/NikoBiele/convinterp
23
+
24
+ # convinterp
25
+
26
+ High-order convolution interpolation on uniform grids in any number of dimensions, with
27
+ derivatives, for Python. The core is written in Rust; the kernels are exact polynomials.
28
+
29
+ convinterp is a port of the Julia package
30
+ [ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), by the
31
+ same author, and is tested against it.
32
+
33
+ **Status: alpha.** Interpolation and derivatives on uniform grids work in any dimension.
34
+ Integrals and scattered data are coming.
35
+
36
+ ## Installation
37
+
38
+ ```
39
+ pip install convinterp
40
+ ```
41
+
42
+ ## Example
43
+
44
+ ```python
45
+ import numpy as np
46
+ from convinterp import convolution_interpolation
47
+
48
+ # 1D: data on a uniform grid
49
+ x = np.linspace(0.0, 2 * np.pi, 50) # 50 uniformly spaced knots
50
+ itp = convolution_interpolation(x, np.sin(x)) # the interpolant of sin(x)
51
+ print(itp(1.0)) # ≈ sin(1) = 0.841471
52
+
53
+ # derivatives: one order for the whole interpolant
54
+ d_itp = convolution_interpolation(x, np.sin(x), derivative=1)
55
+ print(d_itp(1.0)) # ≈ cos(1) = 0.540302
56
+
57
+ # 2D: one knot array per axis, and data whose axis d runs along knots[d]
58
+ y = np.linspace(0.0, 1.0, 30) # knots of the second axis
59
+ data = np.sin(x)[:, None] * np.exp(y)[None, :] # sin(x)·exp(y) on the 50 × 30 grid
60
+ itp2 = convolution_interpolation((x, y), data) # the 2D interpolant
61
+ print(itp2(1.0, 0.5)) # ≈ sin(1)·exp(0.5) = 1.387351
62
+
63
+ # a mixed derivative, with an order per axis: ∂²/∂x∂y
64
+ dxy = convolution_interpolation((x, y), data, derivative=(1, 1))
65
+ print(dxy(1.0, 0.5)) # ≈ cos(1)·exp(0.5) = 0.890808
66
+
67
+ # arrays of points broadcast like NumPy arrays: here a 3 × 4 table of values
68
+ xs = np.array([[0.5], [1.0], [1.5]]) # a column of x coordinates
69
+ ys = np.array([[0.1, 0.2, 0.3, 0.4]]) # a row of y coordinates
70
+ print(itp2(xs, ys).shape) # (3, 4)
71
+ ```
72
+
73
+ ## Kernels
74
+
75
+ `kernel="auto"` (the default) chooses by the number of dimensions: `"b7"` in 1D and 2D, `"b5"` in
76
+ 3D, and narrower kernels beyond. You can choose any of:
77
+
78
+ | kernel | order of accuracy | highest derivative |
79
+ |---|---|---|
80
+ | `"a0"` | nearest neighbour | none |
81
+ | `"a1"` | linear | none |
82
+ | `"a3"`, `"a4"`, `"a5"`, `"a7"` | cubic and higher | 1 |
83
+ | `"b5"`, `"b7"`, `"b9"`, `"b11"`, `"b13"` | high order | 3 to 7 |
84
+
85
+ ## Boundary conditions
86
+
87
+ The data are extended beyond each boundary by extrapolation: `bc="detect"` (the default) uses
88
+ polynomial extrapolation where the data near the boundary allow it and linear otherwise. You can
89
+ also choose `"poly"`, `"linear"` or `"quadratic"`, separately for each side and each axis.
90
+
91
+ ## Declaration of AI Assistance
92
+
93
+ The Rust core and much of the Python code of convinterp were written with substantial assistance
94
+ from Claude (Anthropic). The mathematical methods, the kernels and the reference implementation
95
+ come from the author's Julia package
96
+ [ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), and the
97
+ port is validated against it: the test suite compares convinterp with the Julia package across
98
+ kernels, boundary conditions, derivative orders and dimensions, with the boundary coefficients
99
+ agreeing bit for bit. The author has reviewed and is responsible for all code.
100
+
101
+ ## License
102
+
103
+ MIT
@@ -0,0 +1,80 @@
1
+ # convinterp
2
+
3
+ High-order convolution interpolation on uniform grids in any number of dimensions, with
4
+ derivatives, for Python. The core is written in Rust; the kernels are exact polynomials.
5
+
6
+ convinterp is a port of the Julia package
7
+ [ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), by the
8
+ same author, and is tested against it.
9
+
10
+ **Status: alpha.** Interpolation and derivatives on uniform grids work in any dimension.
11
+ Integrals and scattered data are coming.
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ pip install convinterp
17
+ ```
18
+
19
+ ## Example
20
+
21
+ ```python
22
+ import numpy as np
23
+ from convinterp import convolution_interpolation
24
+
25
+ # 1D: data on a uniform grid
26
+ x = np.linspace(0.0, 2 * np.pi, 50) # 50 uniformly spaced knots
27
+ itp = convolution_interpolation(x, np.sin(x)) # the interpolant of sin(x)
28
+ print(itp(1.0)) # ≈ sin(1) = 0.841471
29
+
30
+ # derivatives: one order for the whole interpolant
31
+ d_itp = convolution_interpolation(x, np.sin(x), derivative=1)
32
+ print(d_itp(1.0)) # ≈ cos(1) = 0.540302
33
+
34
+ # 2D: one knot array per axis, and data whose axis d runs along knots[d]
35
+ y = np.linspace(0.0, 1.0, 30) # knots of the second axis
36
+ data = np.sin(x)[:, None] * np.exp(y)[None, :] # sin(x)·exp(y) on the 50 × 30 grid
37
+ itp2 = convolution_interpolation((x, y), data) # the 2D interpolant
38
+ print(itp2(1.0, 0.5)) # ≈ sin(1)·exp(0.5) = 1.387351
39
+
40
+ # a mixed derivative, with an order per axis: ∂²/∂x∂y
41
+ dxy = convolution_interpolation((x, y), data, derivative=(1, 1))
42
+ print(dxy(1.0, 0.5)) # ≈ cos(1)·exp(0.5) = 0.890808
43
+
44
+ # arrays of points broadcast like NumPy arrays: here a 3 × 4 table of values
45
+ xs = np.array([[0.5], [1.0], [1.5]]) # a column of x coordinates
46
+ ys = np.array([[0.1, 0.2, 0.3, 0.4]]) # a row of y coordinates
47
+ print(itp2(xs, ys).shape) # (3, 4)
48
+ ```
49
+
50
+ ## Kernels
51
+
52
+ `kernel="auto"` (the default) chooses by the number of dimensions: `"b7"` in 1D and 2D, `"b5"` in
53
+ 3D, and narrower kernels beyond. You can choose any of:
54
+
55
+ | kernel | order of accuracy | highest derivative |
56
+ |---|---|---|
57
+ | `"a0"` | nearest neighbour | none |
58
+ | `"a1"` | linear | none |
59
+ | `"a3"`, `"a4"`, `"a5"`, `"a7"` | cubic and higher | 1 |
60
+ | `"b5"`, `"b7"`, `"b9"`, `"b11"`, `"b13"` | high order | 3 to 7 |
61
+
62
+ ## Boundary conditions
63
+
64
+ The data are extended beyond each boundary by extrapolation: `bc="detect"` (the default) uses
65
+ polynomial extrapolation where the data near the boundary allow it and linear otherwise. You can
66
+ also choose `"poly"`, `"linear"` or `"quadratic"`, separately for each side and each axis.
67
+
68
+ ## Declaration of AI Assistance
69
+
70
+ The Rust core and much of the Python code of convinterp were written with substantial assistance
71
+ from Claude (Anthropic). The mathematical methods, the kernels and the reference implementation
72
+ come from the author's Julia package
73
+ [ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), and the
74
+ port is validated against it: the test suite compares convinterp with the Julia package across
75
+ kernels, boundary conditions, derivative orders and dimensions, with the boundary coefficients
76
+ agreeing bit for bit. The author has reviewed and is responsible for all code.
77
+
78
+ ## License
79
+
80
+ MIT