docs: Mathematiker-Onboarding — Theorie, Validierung, Beispiel-Meshes, 170 Tests
Ziel: einem interessierten Mathematiker ermöglichen, die bisherige Arbeit
unabhängig zu validieren und eigene Forschung beizutragen.
Neu:
doc/math/discrete-conformal-theory.md
Kompakte mathematische Einführung (DCE, Variationsprinzip, drei
Geometriemodi, Holonomie, Periodenmatrix) für Riemann-Flächen-Kenner.
doc/math/validation.md
Analytisch bekannte Sollwerte + wie man sie mit dem Code prüft:
Gauss–Bonnet (χ), τ ∈ Fundamentaldomäne (3 Invarianten), Symmetrie-
Argumente für τ=i (4-fach) und τ=e^{iπ/3} (6-fach), Newton-Konvergenz,
Gradienten-Check (FD), Holonomie-Kommutator. Reviewer-Checkliste.
CONTRIBUTING.md (Root)
Gitea/GitHub-Standard: CONTRIBUTING.md im Root-Verzeichnis als
Kurzreferenz mit Links zu doc/contributing.md und den Math-Docs.
code/data/off/torus_4x4.off — 16 Vertices, 32 Flächen, Genus 1
code/data/off/torus_8x8.off — 64 Vertices, 128 Flächen, Genus 1
code/data/off/torus_hex_6x6.off — 36 Vertices, 72 Flächen, 6-fach Sym.
Aktualisiert:
README.md — 158 → 170 Tests, zwei neue Math-Links in Tabelle
doc/api/tests.md — 28 Suiten, 170 Tests, 1 Skip (korrigiert)
doc/contributing.md — Testzähler 158+2 → 170+1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,8 +29,8 @@ All tests have CTest prefix `cgal.` (set via `TEST_PREFIX "cgal."` in CMakeLists
|
||||
| `ConformalMeshProperties` | `test_conformal_mesh.cpp` | 5 | Property maps (λ, θ, idx, α, geometry type) |
|
||||
| `ConformalMeshValidity` | `test_conformal_mesh.cpp` | 1 | CGAL validity for all factory meshes |
|
||||
| `HyperIdealFunctional` | `test_hyper_ideal_functional.cpp` | 7 | FD gradient checks + Hessian symmetry |
|
||||
| `SphericalFunctional` | `test_spherical_functional.cpp` | 12 | Angle formula + gradient + gauge-fix *(1 skipped)* |
|
||||
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 11 | Angle formula + gradient *(1 skipped)* |
|
||||
| `SphericalFunctional` | `test_spherical_functional.cpp` | 12 | Angle formula + gradient + gauge-fix |
|
||||
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 11 | Angle formula + gradient |
|
||||
| `EuclideanHessian` | `test_euclidean_hessian.cpp` | 9 | Cotangent Laplacian structure, FD agreement, PSD, null space |
|
||||
| `SphericalHessian` | `test_spherical_hessian.cpp` | 8 | Derivative correctness, NSD at equilibrium |
|
||||
| `NewtonSolver` | `test_newton_solver.cpp` | 11 | Convergence: Euclidean ×3, Spherical ×4, HyperIdeal ×4 |
|
||||
@@ -51,15 +51,16 @@ All tests have CTest prefix `cgal.` (set via `TEST_PREFIX "cgal."` in CMakeLists
|
||||
| `PeriodMatrix` | `test_phase7.cpp` | 7 | τ ∈ ℍ, SL(2,ℤ) reduction, exception outside ℍ |
|
||||
| `FundamentalDomain` | `test_phase7.cpp` | 7 | Genus-1 parallelogram CCW, generators, g > 1 empty |
|
||||
| `TilingCopy/Neighbourhood` | `test_phase7.cpp` | 4 | Translation correct, tile count |
|
||||
| `GeometryUtils` | `test_geometry_utils.cpp` | 6 | Java CuttingUtility, UnwrapUtility, ConvergenceUtility, HomologyTest ports (Tests 1–6); Test 7 GTEST_SKIP stub |
|
||||
| `CuttingUtility` | `test_geometry_utils.cpp` | 3 | point_in_triangle_2d: false, true, unit triangle (Java CuttinUtilityTest) |
|
||||
| `UnwrapUtility` | `test_geometry_utils.cpp` | 2 | corner angle: collinear → π, equilateral → π/3 (Java UnwrapUtilityTest) |
|
||||
| `ConvergenceUtility` | `test_geometry_utils.cpp` | 6 | circumradius + scale-invariant R_f/√A (Java ConvergenceUtilityTests) |
|
||||
| `HomologyGenerators` | `test_geometry_utils.cpp` | 1 | GTEST_SKIP stub — genus-2 mesh missing (Java HomologyTest Test 7, Phase 9c) |
|
||||
|
||||
**Total: 158 tests, 2 intentional skips.**
|
||||
**Total: 170 tests, 1 intentional skip.**
|
||||
|
||||
The 2 skips are:
|
||||
- `SphericalFunctional` — analytic gauge-fix stub (Phase 9b)
|
||||
- `GeometryUtils` Test 7 — genus-2 homology (Phase 9c)
|
||||
|
||||
Both correspond to Java `@Ignore`-annotated tests in the original library.
|
||||
The skip is `HomologyGenerators.Genus2_FourGeneratorPaths_BLOCKED` — blocked until
|
||||
a genus-2 mesh is available (Phase 9c). It corresponds to a Java `@Ignore`-annotated
|
||||
test in the original library.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ Two jobs run on push to `dev`/`main` or on pull requests:
|
||||
| Job | What it tests | Trigger |
|
||||
|---|---|---|
|
||||
| `test-fast` | 36 non-CGAL tests, no Boost | all branches |
|
||||
| `test-cgal` | 158 CGAL tests + 2 skips | `main`, `dev`, PRs only |
|
||||
| `test-cgal` | 170 CGAL tests + 1 skip | `main`, `dev`, PRs only |
|
||||
|
||||
A PR is ready to merge when both jobs pass.
|
||||
|
||||
@@ -51,9 +51,10 @@ Every new algorithm needs:
|
||||
|
||||
3. **Registration** — add the `.cpp` file to `code/tests/cgal/CMakeLists.txt`.
|
||||
|
||||
Expected CI result: **36 + 158 tests pass, exactly 2 skipped**.
|
||||
The 2 skips are intentional `GTEST_SKIP()` stubs for Phase 9b (analytic HyperIdeal Hessian)
|
||||
and Phase 9c (genus-2 homology). Do not remove them.
|
||||
Expected CI result: **36 + 170 tests pass, exactly 1 skipped**.
|
||||
The skip is an intentional `GTEST_SKIP()` stub for the genus-2 homology test
|
||||
(`cgal.HomologyGenerators.Genus2_FourGeneratorPaths_BLOCKED`) — blocked until a
|
||||
genus-2 mesh is available in Phase 9c. Do not remove it.
|
||||
|
||||
---
|
||||
|
||||
|
||||
175
doc/math/discrete-conformal-theory.md
Normal file
175
doc/math/discrete-conformal-theory.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Discrete Conformal Geometry — Mathematical Background
|
||||
|
||||
This document is written for a mathematician who knows Riemannian surfaces and
|
||||
complex analysis but is new to the *discrete* setting. It covers exactly the
|
||||
theory implemented in conformallab++.
|
||||
|
||||
---
|
||||
|
||||
## 1 — The continuous picture (in one paragraph)
|
||||
|
||||
A **Riemann surface** (M, g) carries a conformal structure: the class of all
|
||||
metrics related to g by a smooth positive factor. On a compact surface of genus
|
||||
g, the Uniformization Theorem gives a unique constant-curvature representative
|
||||
(flat for g = 1, hyperbolic for g ≥ 2, spherical for g = 0). The conformal
|
||||
modulus of a genus-1 surface is a point τ ∈ ℍ (upper half-plane), well-defined
|
||||
up to SL(2, ℤ).
|
||||
|
||||
---
|
||||
|
||||
## 2 — Discrete conformal equivalence (DCE)
|
||||
|
||||
A **triangulated surface** is a pair (K, ℓ) where K is a simplicial complex
|
||||
homeomorphic to a surface and ℓ: E → ℝ₊ assigns an edge length. Two
|
||||
length assignments ℓ and ℓ̃ are **discretely conformally equivalent** if there
|
||||
exist vertex weights u: V → ℝ such that
|
||||
|
||||
```
|
||||
ℓ̃ᵢⱼ = e^{(uᵢ + uⱼ)/2} · ℓᵢⱼ for every edge {i, j}.
|
||||
```
|
||||
|
||||
This is the discrete analogue of a conformal rescaling g̃ = e^{2φ} g.
|
||||
The weights u ∈ ℝ^V are the *conformal factors* (log-scale factors on vertices).
|
||||
|
||||
**Key fact** (Springborn 2020): within each DCE class there exists a unique
|
||||
length assignment realising a prescribed angle structure, and it can be found
|
||||
by Newton's method on a convex energy.
|
||||
|
||||
---
|
||||
|
||||
## 3 — The variational energy
|
||||
|
||||
For each target corner angle **Θ_v** at vertex v, define the **angle-defect energy**:
|
||||
|
||||
```
|
||||
E(u) = Σ_{corners} φ(αᵥ(u)) − Σᵥ Θᵥ · uᵥ + boundary terms
|
||||
```
|
||||
|
||||
where αᵥ(u) is the corner angle at v in the triangulation with edge lengths
|
||||
ℓ̃(u) and φ is an appropriate primitive (Clausen / Lobachevsky / ImLi₂ depending
|
||||
on geometry).
|
||||
|
||||
The **gradient** is simply the angle-sum residual:
|
||||
|
||||
```
|
||||
∂E/∂uᵥ = Σ_{faces containing v} αᵥ(face) − Θᵥ
|
||||
```
|
||||
|
||||
Setting G = 0 finds the unique u realising the prescribed angle sums.
|
||||
|
||||
### Three geometry modes
|
||||
|
||||
| Mode | Space | φ | Hessian | Newton step |
|
||||
|---|---|---|---|---|
|
||||
| Euclidean | ℝ² | Clausen Cl₂ | cotangent Laplacian, PSD | SimplicialLDLT(H) |
|
||||
| Spherical | S² | ImLi₂ | NSD (concave E) | SimplicialLDLT(−H) |
|
||||
| Hyper-ideal | H² | Lobachevsky | PSD (strictly convex) | SimplicialLDLT(H) |
|
||||
|
||||
---
|
||||
|
||||
## 4 — Gauss–Bonnet constraint
|
||||
|
||||
The target angles **must** satisfy the discrete Gauss–Bonnet equation
|
||||
|
||||
```
|
||||
Σᵥ (2π − Θᵥ) = 2π · χ(M)
|
||||
```
|
||||
|
||||
before any solver is called. If this fails, no conformal factor can realise Θ
|
||||
and Newton will not converge. conformallab++ provides:
|
||||
|
||||
```cpp
|
||||
check_gauss_bonnet(mesh, maps); // throws if violated
|
||||
enforce_gauss_bonnet(mesh, maps); // redistributes residual uniformly
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5 — From angles to geometry: trilateration
|
||||
|
||||
After Newton converges, edge lengths ℓ̃ are known. The layout
|
||||
(embedding into ℝ², S², or H²) is built by a **priority BFS**:
|
||||
|
||||
1. Place an initial face arbitrarily.
|
||||
2. For each adjacent face, place its third vertex by *trilateration* —
|
||||
solving the system of three distance equations.
|
||||
3. Priority is depth in the spanning tree (shallowest first).
|
||||
|
||||
For Euclidean geometry this is the standard cosine rule.
|
||||
For hyperbolic geometry (Poincaré disk model) it uses the Möbius-isometric
|
||||
placement formula implemented in `layout.hpp`.
|
||||
|
||||
---
|
||||
|
||||
## 6 — Cut graph and holonomy
|
||||
|
||||
For genus g ≥ 1 the layout does not close up: a handle introduces a
|
||||
**holonomy** — a non-trivial monodromy around each generator of π₁.
|
||||
|
||||
The **tree-cotree algorithm** (Erickson–Whittlesey 2005) computes a minimal
|
||||
cut graph with exactly 2g seam edges. After cutting, the surface is disk-like
|
||||
and the BFS layout is well-defined. The holonomies along the 2g cut edges are:
|
||||
|
||||
- **Euclidean:** lattice translations ω₁, ω₂ ∈ ℂ
|
||||
- **Hyperbolic:** Möbius isometries T₁, T₂ ∈ SU(1,1)
|
||||
|
||||
---
|
||||
|
||||
## 7 — Period matrix (genus 1)
|
||||
|
||||
For a torus the **conformal modulus** is
|
||||
|
||||
```
|
||||
τ = ω₂ / ω₁ ∈ ℍ
|
||||
```
|
||||
|
||||
After Euclidean uniformization, ω₁ and ω₂ are the holonomies computed from
|
||||
the seam edge displacements. The SL(2, ℤ)-reduction to the fundamental
|
||||
domain {|τ| ≥ 1, |Re(τ)| ≤ 1/2, Im(τ) > 0} is performed automatically by
|
||||
`compute_period_matrix()`.
|
||||
|
||||
For genus g ≥ 2, the Siegel period matrix Ω ∈ H_g (g×g complex symmetric with
|
||||
positive definite imaginary part) requires integrating holomorphic 1-forms — this
|
||||
is Phase 10b.
|
||||
|
||||
---
|
||||
|
||||
## 8 — Fundamental domain
|
||||
|
||||
The fundamental domain of a torus is the parallelogram with vertices
|
||||
{0, ω₁, ω₁+ω₂, ω₂} in ℂ. conformallab++ computes this and provides tiling
|
||||
utilities (`tiling_copy`, `tiling_neighbourhood`).
|
||||
|
||||
For genus g ≥ 2, the fundamental domain is the standard 4g-gon (Phase 9c).
|
||||
|
||||
---
|
||||
|
||||
## 9 — Where the code lives
|
||||
|
||||
```
|
||||
Energy / gradient code/include/*_functional.hpp
|
||||
Hessian code/include/*_hessian.hpp
|
||||
Newton solver code/include/newton_solver.hpp
|
||||
Trilateration / BFS code/include/layout.hpp
|
||||
Cut graph code/include/cut_graph.hpp
|
||||
Holonomy code/include/layout.hpp (HolonomyData)
|
||||
Period matrix code/include/period_matrix.hpp
|
||||
Fundamental domain code/include/fundamental_domain.hpp
|
||||
Möbius maps code/include/layout.hpp (MobiusMap)
|
||||
```
|
||||
|
||||
All implementations are header-only (C++17), no compiled library.
|
||||
|
||||
---
|
||||
|
||||
## 10 — Primary references
|
||||
|
||||
| Reference | Covers |
|
||||
|---|---|
|
||||
| Springborn, *Discrete Uniformization of Polyhedral Surfaces*, 2020 | Complete mathematical foundation of all three modes |
|
||||
| Sechelmann, *Variational Methods for Discrete Surface Parameterization*, TU Berlin 2016 | Original Java implementation — the direct source for this library |
|
||||
| Pinkall & Polthier, 1993 | Cotangent Laplacian |
|
||||
| Erickson & Whittlesey, SODA 2005 | Tree-cotree cut graph |
|
||||
| Bobenko & Springborn, Trans. AMS 2004 | Variational circle-pattern framework |
|
||||
|
||||
Full reference list: [doc/math/references.md](references.md)
|
||||
206
doc/math/validation.md
Normal file
206
doc/math/validation.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# 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 170 tests pass (11 skipped by design — 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.*`).
|
||||
|
||||
---
|
||||
|
||||
## 8 — Checklist for an independent reviewer
|
||||
|
||||
Run these in order to validate the implementation:
|
||||
|
||||
- [ ] `ctest --test-dir build -R cgal --output-on-failure` → 170 tests pass, 11 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.
|
||||
Reference in New Issue
Block a user