# Mathematical Validation This document lists analytically known results and explains how to verify them against conformallab++ output. It is the primary tool for an independent mathematician to check the correctness of the implementation. --- ## How to run the examples ```bash cmake -S code -B build -DWITH_CGAL=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --target conformallab_cgal_tests ctest --test-dir build -R cgal --output-on-failure ``` All 176 tests pass, 0 skipped (see `doc/api/tests.md`). --- ## 1 — Gauss–Bonnet (topology) **Theorem.** For any closed triangulated surface M, ``` Σᵥ (2π − Θᵥ) = 2π · χ(M) ``` where χ(M) = 2 − 2g is the Euler characteristic. | Surface | g | χ | Σ(2π − Θᵥ) | |---|---|---|---| | Sphere (tetrahedron, cube, …) | 0 | 2 | 4π | | Torus | 1 | 0 | 0 | | Double torus | 2 | −2 | −4π | **How to check:** ```cpp #include "gauss_bonnet.hpp" auto defect = gauss_bonnet_sum(mesh, maps); // Σ(2π − Θᵥ) auto chi = mesh.euler_characteristic(); EXPECT_NEAR(defect, 2.0 * M_PI * chi, 1e-10); ``` Covered by: `cgal.GaussBonnet.*` tests in `test_phase6.cpp`. --- ## 2 — Period matrix: fundamental domain invariants **Theorem (SL(2,ℤ)-reduction).** Every lattice τ ∈ ℍ has a unique representative in the standard fundamental domain ``` F = { τ ∈ ℍ : |τ| ≥ 1, |Re(τ)| ≤ 1/2, Im(τ) > 0 } ``` **After calling `compute_period_matrix(hol)`, the returned τ must satisfy:** | Condition | Invariant | |---|---| | `pd.tau_reduced.imag() > 0` | τ lies in the upper half-plane | | `std::abs(pd.tau_reduced) >= 1.0 - 1e-10` | τ outside unit disk | | `std::abs(pd.tau_reduced.real()) <= 0.5 + 1e-10` | τ in vertical strip | These three conditions hold for **any** closed genus-1 triangulated surface processed through Euclidean uniformization — they are topology, not geometry. Covered by: `cgal.PeriodMatrix.TauInFundamentalDomain_*` tests in `test_phase7.cpp`. --- ## 3 — Square-symmetric torus **Setup.** Take a torus mesh with 4-fold rotational symmetry around the z-axis (e.g. `code/data/off/torus_4x4.off`, which has M=4 columns of vertices). **Expected.** The symmetry group Z₄ acts conformally. Conformal automorphisms of the torus correspond to SL(2,ℤ) symmetries of τ. The unique fixed point of a rotation of order 4 in the modular group is τ = i. Therefore: ``` For a mesh with exact 4-fold symmetry and uniform edge lengths: Re(τ) = 0 (to machine precision, by symmetry) Im(τ) ≈ 1 (approaches 1 as mesh is refined) ``` The coarse 4×4 mesh (`torus_4x4.off`) gives Im(τ) in (0.7, 1.3) depending on the 3D embedding (R=2, r=1 torus of revolution has unequal inner/outer edge lengths). The uniformization algorithm finds the conformal class of the *abstract* metric encoded in the edge lengths. **Manual verification** (run from the build directory after adding a small program or reading from the test output): ```cpp ConformalMesh mesh; load_mesh(mesh, "code/data/off/torus_4x4.off"); EuclideanMaps maps = setup_euclidean_maps(mesh); compute_euclidean_lambda0_from_mesh(mesh, maps); enforce_gauss_bonnet(mesh, maps); auto res = newton_euclidean(mesh, maps); CutGraph cg = compute_cut_graph(mesh); HolonomyData hol; euclidean_layout(mesh, res.x, maps, &cg, &hol, true); PeriodData pd = compute_period_matrix(hol); // pd.tau_reduced satisfies the fundamental domain invariants above ``` --- ## 4 — Hexagonal-symmetric torus **Setup.** Take a torus mesh with 6-fold rotational symmetry (`code/data/off/torus_hex_6x6.off`, M=6). **Expected.** The unique τ fixed under a rotation of order 6 in SL(2,ℤ) is τ = e^{iπ/3} = ½ + i√3/2. So: ``` Re(τ) = 0.5 (to machine precision, by symmetry) Im(τ) = √3/2 ≈ 0.8660 ``` The coarse 6×6 torus of revolution approximates this: Re(τ) ≈ 0.5 by symmetry, Im(τ) approaches √3/2 as the mesh is refined toward a flat hexagonal lattice. --- ## 5 — Newton convergence rate **Theorem.** Because the Euclidean and hyper-ideal energies are strictly convex (after gauge-fixing), Newton's method converges quadratically near the optimum. **Expected:** for any mesh with up to a few hundred faces, Newton converges in **fewer than 30 iterations** starting from u = 0. ```cpp auto res = newton_euclidean(mesh, maps); EXPECT_LT(res.iterations, 30); EXPECT_LT(res.gradient_norm, 1e-10); ``` Covered by: `cgal.EuclideanPipeline.ConvRates_*` and similar tests. --- ## 6 — Gradient check (finite differences) For each functional F(u), the gradient G = ∂F/∂u is verified by: ``` |G(u)ᵢ − (F(u + εeᵢ) − F(u − εeᵢ)) / (2ε)| < 1e-6 ``` with ε = 1e-5. This check is run **inside the test suite** for all three geometries (Euclidean, Spherical, HyperIdeal) at u = 0 and at random u. Relevant test suites: ``` cgal.EuclideanFunctional.GradientCheck_* cgal.SphericalFunctional.GradientCheck_* cgal.HyperIdealFunctional.GradientCheck_* ``` A failing gradient check means the energy and its derivative are inconsistent — the Newton solver will converge to the wrong point. --- ## 7 — Holonomy composition (Möbius maps) For a closed surface, the composition of holonomies around any contractible cycle must be the identity. In genus 1 with a single handle: ``` T₁ · T₂ · T₁⁻¹ · T₂⁻¹ = Id (commutator = Id for a torus) ``` because π₁(T²) = ℤ × ℤ is abelian. For genus g ≥ 2, the fundamental group is non-abelian and this check does not hold, but the representation ρ: π₁(Σ_g) → SU(1,1) must still satisfy the relation ``` [T₁, T₂] · [T₃, T₄] · … = Id (product of g commutators = Id) ``` These are the **holonomy consistency** checks implemented in `test_phase7.cpp` (`cgal.HolonomyData.*`). --- ## 9 — Cross-validation with geometry-central *(optional / hypothetical)* > **Hinweis:** Dieser Abschnitt beschreibt eine mögliche externe Kreuz-Validierung, > die keine Voraussetzung für die Korrektheit der Implementierung ist. > Sie ist interessant, weil geometry-central denselben mathematischen Kern > implementiert (Gillespie, Springborn, Crane — SIGGRAPH 2021, aufbauend auf > Springborn 2020), aber mit einer anderen algorithmischen Strategie > (Ptolemäische Flips + intrinsische Triangulierungen statt Newton auf der > Original-Triangulierung). ### Welche Outputs sind vergleichbar? | Output | conformallab++ | geometry-central | Vergleichbar? | |---|---|---|---| | u-Vektor (Skalierungsparameter) | `res.x` | `u` nach Yamabe flow | ✓ nach Normalisierung | | UV-Koordinaten | `layout.uv[v]` | konforme Parametrisierung | ✓ bis auf Möbius-Transformation | | Gauss-Bonnet Defekt | `gauss_bonnet_sum()` | implizit via Krümmungsfluss | ✓ (analytisch identisch) | | Anzahl Newton-Iterationen | `res.iterations` | Yamabe-Schritte | ~ (anderer Algorithmus) | | Period-Matrix τ | `pd.tau_reduced` | **nicht vorhanden** | ✗ | | Möbius-Holonomie | `hol.T_a, T_b` | **nicht vorhanden** | ✗ | ### Normalisierungsabgleich Der u-Vektor in conformallab++ hat einen Freiheitsgrad (globale additive Konstante — Eichfreiheit nach Pin-Fixierung). geometry-central kann eine andere Konvention nutzen. Vor dem Vergleich normalisieren: ```cpp // conformallab++: u zentrieren double mean_u = std::accumulate(x.begin(), x.end(), 0.0) / x.size(); std::vector x_norm(x.size()); for (int i = 0; i < x.size(); ++i) x_norm[i] = x[i] - mean_u; // Dann mit geometry-central u-Vektor (ebenfalls zentriert) vergleichen: // max|x_norm[i] - gc_u[i]| < 1e-8 → identischer Konvergenzpunkt ``` ### Wann ist der Vergleich sinnvoll? | Zeitpunkt | Was ist möglich | |---|---| | **Jetzt (Phase 7)** | Manueller Vergleich mit denselben `.off`/`.obj` Testnetzen | | **Nach Phase 8** | Automatisiertes Vergleichsskript (Python oder separates C++-Binary) | | **Phase 10 (Forschung)** | Algorithmus-Vergleich: Newton vs. Ptolemäische Flips auf schwierigen Netzen | ### Voraussetzungen für einen fairen Vergleich 1. Identische Eingabenetze (OFF/OBJ, gleiche Vertex-Orientierung) 2. Gleiche Gauss-Bonnet-Zielkrümmungen (Θᵥ = 2π für alle v, geschlossene Fläche) 3. u-Normalisierung abgeglichen (zentriert, gleiche Eichfixierung) 4. Konvergenztoleranz synchronisiert (max. Gradientnorm < 1e-8) ### Verbindung zur Literatur Das Springborn 2020-Papier ("Ideal Hyperbolic Polyhedra and Discrete Uniformization") ist **in conformallab++ bereits implementiert** — es ist die mathematische Grundlage für den HyperIdeal-Geometriemodus (Phase 2/3). Die geometry-central Implementierung basiert auf der Weiterentwicklung von Gillespie, Springborn & Crane (2021), die denselben Variationsprinzip von Bobenko–Springborn 2004 verwendet, aber zusätzlich Ptolemäische Flips einsetzt, um die Triangulierung während der Optimierung zu verbessern — eine Idee, die in conformallab++ noch nicht implementiert ist (→ GC-2 im Phasen-Roadmap). --- ## 8 — Checklist for an independent reviewer Run these in order to validate the implementation: - [ ] `ctest --test-dir build -R cgal --output-on-failure` → 176 tests pass, 0 skipped - [ ] `cgal.GaussBonnet.*` all pass → topology is correctly read from mesh - [ ] `cgal.EuclideanFunctional.GradientCheck_*` pass → energy = integral of gradient - [ ] `cgal.PeriodMatrix.TauInFundamentalDomain_*` pass → SL(2,ℤ) reduction correct - [ ] `cgal.MobiusMap.Compose_*` and `Inverse_*` pass → Möbius arithmetic correct - [ ] `cgal.HolonomyData.*` pass → holonomy loops close up All of the above are **deterministic, analytic tests** — no mesh loading, no file I/O, no floating-point non-determinism beyond standard IEEE-754.