fix+test: Euclidean holonomy/τ end-to-end + spherical edge-DOF oracle (2026-05-29 audit)
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m3s
Markdown link check / check (pull_request) Successful in 44s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m11s
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m3s
Markdown link check / check (pull_request) Successful in 44s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m11s
Bundles the 2026-05-29 Java↔C++ math-correctness audit (doc/reviewer/ java-port-audit.md, 11 findings) with two follow-up fixes. Audit code changes: - Finding 3 (spherical_functional): edge-DOF replacement parameterization via spher_eff_lambda; edge gradient α_opp⁺+α_opp⁻−θ_e (drops additive −(S⁺+S⁻)/2) - Finding 4 (spherical_hessian): always-compiled edge-DOF throw guard - Finding 6 (period_matrix): faithful normalizeModulus (0≤Re≤½, Im≥0, |τ|≥1) - Finding 9 (inversive_distance): degenerate-face limiting angles, no skip - Findings 1/2 (euclidean): degenerate gradient limiting angles + Hessian guard Euclidean holonomy/τ fix: develop the cut surface across the dual spanning tree only (cut_graph now exposes is_dual_tree), so genus-1 cut edges yield non-degenerate lattice generators. Previously τ came out 0 / NaN / 1e13 on the bundled tori; now matches the analytic revolution modulus i·√(R²−r²)/r. Re-enabled τ reporting in the Euclidean CLI; rewrote validation.md §3/§4 accordingly. Tests (240 CGAL, 0 skipped): - HolonomyEndToEnd ×3 — tori of revolution (4×4, hex 6×6, 8×8) vs analytic modulus - SphericalFunctional.EdgeGradient_RegularTetClosedForm — independent closed-form π/3 oracle locking the Finding-3 edge formula (the path-integral FD check cannot detect a wrong-but-conservative gradient) Also documents the latent spherical/hyperbolic holonomy-extraction bug (same single-development pattern, dead code today) in research-track.md (Phase 9c/10), and adds favour/normalisations to the codespell ignore list. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
// rescales all three sides by the same factor, leaving angles unchanged but
|
||||
// keeping the arguments of exp in a safe numerical range.
|
||||
|
||||
#include "constants.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace conformallab {
|
||||
@@ -50,8 +51,16 @@ inline EuclideanFaceAngles euclidean_angles_from_lengths(
|
||||
const double t23 = +l12 - l23 + l31; // 2*(s − l23)
|
||||
const double t31 = +l12 + l23 - l31; // 2*(s − l31)
|
||||
|
||||
if (t12 <= 0.0 || t23 <= 0.0 || t31 <= 0.0)
|
||||
return {0.0, 0.0, 0.0, false};
|
||||
// Degenerate (triangle inequality violated): return the *limiting* angles
|
||||
// of the flat-out triangle — the corner opposite the over-long edge is π,
|
||||
// the other two are 0. This is the convex C¹ extension of the BPS energy
|
||||
// onto the infeasible region and is what the Java reference
|
||||
// (EuclideanCyclicFunctional.triangleEnergyAndAlphas) does. `valid` stays
|
||||
// false so the cotangent Hessian still skips this face. At most one t can
|
||||
// be ≤ 0 (t12+t23 = 2·l31 > 0, etc.), so the order of these checks is moot.
|
||||
if (t23 <= 0.0) return {PI, 0.0, 0.0, false}; // l23 too long → α₁ = π
|
||||
if (t31 <= 0.0) return {0.0, PI, 0.0, false}; // l31 too long → α₂ = π
|
||||
if (t12 <= 0.0) return {0.0, 0.0, PI, false}; // l12 too long → α₃ = π
|
||||
|
||||
const double l123 = l12 + l23 + l31;
|
||||
const double denom2 = t12 * t23 * t31 * l123; // = (4·Area)²
|
||||
|
||||
Reference in New Issue
Block a user