Fast N-dimensional Delaunay triangulation with incremental point insertion
Project description
adaptive-triangulation
Fast N-dimensional Delaunay triangulation in Rust with Python bindings (PyO3).
Drop-in replacement for adaptive's Triangulation class — 30-300× faster standalone, 3.7× end-to-end in LearnerND (where adaptive's own Python code dominates).
Performance
Measured with the scripts in examples/, best of 3 for the standalone runs.
Absolute times are machine-dependent; the ratios are representative.
Standalone triangulation (incremental insertion)
| Case | Rust | Python | Speedup |
|---|---|---|---|
| 2D, 1K pts | 18 ms | 731 ms | 40× |
| 2D, 5K pts | 134 ms | 14,611 ms | 109× |
| 3D, 500 pts | 32 ms | 3,001 ms | 94× |
| 3D, 2K pts | 152 ms | 44,262 ms | 291× |
LearnerND integration (end-to-end, ring_of_fire 2D)
| N pts | Learner2D (scipy) | LearnerND (Python) | LearnerND (Rust) |
|---|---|---|---|
| 1,000 | 0.23 s | 0.59 s | 0.16 s |
| 2,000 | 0.90 s | 1.16 s | 0.32 s |
| 5,000 | 5.64 s | 2.95 s | 0.81 s |
LearnerND + Rust is 3.7× faster than LearnerND + Python, and 7× faster than Learner2D at 5K points. The end-to-end ratio is smaller than the standalone one because adaptive's own Python-side loss machinery dominates once the triangulation is fast.
Installation
pip install adaptive-triangulation
Requires a Rust toolchain for building from source. Pre-built wheels are available for common platforms via CI.
Quick start
from adaptive_triangulation import Triangulation
# Build a 2D triangulation
tri = Triangulation([(0, 0), (1, 0), (0, 1), (1, 1)])
# Insert points incrementally (Bowyer-Watson)
deleted, added = tri.add_point((0.5, 0.5))
# Query properties
print(len(tri.simplices)) # number of triangles
print(tri.dim) # 2
print(tri.reference_invariant()) # True
Usage with adaptive's LearnerND
This is a drop-in replacement for adaptive's built-in triangulation.
Monkey-patch the module to use Rust triangulation everywhere:
import adaptive_triangulation as at
from adaptive.learner import learnerND as lnd_mod
from adaptive.learner.learnerND import LearnerND
# Replace both the class and standalone functions
lnd_mod.Triangulation = at.Triangulation
lnd_mod.circumsphere = at.circumsphere
lnd_mod.simplex_volume_in_embedding = at.simplex_volume_in_embedding
lnd_mod.point_in_simplex = at.point_in_simplex
# Now use LearnerND as normal — including neighbor-aware losses
# like curvature_loss_function()
learner = LearnerND(my_function, bounds=[(-1, 1), (-1, 1)])
See examples/adaptive_learnernd.py for a full working example with timing comparison.
API
Triangulation class
tri = Triangulation(coords) # Build from initial points
tri.add_point(point) # Incremental insertion → (deleted, added)
tri.locate_point(point) # Find containing simplex
tri.circumscribed_circle(simplex) # → (center, radius)
tri.volume(simplex) # Simplex volume
tri.volumes() # All simplex volumes
tri.point_in_simplex(point, simplex) # Containment test
tri.point_in_circumcircle(pt, simplex) # Circumcircle test
tri.bowyer_watson(pt_index) # Direct Bowyer-Watson
tri.get_opposing_vertices(simplex) # Facet neighbours' opposite vertices
tri.get_simplices_attached_to_points(simplex) # Facet-sharing neighbours
tri.reference_invariant() # Consistency check
Properties: vertices, simplices, vertex_to_simplices, hull, dim, default_transform
Standalone functions
from adaptive_triangulation import (
circumsphere, # General circumsphere
fast_2d_circumcircle, # Optimized 2D
fast_3d_circumsphere, # Optimized 3D
point_in_simplex, # Containment test
volume, # Simplex volume
simplex_volume_in_embedding, # Volume in embedding space
orientation, # Face orientation
)
Examples
examples/basic_usage.py— Core API walkthroughexamples/adaptive_learnernd.py— LearnerND integration with timingexamples/benchmark_vs_python.py— Standalone benchmarks across dimensions
Robustness on degenerate input
Point sets that mix widely separated coordinate scales force sliver simplices that no floating-point predicate can handle reliably.
Unlike the Python reference (which can corrupt its state on such input), this implementation validates every insertion before mutating: a cavity that cannot be re-triangulated is first repaired with exact predicates (Shewchuk's, via the robust crate), and if even that fails the insertion raises with the triangulation untouched, so callers can skip the point and continue.
Well-conditioned inputs behave identically to the reference.
The full policy is documented in src/tolerances.rs.
Development
# Build (requires Rust toolchain)
pip install maturin
maturin develop --release
# Tests
cargo test # Rust tests
python -m pytest tests/ -v # Python tests
# Linting
pre-commit run --all-files # ruff, mypy, cargo fmt, cargo clippy
License
BSD-3-Clause
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adaptive_triangulation-0.2.1.tar.gz.
File metadata
- Download URL: adaptive_triangulation-0.2.1.tar.gz
- Upload date:
- Size: 101.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
664cf2c4da60908705c0f6f9c150288a739892905a5e4f8b0fde63a46fba4f87
|
|
| MD5 |
ecee3b951064312f63f4e658c21e0543
|
|
| BLAKE2b-256 |
1d87c2173a0efb00d1b3507d035c2f7ff4bc30250a7c8837a8d5f9b4e288af97
|
Provenance
The following attestation bundles were made for adaptive_triangulation-0.2.1.tar.gz:
Publisher:
ci.yml on python-adaptive/adaptive-triangulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adaptive_triangulation-0.2.1.tar.gz -
Subject digest:
664cf2c4da60908705c0f6f9c150288a739892905a5e4f8b0fde63a46fba4f87 - Sigstore transparency entry: 1782930862
- Sigstore integration time:
-
Permalink:
python-adaptive/adaptive-triangulation@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/python-adaptive
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adaptive_triangulation-0.2.1-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: adaptive_triangulation-0.2.1-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 381.4 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb9a78743118a139ef11437a4adce2187c3de2c18ca8682c3d06b32258b11e52
|
|
| MD5 |
adb497fc1b92915c5eefedde3cf0abed
|
|
| BLAKE2b-256 |
9be9033ea183d5273baf6c101fa1c337d4bc841b7ca75f430c69b12c447de50d
|
Provenance
The following attestation bundles were made for adaptive_triangulation-0.2.1-cp310-abi3-win_amd64.whl:
Publisher:
ci.yml on python-adaptive/adaptive-triangulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adaptive_triangulation-0.2.1-cp310-abi3-win_amd64.whl -
Subject digest:
fb9a78743118a139ef11437a4adce2187c3de2c18ca8682c3d06b32258b11e52 - Sigstore transparency entry: 1782931010
- Sigstore integration time:
-
Permalink:
python-adaptive/adaptive-triangulation@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/python-adaptive
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adaptive_triangulation-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: adaptive_triangulation-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 450.4 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b64a8b17e2a83a28626c866fd57e6d5efbb7814fd6999dee211b61354db31bee
|
|
| MD5 |
7e9763001cae6e1df2014d9c17895828
|
|
| BLAKE2b-256 |
99bb2437866dec8e5fa2393227f2fa2164b65f66d1cd63cd659fb469f7447e98
|
Provenance
The following attestation bundles were made for adaptive_triangulation-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
ci.yml on python-adaptive/adaptive-triangulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adaptive_triangulation-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
b64a8b17e2a83a28626c866fd57e6d5efbb7814fd6999dee211b61354db31bee - Sigstore transparency entry: 1782931118
- Sigstore integration time:
-
Permalink:
python-adaptive/adaptive-triangulation@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/python-adaptive
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adaptive_triangulation-0.2.1-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: adaptive_triangulation-0.2.1-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 415.8 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8c8b3880b8f06c6dab0307e69a2a6fdc4c95f605a048befd5bb01bf1adb3166
|
|
| MD5 |
f1f5a361fc0316ba8eee14ec18a39860
|
|
| BLAKE2b-256 |
a71397aef8c00962449b4457bbfa0073494b6abdfce9ee3e103e0a5e06388aeb
|
Provenance
The following attestation bundles were made for adaptive_triangulation-0.2.1-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
ci.yml on python-adaptive/adaptive-triangulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adaptive_triangulation-0.2.1-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
f8c8b3880b8f06c6dab0307e69a2a6fdc4c95f605a048befd5bb01bf1adb3166 - Sigstore transparency entry: 1782930934
- Sigstore integration time:
-
Permalink:
python-adaptive/adaptive-triangulation@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/python-adaptive
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c6d6de40a5ceba54e9fd381fa809407a94c0e625 -
Trigger Event:
push
-
Statement type: