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:
@@ -41,6 +41,7 @@
|
||||
// std::complex<double> reduce_to_fundamental_domain(τ) — apply SL(2,ℤ)
|
||||
|
||||
#include "layout.hpp"
|
||||
#include "discrete_elliptic_utility.hpp" // normalizeModulus (Java-faithful)
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
@@ -129,8 +130,14 @@ inline bool is_in_fundamental_domain(std::complex<double> tau, double tol = 1e-9
|
||||
// For genus-1 surfaces, also reduces τ to the fundamental domain.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
/// Compute the period data from the Euclidean holonomy translations.
|
||||
/// For genus 1, also reduces `τ` to the SL(2,ℤ) fundamental domain
|
||||
/// when `reduce` is `true` (default).
|
||||
/// For genus 1, also normalises `τ` when `reduce` is `true` (default)
|
||||
/// using `normalizeModulus` — the Java-faithful reduction
|
||||
/// (`DiscreteEllipticUtility.normalizeModulus`), which folds τ into
|
||||
/// `0 ≤ Re(τ) ≤ ½`, `Im(τ) ≥ 0`, `|τ| ≥ 1` (the extra `Re ≥ 0` fold
|
||||
/// uses the mirror symmetry `τ ≅ −τ̄`). This matches the upstream Java
|
||||
/// output exactly (Finding 6). For the canonical SL(2,ℤ) domain
|
||||
/// (`−½ ≤ Re τ < ½`, no mirror fold) call `reduce_to_fundamental_domain`
|
||||
/// on `pd.tau` instead.
|
||||
inline PeriodData compute_period_matrix(const HolonomyData& hol, bool reduce = true)
|
||||
{
|
||||
PeriodData pd;
|
||||
@@ -156,7 +163,9 @@ inline PeriodData compute_period_matrix(const HolonomyData& hol, bool reduce = t
|
||||
if (tau.imag() < 0.0) return pd; // degenerate
|
||||
|
||||
if (reduce) {
|
||||
tau = reduce_to_fundamental_domain(tau);
|
||||
// Java-faithful normalisation (Finding 6): folds τ into
|
||||
// 0 ≤ Re ≤ ½, Im ≥ 0, |τ| ≥ 1 via DiscreteEllipticUtility.normalizeModulus.
|
||||
tau = normalizeModulus(tau);
|
||||
pd.in_fundamental_domain = true;
|
||||
}
|
||||
pd.tau = tau;
|
||||
|
||||
Reference in New Issue
Block a user