Skip to content

Commit efe23d8

Browse files
authored
docs: refresh README benchmarks and document the robustness contract (#9)
* docs: refresh benchmark numbers after the performance and robustness work All numbers re-measured on one machine with the scripts in examples/ against the current main (post data-structure rework, cavity repair, and PyO3 fast paths): - standalone incremental insertion: 40-291x vs the Python reference (was 17-42x before the rework; the Rust side got 2-8x faster) - LearnerND end-to-end: 3.7x vs Python LearnerND and 7x vs Learner2D at 5K points, with a note explaining why the end-to-end ratio is smaller (adaptive's own Python loss machinery dominates once the triangulation is fast) - note that numbers are machine-dependent and how they were produced Also: mention the now-supported neighbor-aware losses and the two neighbor-query methods in the API list, and add a short Robustness section describing the validate/repair/reject contract on degenerate input, pointing at src/tolerances.rs. * docs: one sentence per line in README prose Semantic line breaks instead of hard-wrapped paragraphs, so future diffs touch exactly the sentences that changed.
1 parent 6a68633 commit efe23d8

2 files changed

Lines changed: 28 additions & 11 deletions

File tree

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,39 @@
66
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
77

88
Fast N-dimensional Delaunay triangulation in Rust with Python bindings (PyO3).
9-
Drop-in replacement for [adaptive](https://github.com/python-adaptive/adaptive)'s `Triangulation` class — **5-99× faster**.
9+
Drop-in replacement for [adaptive](https://github.com/python-adaptive/adaptive)'s `Triangulation` class — **30-300× faster** standalone, **3.7×** end-to-end in `LearnerND` (where adaptive's own Python code dominates).
1010

1111
## Performance
1212

13+
Measured with the scripts in [`examples/`](examples/), best of 3 for the standalone runs.
14+
Absolute times are machine-dependent; the ratios are representative.
15+
1316
### Standalone triangulation (incremental insertion)
1417
| Case | Rust | Python | Speedup |
1518
|---|---:|---:|---:|
16-
| 2D, 1K pts | 38.5 ms | 668 ms | **17×** |
17-
| 2D, 5K pts | 260 ms | 8,547 ms | **33×** |
18-
| 3D, 500 pts | 133 ms | 5,571 ms | **42×** |
19+
| 2D, 1K pts | 18 ms | 731 ms | **40×** |
20+
| 2D, 5K pts | 134 ms | 14,611 ms | **109×** |
21+
| 3D, 500 pts | 32 ms | 3,001 ms | **94×** |
22+
| 3D, 2K pts | 152 ms | 44,262 ms | **291×** |
1923

2024
### LearnerND integration (end-to-end, `ring_of_fire` 2D)
2125
| N pts | Learner2D (scipy) | LearnerND (Python) | LearnerND (Rust) |
2226
|---|---:|---:|---:|
23-
| 1,000 | 0.34 s | 0.91 s | **0.23 s** |
24-
| 2,000 | 1.17 s | 1.80 s | **0.38 s** |
25-
| 5,000 | 6.99 s | 4.57 s | **0.99 s** |
27+
| 1,000 | 0.23 s | 0.59 s | **0.16 s** |
28+
| 2,000 | 0.90 s | 1.16 s | **0.32 s** |
29+
| 5,000 | 5.64 s | 2.95 s | **0.81 s** |
2630

27-
LearnerND + Rust is **5× faster** than LearnerND + Python, and **7× faster** than Learner2D at 5K points.
31+
LearnerND + Rust is **3.7× faster** than LearnerND + Python, and **7× faster** than Learner2D at 5K points.
32+
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.
2833

2934
## Installation
3035

3136
```bash
3237
pip install adaptive-triangulation
3338
```
3439

35-
Requires a Rust toolchain for building from source. Pre-built wheels are available for common platforms via CI.
40+
Requires a Rust toolchain for building from source.
41+
Pre-built wheels are available for common platforms via CI.
3642

3743
## Quick start
3844

@@ -67,7 +73,8 @@ lnd_mod.circumsphere = at.circumsphere
6773
lnd_mod.simplex_volume_in_embedding = at.simplex_volume_in_embedding
6874
lnd_mod.point_in_simplex = at.point_in_simplex
6975

70-
# Now use LearnerND as normal — it's 5× faster
76+
# Now use LearnerND as normal — including neighbor-aware losses
77+
# like curvature_loss_function()
7178
learner = LearnerND(my_function, bounds=[(-1, 1), (-1, 1)])
7279
```
7380

@@ -87,6 +94,8 @@ tri.volumes() # All simplex volumes
8794
tri.point_in_simplex(point, simplex) # Containment test
8895
tri.point_in_circumcircle(pt, simplex) # Circumcircle test
8996
tri.bowyer_watson(pt_index) # Direct Bowyer-Watson
97+
tri.get_opposing_vertices(simplex) # Facet neighbours' opposite vertices
98+
tri.get_simplices_attached_to_points(simplex) # Facet-sharing neighbours
9099
tri.reference_invariant() # Consistency check
91100
```
92101

@@ -112,6 +121,13 @@ from adaptive_triangulation import (
112121
- [`examples/adaptive_learnernd.py`](examples/adaptive_learnernd.py) — LearnerND integration with timing
113122
- [`examples/benchmark_vs_python.py`](examples/benchmark_vs_python.py) — Standalone benchmarks across dimensions
114123

124+
## Robustness on degenerate input
125+
126+
Point sets that mix widely separated coordinate scales force sliver simplices that no floating-point predicate can handle reliably.
127+
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`](https://crates.io/crates/robust) crate), and if even that fails the insertion raises with the triangulation untouched, so callers can skip the point and continue.
128+
Well-conditioned inputs behave identically to the reference.
129+
The full policy is documented in [`src/tolerances.rs`](src/tolerances.rs).
130+
115131
## Development
116132

117133
```bash

examples/adaptive_learnernd.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Using adaptive-triangulation with adaptive's LearnerND.
22
33
Drop-in replacement for adaptive's built-in Triangulation class,
4-
providing 5× speedup for LearnerND and 7× vs Learner2D at 5K points.
4+
providing ~3.7× end-to-end speedup for LearnerND (and ~7× vs Learner2D
5+
at 5K points); the triangulation work itself is 30-300× faster.
56
67
Requirements:
78
pip install adaptive adaptive-triangulation

0 commit comments

Comments
 (0)