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:
17
CONTRIBUTING.md
Normal file
17
CONTRIBUTING.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Contributing to conformallab++
|
||||||
|
|
||||||
|
See **[doc/contributing.md](doc/contributing.md)** for the full guide:
|
||||||
|
|
||||||
|
- Git workflow (dev → PR → main)
|
||||||
|
- CI pipeline (test-fast / test-cgal)
|
||||||
|
- Test standards (gradient check, convergence test, registration)
|
||||||
|
- Code style (C++17, header-only, namespace, property map naming)
|
||||||
|
- Release process
|
||||||
|
|
||||||
|
For the mathematical background of what's being implemented, see:
|
||||||
|
|
||||||
|
- [doc/math/discrete-conformal-theory.md](doc/math/discrete-conformal-theory.md) — theory overview
|
||||||
|
- [doc/math/validation.md](doc/math/validation.md) — how to validate the implementation
|
||||||
|
- [doc/math/references.md](doc/math/references.md) — all referenced papers
|
||||||
|
|
||||||
|
To add your own research, see [doc/api/extending.md](doc/api/extending.md).
|
||||||
@@ -9,7 +9,7 @@ Algorithmic foundation:
|
|||||||
> DOI: [10.14279/depositonce-5415](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f) · CC BY-SA 4.0 ·
|
> DOI: [10.14279/depositonce-5415](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f) · CC BY-SA 4.0 ·
|
||||||
> [Java original](https://github.com/varylab/conformallab) · [sechel.de](https://sechel.de/)
|
> [Java original](https://github.com/varylab/conformallab) · [sechel.de](https://sechel.de/)
|
||||||
|
|
||||||
**Status:** Phase 7 complete. Newton solver for all three geometries (Euclidean / Spherical / HyperIdeal), priority-BFS layout in ℝ²/S²/Poincaré disk, Gauss–Bonnet, tree-cotree cut graph, Möbius holonomy, period matrix (genus 1), fundamental domain, halfedge_uv texture atlas, JSON/XML serialisation, CLI app. **158 CGAL tests + 36 non-CGAL tests.**
|
**Status:** Phase 7 complete. Newton solver for all three geometries (Euclidean / Spherical / HyperIdeal), priority-BFS layout in ℝ²/S²/Poincaré disk, Gauss–Bonnet, tree-cotree cut graph, Möbius holonomy, period matrix (genus 1), fundamental domain, halfedge_uv texture atlas, JSON/XML serialisation, CLI app. **170 CGAL tests + 36 non-CGAL tests.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -76,13 +76,15 @@ Layout2D layout = euclidean_layout(mesh, res.x, maps);
|
|||||||
| **Getting started** — build modes, single-test invocation, CLI, Docker | [doc/getting-started.md](doc/getting-started.md) |
|
| **Getting started** — build modes, single-test invocation, CLI, Docker | [doc/getting-started.md](doc/getting-started.md) |
|
||||||
| **Pipeline API** — all three geometries, holonomy, serialisation | [doc/api/pipeline.md](doc/api/pipeline.md) |
|
| **Pipeline API** — all three geometries, holonomy, serialisation | [doc/api/pipeline.md](doc/api/pipeline.md) |
|
||||||
| **Public headers** — all 24 headers with descriptions | [doc/api/headers.md](doc/api/headers.md) |
|
| **Public headers** — all 24 headers with descriptions | [doc/api/headers.md](doc/api/headers.md) |
|
||||||
| **Test suites** — 26 suites, 158 tests, individual counts | [doc/api/tests.md](doc/api/tests.md) |
|
| **Test suites** — 28 suites, 170 tests, individual counts | [doc/api/tests.md](doc/api/tests.md) |
|
||||||
| **Extending** — new functionals, geometry modes, porting from Java | [doc/api/extending.md](doc/api/extending.md) |
|
| **Extending** — new functionals, geometry modes, porting from Java | [doc/api/extending.md](doc/api/extending.md) |
|
||||||
| **Processing unit contracts** — preconditions / provides table | [doc/api/contracts.md](doc/api/contracts.md) |
|
| **Processing unit contracts** — preconditions / provides table | [doc/api/contracts.md](doc/api/contracts.md) |
|
||||||
| **CGAL package design** — Phase 8 target, YAML pipeline | [doc/api/cgal-package.md](doc/api/cgal-package.md) |
|
| **CGAL package design** — Phase 8 target, YAML pipeline | [doc/api/cgal-package.md](doc/api/cgal-package.md) |
|
||||||
| **Architecture & pipeline diagram** | [doc/architecture/overall_pipeline.md](doc/architecture/overall_pipeline.md) |
|
| **Architecture & pipeline diagram** | [doc/architecture/overall_pipeline.md](doc/architecture/overall_pipeline.md) |
|
||||||
| **Design decisions** — key architectural choices + rationale | [doc/architecture/design-decisions.md](doc/architecture/design-decisions.md) |
|
| **Design decisions** — key architectural choices + rationale | [doc/architecture/design-decisions.md](doc/architecture/design-decisions.md) |
|
||||||
| **Project structure** — directory tree + build targets | [doc/architecture/project-structure.md](doc/architecture/project-structure.md) |
|
| **Project structure** — directory tree + build targets | [doc/architecture/project-structure.md](doc/architecture/project-structure.md) |
|
||||||
|
| **Discrete conformal theory** — mathematical background for collaborators | [doc/math/discrete-conformal-theory.md](doc/math/discrete-conformal-theory.md) |
|
||||||
|
| **Validation** — known analytic results + how to verify them | [doc/math/validation.md](doc/math/validation.md) |
|
||||||
| **Geometry modes** — Euclidean / Spherical / HyperIdeal comparison | [doc/math/geometry-modes.md](doc/math/geometry-modes.md) |
|
| **Geometry modes** — Euclidean / Spherical / HyperIdeal comparison | [doc/math/geometry-modes.md](doc/math/geometry-modes.md) |
|
||||||
| **References** — all papers by module | [doc/math/references.md](doc/math/references.md) |
|
| **References** — all papers by module | [doc/math/references.md](doc/math/references.md) |
|
||||||
| **Roadmap** — Phases 1–10 | [doc/roadmap/phases.md](doc/roadmap/phases.md) |
|
| **Roadmap** — Phases 1–10 | [doc/roadmap/phases.md](doc/roadmap/phases.md) |
|
||||||
|
|||||||
50
code/data/off/torus_4x4.off
Normal file
50
code/data/off/torus_4x4.off
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
OFF
|
||||||
|
16 32 0
|
||||||
|
3.000000 0.000000 0.000000
|
||||||
|
2.000000 0.000000 1.000000
|
||||||
|
1.000000 0.000000 0.000000
|
||||||
|
2.000000 0.000000 -1.000000
|
||||||
|
0.000000 3.000000 0.000000
|
||||||
|
0.000000 2.000000 1.000000
|
||||||
|
0.000000 1.000000 0.000000
|
||||||
|
0.000000 2.000000 -1.000000
|
||||||
|
-3.000000 0.000000 0.000000
|
||||||
|
-2.000000 0.000000 1.000000
|
||||||
|
-1.000000 0.000000 0.000000
|
||||||
|
-2.000000 0.000000 -1.000000
|
||||||
|
-0.000000 -3.000000 0.000000
|
||||||
|
-0.000000 -2.000000 1.000000
|
||||||
|
-0.000000 -1.000000 0.000000
|
||||||
|
-0.000000 -2.000000 -1.000000
|
||||||
|
3 0 4 1
|
||||||
|
3 1 4 5
|
||||||
|
3 1 5 2
|
||||||
|
3 2 5 6
|
||||||
|
3 2 6 3
|
||||||
|
3 3 6 7
|
||||||
|
3 3 7 0
|
||||||
|
3 0 7 4
|
||||||
|
3 4 8 5
|
||||||
|
3 5 8 9
|
||||||
|
3 5 9 6
|
||||||
|
3 6 9 10
|
||||||
|
3 6 10 7
|
||||||
|
3 7 10 11
|
||||||
|
3 7 11 4
|
||||||
|
3 4 11 8
|
||||||
|
3 8 12 9
|
||||||
|
3 9 12 13
|
||||||
|
3 9 13 10
|
||||||
|
3 10 13 14
|
||||||
|
3 10 14 11
|
||||||
|
3 11 14 15
|
||||||
|
3 11 15 8
|
||||||
|
3 8 15 12
|
||||||
|
3 12 0 13
|
||||||
|
3 13 0 1
|
||||||
|
3 13 1 14
|
||||||
|
3 14 1 2
|
||||||
|
3 14 2 15
|
||||||
|
3 15 2 3
|
||||||
|
3 15 3 12
|
||||||
|
3 12 3 0
|
||||||
194
code/data/off/torus_8x8.off
Normal file
194
code/data/off/torus_8x8.off
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
OFF
|
||||||
|
64 128 0
|
||||||
|
4.000000 0.000000 0.000000
|
||||||
|
3.707107 0.000000 0.707107
|
||||||
|
3.000000 0.000000 1.000000
|
||||||
|
2.292893 0.000000 0.707107
|
||||||
|
2.000000 0.000000 0.000000
|
||||||
|
2.292893 0.000000 -0.707107
|
||||||
|
3.000000 0.000000 -1.000000
|
||||||
|
3.707107 0.000000 -0.707107
|
||||||
|
2.828427 2.828427 0.000000
|
||||||
|
2.621320 2.621320 0.707107
|
||||||
|
2.121320 2.121320 1.000000
|
||||||
|
1.621320 1.621320 0.707107
|
||||||
|
1.414214 1.414214 0.000000
|
||||||
|
1.621320 1.621320 -0.707107
|
||||||
|
2.121320 2.121320 -1.000000
|
||||||
|
2.621320 2.621320 -0.707107
|
||||||
|
0.000000 4.000000 0.000000
|
||||||
|
0.000000 3.707107 0.707107
|
||||||
|
0.000000 3.000000 1.000000
|
||||||
|
0.000000 2.292893 0.707107
|
||||||
|
0.000000 2.000000 0.000000
|
||||||
|
0.000000 2.292893 -0.707107
|
||||||
|
0.000000 3.000000 -1.000000
|
||||||
|
0.000000 3.707107 -0.707107
|
||||||
|
-2.828427 2.828427 0.000000
|
||||||
|
-2.621320 2.621320 0.707107
|
||||||
|
-2.121320 2.121320 1.000000
|
||||||
|
-1.621320 1.621320 0.707107
|
||||||
|
-1.414214 1.414214 0.000000
|
||||||
|
-1.621320 1.621320 -0.707107
|
||||||
|
-2.121320 2.121320 -1.000000
|
||||||
|
-2.621320 2.621320 -0.707107
|
||||||
|
-4.000000 0.000000 0.000000
|
||||||
|
-3.707107 0.000000 0.707107
|
||||||
|
-3.000000 0.000000 1.000000
|
||||||
|
-2.292893 0.000000 0.707107
|
||||||
|
-2.000000 0.000000 0.000000
|
||||||
|
-2.292893 0.000000 -0.707107
|
||||||
|
-3.000000 0.000000 -1.000000
|
||||||
|
-3.707107 0.000000 -0.707107
|
||||||
|
-2.828427 -2.828427 0.000000
|
||||||
|
-2.621320 -2.621320 0.707107
|
||||||
|
-2.121320 -2.121320 1.000000
|
||||||
|
-1.621320 -1.621320 0.707107
|
||||||
|
-1.414214 -1.414214 0.000000
|
||||||
|
-1.621320 -1.621320 -0.707107
|
||||||
|
-2.121320 -2.121320 -1.000000
|
||||||
|
-2.621320 -2.621320 -0.707107
|
||||||
|
-0.000000 -4.000000 0.000000
|
||||||
|
-0.000000 -3.707107 0.707107
|
||||||
|
-0.000000 -3.000000 1.000000
|
||||||
|
-0.000000 -2.292893 0.707107
|
||||||
|
-0.000000 -2.000000 0.000000
|
||||||
|
-0.000000 -2.292893 -0.707107
|
||||||
|
-0.000000 -3.000000 -1.000000
|
||||||
|
-0.000000 -3.707107 -0.707107
|
||||||
|
2.828427 -2.828427 0.000000
|
||||||
|
2.621320 -2.621320 0.707107
|
||||||
|
2.121320 -2.121320 1.000000
|
||||||
|
1.621320 -1.621320 0.707107
|
||||||
|
1.414214 -1.414214 0.000000
|
||||||
|
1.621320 -1.621320 -0.707107
|
||||||
|
2.121320 -2.121320 -1.000000
|
||||||
|
2.621320 -2.621320 -0.707107
|
||||||
|
3 0 8 1
|
||||||
|
3 1 8 9
|
||||||
|
3 1 9 2
|
||||||
|
3 2 9 10
|
||||||
|
3 2 10 3
|
||||||
|
3 3 10 11
|
||||||
|
3 3 11 4
|
||||||
|
3 4 11 12
|
||||||
|
3 4 12 5
|
||||||
|
3 5 12 13
|
||||||
|
3 5 13 6
|
||||||
|
3 6 13 14
|
||||||
|
3 6 14 7
|
||||||
|
3 7 14 15
|
||||||
|
3 7 15 0
|
||||||
|
3 0 15 8
|
||||||
|
3 8 16 9
|
||||||
|
3 9 16 17
|
||||||
|
3 9 17 10
|
||||||
|
3 10 17 18
|
||||||
|
3 10 18 11
|
||||||
|
3 11 18 19
|
||||||
|
3 11 19 12
|
||||||
|
3 12 19 20
|
||||||
|
3 12 20 13
|
||||||
|
3 13 20 21
|
||||||
|
3 13 21 14
|
||||||
|
3 14 21 22
|
||||||
|
3 14 22 15
|
||||||
|
3 15 22 23
|
||||||
|
3 15 23 8
|
||||||
|
3 8 23 16
|
||||||
|
3 16 24 17
|
||||||
|
3 17 24 25
|
||||||
|
3 17 25 18
|
||||||
|
3 18 25 26
|
||||||
|
3 18 26 19
|
||||||
|
3 19 26 27
|
||||||
|
3 19 27 20
|
||||||
|
3 20 27 28
|
||||||
|
3 20 28 21
|
||||||
|
3 21 28 29
|
||||||
|
3 21 29 22
|
||||||
|
3 22 29 30
|
||||||
|
3 22 30 23
|
||||||
|
3 23 30 31
|
||||||
|
3 23 31 16
|
||||||
|
3 16 31 24
|
||||||
|
3 24 32 25
|
||||||
|
3 25 32 33
|
||||||
|
3 25 33 26
|
||||||
|
3 26 33 34
|
||||||
|
3 26 34 27
|
||||||
|
3 27 34 35
|
||||||
|
3 27 35 28
|
||||||
|
3 28 35 36
|
||||||
|
3 28 36 29
|
||||||
|
3 29 36 37
|
||||||
|
3 29 37 30
|
||||||
|
3 30 37 38
|
||||||
|
3 30 38 31
|
||||||
|
3 31 38 39
|
||||||
|
3 31 39 24
|
||||||
|
3 24 39 32
|
||||||
|
3 32 40 33
|
||||||
|
3 33 40 41
|
||||||
|
3 33 41 34
|
||||||
|
3 34 41 42
|
||||||
|
3 34 42 35
|
||||||
|
3 35 42 43
|
||||||
|
3 35 43 36
|
||||||
|
3 36 43 44
|
||||||
|
3 36 44 37
|
||||||
|
3 37 44 45
|
||||||
|
3 37 45 38
|
||||||
|
3 38 45 46
|
||||||
|
3 38 46 39
|
||||||
|
3 39 46 47
|
||||||
|
3 39 47 32
|
||||||
|
3 32 47 40
|
||||||
|
3 40 48 41
|
||||||
|
3 41 48 49
|
||||||
|
3 41 49 42
|
||||||
|
3 42 49 50
|
||||||
|
3 42 50 43
|
||||||
|
3 43 50 51
|
||||||
|
3 43 51 44
|
||||||
|
3 44 51 52
|
||||||
|
3 44 52 45
|
||||||
|
3 45 52 53
|
||||||
|
3 45 53 46
|
||||||
|
3 46 53 54
|
||||||
|
3 46 54 47
|
||||||
|
3 47 54 55
|
||||||
|
3 47 55 40
|
||||||
|
3 40 55 48
|
||||||
|
3 48 56 49
|
||||||
|
3 49 56 57
|
||||||
|
3 49 57 50
|
||||||
|
3 50 57 58
|
||||||
|
3 50 58 51
|
||||||
|
3 51 58 59
|
||||||
|
3 51 59 52
|
||||||
|
3 52 59 60
|
||||||
|
3 52 60 53
|
||||||
|
3 53 60 61
|
||||||
|
3 53 61 54
|
||||||
|
3 54 61 62
|
||||||
|
3 54 62 55
|
||||||
|
3 55 62 63
|
||||||
|
3 55 63 48
|
||||||
|
3 48 63 56
|
||||||
|
3 56 0 57
|
||||||
|
3 57 0 1
|
||||||
|
3 57 1 58
|
||||||
|
3 58 1 2
|
||||||
|
3 58 2 59
|
||||||
|
3 59 2 3
|
||||||
|
3 59 3 60
|
||||||
|
3 60 3 4
|
||||||
|
3 60 4 61
|
||||||
|
3 61 4 5
|
||||||
|
3 61 5 62
|
||||||
|
3 62 5 6
|
||||||
|
3 62 6 63
|
||||||
|
3 63 6 7
|
||||||
|
3 63 7 56
|
||||||
|
3 56 7 0
|
||||||
110
code/data/off/torus_hex_6x6.off
Normal file
110
code/data/off/torus_hex_6x6.off
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
OFF
|
||||||
|
36 72 0
|
||||||
|
4.000000 0.000000 0.000000
|
||||||
|
3.500000 0.000000 0.866025
|
||||||
|
2.500000 0.000000 0.866025
|
||||||
|
2.000000 0.000000 0.000000
|
||||||
|
2.500000 0.000000 -0.866025
|
||||||
|
3.500000 0.000000 -0.866025
|
||||||
|
2.000000 3.464102 0.000000
|
||||||
|
1.750000 3.031089 0.866025
|
||||||
|
1.250000 2.165064 0.866025
|
||||||
|
1.000000 1.732051 0.000000
|
||||||
|
1.250000 2.165064 -0.866025
|
||||||
|
1.750000 3.031089 -0.866025
|
||||||
|
-2.000000 3.464102 0.000000
|
||||||
|
-1.750000 3.031089 0.866025
|
||||||
|
-1.250000 2.165064 0.866025
|
||||||
|
-1.000000 1.732051 0.000000
|
||||||
|
-1.250000 2.165064 -0.866025
|
||||||
|
-1.750000 3.031089 -0.866025
|
||||||
|
-4.000000 0.000000 0.000000
|
||||||
|
-3.500000 0.000000 0.866025
|
||||||
|
-2.500000 0.000000 0.866025
|
||||||
|
-2.000000 0.000000 0.000000
|
||||||
|
-2.500000 0.000000 -0.866025
|
||||||
|
-3.500000 0.000000 -0.866025
|
||||||
|
-2.000000 -3.464102 0.000000
|
||||||
|
-1.750000 -3.031089 0.866025
|
||||||
|
-1.250000 -2.165064 0.866025
|
||||||
|
-1.000000 -1.732051 0.000000
|
||||||
|
-1.250000 -2.165064 -0.866025
|
||||||
|
-1.750000 -3.031089 -0.866025
|
||||||
|
2.000000 -3.464102 0.000000
|
||||||
|
1.750000 -3.031089 0.866025
|
||||||
|
1.250000 -2.165064 0.866025
|
||||||
|
1.000000 -1.732051 0.000000
|
||||||
|
1.250000 -2.165064 -0.866025
|
||||||
|
1.750000 -3.031089 -0.866025
|
||||||
|
3 0 6 1
|
||||||
|
3 1 6 7
|
||||||
|
3 1 7 2
|
||||||
|
3 2 7 8
|
||||||
|
3 2 8 3
|
||||||
|
3 3 8 9
|
||||||
|
3 3 9 4
|
||||||
|
3 4 9 10
|
||||||
|
3 4 10 5
|
||||||
|
3 5 10 11
|
||||||
|
3 5 11 0
|
||||||
|
3 0 11 6
|
||||||
|
3 6 12 7
|
||||||
|
3 7 12 13
|
||||||
|
3 7 13 8
|
||||||
|
3 8 13 14
|
||||||
|
3 8 14 9
|
||||||
|
3 9 14 15
|
||||||
|
3 9 15 10
|
||||||
|
3 10 15 16
|
||||||
|
3 10 16 11
|
||||||
|
3 11 16 17
|
||||||
|
3 11 17 6
|
||||||
|
3 6 17 12
|
||||||
|
3 12 18 13
|
||||||
|
3 13 18 19
|
||||||
|
3 13 19 14
|
||||||
|
3 14 19 20
|
||||||
|
3 14 20 15
|
||||||
|
3 15 20 21
|
||||||
|
3 15 21 16
|
||||||
|
3 16 21 22
|
||||||
|
3 16 22 17
|
||||||
|
3 17 22 23
|
||||||
|
3 17 23 12
|
||||||
|
3 12 23 18
|
||||||
|
3 18 24 19
|
||||||
|
3 19 24 25
|
||||||
|
3 19 25 20
|
||||||
|
3 20 25 26
|
||||||
|
3 20 26 21
|
||||||
|
3 21 26 27
|
||||||
|
3 21 27 22
|
||||||
|
3 22 27 28
|
||||||
|
3 22 28 23
|
||||||
|
3 23 28 29
|
||||||
|
3 23 29 18
|
||||||
|
3 18 29 24
|
||||||
|
3 24 30 25
|
||||||
|
3 25 30 31
|
||||||
|
3 25 31 26
|
||||||
|
3 26 31 32
|
||||||
|
3 26 32 27
|
||||||
|
3 27 32 33
|
||||||
|
3 27 33 28
|
||||||
|
3 28 33 34
|
||||||
|
3 28 34 29
|
||||||
|
3 29 34 35
|
||||||
|
3 29 35 24
|
||||||
|
3 24 35 30
|
||||||
|
3 30 0 31
|
||||||
|
3 31 0 1
|
||||||
|
3 31 1 32
|
||||||
|
3 32 1 2
|
||||||
|
3 32 2 33
|
||||||
|
3 33 2 3
|
||||||
|
3 33 3 34
|
||||||
|
3 34 3 4
|
||||||
|
3 34 4 35
|
||||||
|
3 35 4 5
|
||||||
|
3 35 5 30
|
||||||
|
3 30 5 0
|
||||||
@@ -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) |
|
| `ConformalMeshProperties` | `test_conformal_mesh.cpp` | 5 | Property maps (λ, θ, idx, α, geometry type) |
|
||||||
| `ConformalMeshValidity` | `test_conformal_mesh.cpp` | 1 | CGAL validity for all factory meshes |
|
| `ConformalMeshValidity` | `test_conformal_mesh.cpp` | 1 | CGAL validity for all factory meshes |
|
||||||
| `HyperIdealFunctional` | `test_hyper_ideal_functional.cpp` | 7 | FD gradient checks + Hessian symmetry |
|
| `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)* |
|
| `SphericalFunctional` | `test_spherical_functional.cpp` | 12 | Angle formula + gradient + gauge-fix |
|
||||||
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 11 | Angle formula + gradient *(1 skipped)* |
|
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 11 | Angle formula + gradient |
|
||||||
| `EuclideanHessian` | `test_euclidean_hessian.cpp` | 9 | Cotangent Laplacian structure, FD agreement, PSD, null space |
|
| `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 |
|
| `SphericalHessian` | `test_spherical_hessian.cpp` | 8 | Derivative correctness, NSD at equilibrium |
|
||||||
| `NewtonSolver` | `test_newton_solver.cpp` | 11 | Convergence: Euclidean ×3, Spherical ×4, HyperIdeal ×4 |
|
| `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 ℍ |
|
| `PeriodMatrix` | `test_phase7.cpp` | 7 | τ ∈ ℍ, SL(2,ℤ) reduction, exception outside ℍ |
|
||||||
| `FundamentalDomain` | `test_phase7.cpp` | 7 | Genus-1 parallelogram CCW, generators, g > 1 empty |
|
| `FundamentalDomain` | `test_phase7.cpp` | 7 | Genus-1 parallelogram CCW, generators, g > 1 empty |
|
||||||
| `TilingCopy/Neighbourhood` | `test_phase7.cpp` | 4 | Translation correct, tile count |
|
| `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:
|
The skip is `HomologyGenerators.Genus2_FourGeneratorPaths_BLOCKED` — blocked until
|
||||||
- `SphericalFunctional` — analytic gauge-fix stub (Phase 9b)
|
a genus-2 mesh is available (Phase 9c). It corresponds to a Java `@Ignore`-annotated
|
||||||
- `GeometryUtils` Test 7 — genus-2 homology (Phase 9c)
|
test in the original library.
|
||||||
|
|
||||||
Both correspond to Java `@Ignore`-annotated tests 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 |
|
| Job | What it tests | Trigger |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `test-fast` | 36 non-CGAL tests, no Boost | all branches |
|
| `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.
|
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`.
|
3. **Registration** — add the `.cpp` file to `code/tests/cgal/CMakeLists.txt`.
|
||||||
|
|
||||||
Expected CI result: **36 + 158 tests pass, exactly 2 skipped**.
|
Expected CI result: **36 + 170 tests pass, exactly 1 skipped**.
|
||||||
The 2 skips are intentional `GTEST_SKIP()` stubs for Phase 9b (analytic HyperIdeal Hessian)
|
The skip is an intentional `GTEST_SKIP()` stub for the genus-2 homology test
|
||||||
and Phase 9c (genus-2 homology). Do not remove them.
|
(`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