You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Level 4 embedding validation (added in #449) is too slow at scale. For the 2D large-scale case (32,000 vertices -> 63,885 simplices), validation_report (Levels 1-5) takes ~190s, dominated by the Level 4 embedding narrow phase (~174s, ~89%). A secondary cost is the Euclidean Level 5 all-violations scan (~22s), tracked separately in #483. Insertion for the same case is only ~45s.
Measured L4 vs L5 split (2D, 63,885 simplices; feat/449 branch)
Per-level wall times from one validation_report run (in-test watchdog raised so it completes):
L1-3 (structure + topology): 0.20s
L4 embedding (embedding_report): 173.6s <- this issue
On the pre-#449 branch the same report ran in ~0.3s, so the new cost is the #449 Level 4 embedding check (plus the renumbered Level 5 all-violations scan; see #483).
Root cause
validate_simplex_embeddings_intersect_only_in_shared_faces (src/geometry/embedding.rs) runs an exact BigRational linear program on every AABB-overlapping candidate pair: it solves D+1 exact DxD barycentric systems and enumerates C(2(D+1), D) active-constraint sets (15/56/210/792 for D=2..5), each an exact Gaussian solve over ratios of bignums (solve_rational_system).
The sweep-and-prune broad phase (landed with #449) removes the O(S^2) AABB scan, but the dominant remaining candidate class is face-sharing neighbors (share a vertex/edge but not a full facet). Their true intersection is exactly the shared face, so the decision sits on a true-zero boundary: a float/interval prefilter is inconclusive there and falls back to exact regardless. The fix has to make the exact path fast.
Proposed approach
Fast exact narrow-phase kernel. Replace the BigRational Gaussian solver with fraction-free exact sign evaluation reusing exact_det_sign (Bareiss) - the same exact stage used by insphere/orientation. Reformulate each LP decision (feasibility >= 0, witness > 0) as a sign-of-determinant on the input coordinates. Preserve semantics and error shapes exactly.
Cheap disjointness early-out. Before any solve, a conservative f64 separating-axis test (facet normals via the existing robust orientation filter) rejects clearly-disjoint candidate pairs without exact work. Sound: a certified separating axis proves disjointness; inconclusive => proceed.
Optional Stage-1 fast filter via matrix_fast_filter -> exact_det_sign where a single determinant drives a decision. General interval arithmetic in la-stack is deferred - it would not resolve the boundary pairs.
Narrow phase to replace: validate_simplex_pair_intersection -> validate_simplex_embeddings_intersect_only_in_shared_faces (src/geometry/embedding.rs), currently exact BigRational with no f64 filter.
Predicate idiom to reuse: matrix_fast_filter (Shewchuk det+errbound, src/geometry/matrix.rs) -> exact_det_sign (Bareiss) -> degenerate fallback, as in try_orientation_from_matrix / try_insphere_from_matrix (src/geometry/predicates.rs).
Soundness / correctness
No semantic change to Level 4. Add a property test asserting the new narrow phase agrees with the current BigRational predicate on the shared domain (random + degenerate simplex pairs, 2D-5D).
Summary
Level 4 embedding validation (added in #449) is too slow at scale. For the 2D large-scale case (32,000 vertices -> 63,885 simplices),
validation_report(Levels 1-5) takes ~190s, dominated by the Level 4 embedding narrow phase (~174s, ~89%). A secondary cost is the Euclidean Level 5 all-violations scan (~22s), tracked separately in #483. Insertion for the same case is only ~45s.Measured L4 vs L5 split (2D, 63,885 simplices;
feat/449branch)Per-level wall times from one
validation_reportrun (in-test watchdog raised so it completes):embedding_report): 173.6s <- this issuedelaunay_report(Euclidean all-violations): 21.8s <- tracked in Speed up Euclidean Level 5 Delaunay validation report (O(S*V) all-violations scan) #483is_valid_delaunay(flip-based, same pass/fail): 48.8msLevel 4 is ~89% of the full-report cost; the remaining ~11% is the Euclidean Level 5 all-violations scan (#483). This issue covers Level 4 only.
Evidence
Measured on
feat/449-embedded-triangulation-validation(in-test watchdog raised so the run completes):On the pre-#449 branch the same report ran in ~0.3s, so the new cost is the #449 Level 4 embedding check (plus the renumbered Level 5 all-violations scan; see #483).
Root cause
validate_simplex_embeddings_intersect_only_in_shared_faces(src/geometry/embedding.rs) runs an exactBigRationallinear program on every AABB-overlapping candidate pair: it solvesD+1exactDxDbarycentric systems and enumeratesC(2(D+1), D)active-constraint sets (15/56/210/792 for D=2..5), each an exact Gaussian solve over ratios of bignums (solve_rational_system).The sweep-and-prune broad phase (landed with #449) removes the O(S^2) AABB scan, but the dominant remaining candidate class is face-sharing neighbors (share a vertex/edge but not a full facet). Their true intersection is exactly the shared face, so the decision sits on a true-zero boundary: a float/interval prefilter is inconclusive there and falls back to exact regardless. The fix has to make the exact path fast.
Proposed approach
BigRationalGaussian solver with fraction-free exact sign evaluation reusingexact_det_sign(Bareiss) - the same exact stage used byinsphere/orientation. Reformulate each LP decision (feasibility>= 0, witness> 0) as a sign-of-determinant on the input coordinates. Preserve semantics and error shapes exactly.matrix_fast_filter->exact_det_signwhere a single determinant drives a decision. General interval arithmetic inla-stackis deferred - it would not resolve the boundary pairs.Implementation pointers
for_each_candidate_simplex_pair(sweep-and-prune) insrc/core/embedding.rs; Euclidean charts only, periodic stays exhaustive.try_validate_full_facet_pairinsrc/core/embedding.rsalready fast-paths full-facet neighbors with tworobust_orientationtests, bypassing the barycentric solver for the adjacent-pair case.validate_simplex_pair_intersection->validate_simplex_embeddings_intersect_only_in_shared_faces(src/geometry/embedding.rs), currently exactBigRationalwith no f64 filter.matrix_fast_filter(Shewchuk det+errbound,src/geometry/matrix.rs) ->exact_det_sign(Bareiss) -> degenerate fallback, as intry_orientation_from_matrix/try_insphere_from_matrix(src/geometry/predicates.rs).Soundness / correctness
BigRationalpredicate on the shared domain (random + degenerate simplex pairs, 2D-5D).is_valid_embedding/embedding_report/validate_embeddingsurface stay unchanged.Acceptance criteria
docs/dev/perf-tuning.md; add a Level 4 embedding-validation benchmark if none exists (2D-5D, realistic + near-degenerate inputs).embedding_report()(Level 4) for the 2D 63,885-simplex case drops from ~174s to <= a few seconds.just cigreen. (Fullvalidation_reportat this scale also needs Speed up Euclidean Level 5 Delaunay validation report (O(S*V) all-violations scan) #483 to drop the ~22s Euclidean Level 5 all-violations cost.)Notes
DELAUNAY_LARGE_DEBUG_VALIDATION=construction) are on main, so this issue is unblocked and ready to start.