Rust numerical geometry
This optional extension accelerates numerical search geometry. The Python algebraic certificate checker remains independent and does not import it.
From the project root:
uv sync --extra native --locked
uv run --extra native python -m experiments.baseline \
--seconds 30 --seeds 31 47 83 \
--output .research-cache/guarded-rust
The normal backend is auto: Rust when the extension is installed, otherwise
the existing Python/SciPy implementation. Require Rust, or explicitly compare
the reference implementation, with:
SCISSORS_GEOMETRY_BACKEND=rust uv run --extra native python -m experiments.baseline --output .research-cache/required-rust
SCISSORS_GEOMETRY_BACKEND=python uv run --extra native python -m experiments.baseline --output .research-cache/reference-python
rust reports an installation error when the extension is missing. It still
allows a recorded per-operation Python fallback for a numerically inconsistent
native mesh. Search reports include the effective backend, kernel version,
operation counts, and fallback reasons. Numerical cells with cached native
geometry have read-only arrays; construct a new cell instead of mutating one.
The extension uses PyO3 and maturin, with Python 3.11+
ABI support. Rust 1.75 is the tested minimum toolchain. Cargo.lock and the root
uv.lock pin dependencies. uv tracks Cargo manifests, the lockfile, and Rust
source changes through explicit cache keys,
so the next uv sync --extra native or uv run --extra native rebuilds changed
native code. An already-running Python process needs restarting after a rebuild.
Kernel and trust boundary
- Initial unconstrained hulls still use SciPy/Qhull.
- Native cells retain polygon-face connectivity. Plane clipping and bisection clip those faces and add a cap, avoiding a fresh hull at each cut.
- Intersection and difference execute the sequence of cuts in Rust. A disjoint cutter returns the original cell rather than unnecessary subdivisions.
- Rigid transforms reuse the topology and volume.
- The kernel checks closed boundaries, finite data, supporting planes, and
bisection volume ledgers. Numerical degeneracies raise
GeometryError, which the bridge counts and retries with the retained reference implementation. - Sampling, optimization, and numerical geometry remain proposal machinery.
Rust uses
f64, the existing 1e-9 classification tolerance, and 1e-12 vertex welding. Mesh triangulation and near-boundary floating results need not be bit-for-bit identical to Qhull. Neither backend proves exact congruence. - The handoff replays rational construction recipes in the original exact number field. Only the unchanged Python checker accepts certificates.
Checks and measurements
uv run --extra native python -m unittest discover -s tests -p 'test_*.py'
SCISSORS_GEOMETRY_BACKEND=python uv run --extra native python -m unittest discover -s tests -p 'test_*.py'
uv run --extra native python -m experiments.benchmark_native_geometry \
--repeats 5 --output .research-cache/rust-benchmark.json
cargo fmt --manifest-path native/Cargo.toml --check
cargo test --manifest-path native/Cargo.toml --locked
cargo clippy --manifest-path native/Cargo.toml --locked -- -D warnings
If Cargo cannot locate Python, set PYO3_PYTHON to the absolute path of the
project's .venv/bin/python when running Cargo tests or Clippy. uv supplies
the interpreter automatically when building the extension.
The benchmark excludes input construction, warms both backends, repeats identical workloads, and checks volume agreement and partition ledgers before writing its report. See measured results.