Files
ConformalLabpp/doc/math/validation.md
Tarik Moussa d25f3cafe6
All checks were successful
C++ Tests / test-fast (push) Successful in 2m1s
C++ Tests / test-cgal (push) Has been skipped
docs: geometry-central Vergleich als optionalen Track einarbeiten
- phases.md: neue Sektion "Optional/Hypothetisch — geometry-central
  Cross-Comparison" mit GC-1 (Output-Vergleich, sofort möglich),
  GC-2 (Intrinsic Delaunay Pre-Conditioning, nach Phase 8) und
  GC-3 (Ptolemäischer Flip-Solver, hypothetisch Phase 10+)
- validation.md: neuer Abschnitt 9 mit Vergleichstabelle, Normalisierungs-
  abgleich, Zeitplan und Springborn-2020-Einordnung
- references.md: Gillespie–Springborn–Crane SIGGRAPH 2021 + Sharp 2019
  als geometry-central-Referenzen eingetragen; Klarstellung zu Springborn 2020
- validation.md: Testzähler 170→173 / 11 skips→1 skip korrigiert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 01:56:16 +02:00

9.5 KiB
Raw Blame History

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

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 173 tests pass (1 skipped by design — see doc/api/tests.md).


1 — GaussBonnet (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
Torus 1 0 0
Double torus 2 2

How to check:

#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):

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.

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:

// conformallab++: u zentrieren
double mean_u = std::accumulate(x.begin(), x.end(), 0.0) / x.size();
std::vector<double> 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 BobenkoSpringborn 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 → 173 tests pass, 1 skip
  • 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.