Files
ConformalLabpp/doc/api/tests.md
Tarik Moussa ba83974525
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 59s
Markdown link check / check (pull_request) Successful in 51s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m19s
test: Java golden-value oracles for the five DCE math cores + P1-2/P1-3 fixes
Add bit-for-bit (1e-12) golden-value oracle tests pinning the C++ pure-math
and functional cores against the compiled upstream Java library (openjdk 17):

- HyperIdealGoldenJava: Clausen/Л/ImLi2, ζ13/14/15/ζ, both tetrahedron-volume
  formulas (real de.varylab…Clausen / HyperIdealUtility).
- EuclideanGoldenJava / SphericalGoldenJava: angle formulas + β relations + Л
  energy terms, plus FULL-MESH oracles driving the real EuclideanCyclicFunctional
  / SphericalFunctional on a shared tetrahedron — per-vertex gradient (Θ−Σα) and
  ΔE = E(x)−E(0) (C++ Gauss-Legendre path integral vs Java closed form).
- SphericalGoldenJava.FullMeshEdgeDofGradient: edge-DOF gradient (vertex + edge
  components, α_opp⁺+α_opp⁻−θ_e) vs raw conformalEnergyAndGradient — locks
  Finding 3 at the solution level (audit items 4 & 5).
- PeriodMatrix.NormalizeModulus_GoldenJava: τ-reduction fold convention vs the
  real DiscreteEllipticUtility.normalizeModulus (audit items 7 & 8).

Subtlety documented: the spherical oracles call Java's raw
conformalEnergyAndGradient, not evaluate() (which pre-runs a Brent gauge
maximization that C++ factors into the Newton solver's spherical_gauge_shift).

Also:
- P1-2 (layout.hpp): Euclidean holonomy now uses a per-cut-edge rigid-motion fit
  g(z)=a·z+b, exposing residual_rotation = |arg(a)| as a diagnostic; non-
  regressive (flat case a=1 reduces to the old midpoint formula).
- P1-3 (period_matrix.hpp): is_in_fundamental_domain fixed to the correct
  half-open SL(2,ℤ) domain (−½ ≤ Re < ½). Updated the now-exposed
  ComputePeriodMatrix_ReducedTau_InFD to assert the normalizeModulus domain
  (closed +½ edge) instead.

Test counts (single source of truth = doc/api/tests.md): 272/272 pass, 0
skipped (26 non-CGAL + 246 CGAL).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 19:08:37 +02:00

91 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Test Suites
## `conformallab_tests` — always built (no CGAL)
Pure-math tests, only Eigen required. Covers Java utilities ported in Phase 12.
| File | What it tests |
|---|---|
| `test_clausen.cpp` | Clausen Cl₂, Lobachevsky Л, ImLi₂ — values at known points |
| `test_hyper_ideal_utility.cpp` | Tetrahedron volumes (Meyerhoff / KolpakovMednykh) + Java golden-value oracle (Clausen/Л/ImLi₂, ζ₁₃/₁₄/₁₅/ζ, both volume formulas) |
| `test_matrix_utility.cpp` | Matrix helpers |
| `test_surface_curve_utility.cpp` | Surface curve utilities |
| `test_discrete_elliptic_utility.cpp` | Discrete elliptic functions |
| `test_p2_utility.cpp` | P2 projective utilities |
| `test_hyper_ideal_visualization_utility.cpp` | Poincaré disk projection, circumcircle |
**Total: 26 tests, 0 skipped.**
---
## `conformallab_cgal_tests` — built with `-DWITH_CGAL_TESTS=ON` or `-DWITH_CGAL=ON`
All tests have CTest prefix `cgal.` (set via `TEST_PREFIX "cgal."` in CMakeLists).
| Suite | File | Tests | What is verified |
|---|---|---:|---|
| `ConformalMeshTopology` | `test_conformal_mesh.cpp` | 4 | Euler characteristic, vertex/edge/face counts |
| `ConformalMeshTraversal` | `test_conformal_mesh.cpp` | 4 | Halfedge iteration, valence, opposite |
| `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` | 13 | Angle formula + gradient + gauge-fix + cross-module Hessian check + closed-form edge-DOF oracle |
| `SphericalGoldenJava` | `test_spherical_functional.cpp` | 3 | Java golden oracles: (1) law-of-cosines angles + β relations + Л energy term; (2) full-mesh tetrahedron — per-vertex gradient + ΔE; (3) full-mesh **edge-DOF** gradient (vertex + edge components, Finding 3) vs raw `conformalEnergyAndGradient` |
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 12 | Angle formula + gradient + cross-module Hessian check |
| `EuclideanGoldenJava` | `test_euclidean_functional.cpp` | 2 | Java golden oracles: (1) angle formula + 2·Л(α) energy term; (2) full-mesh tetrahedron — per-vertex gradient + ΔE vs real `EuclideanCyclicFunctional` |
| `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 |
| `SparseQRFallback` | `test_newton_solver.cpp` | 3 | Full-rank LDLT · singular matrix → QR · closed mesh gauge mode |
| `MeshIO` | `test_mesh_io.cpp` | 6 | OFF/OBJ round-trips, error handling |
| `Pipeline` | `test_pipeline.cpp` | 5 | End-to-end: build → setup → solve → export → reload |
| `Layout` | `test_layout.cpp` | 6 | Edge-length preservation (Eucl./Spher.), Poincaré disk layout |
| `Serialization` | `test_layout.cpp` | 2 | JSON and XML round-trips (DOF vector + layout UVs) |
| `GaussBonnet` | `test_phase6.cpp` | 12 | χ, genus, sum/RHS, deficit, check, enforce |
| `CutGraph` | `test_phase6.cpp` | 6 | Tree-cotree, open/closed meshes, flagindex consistency |
| `HyperbolicTrilateration` | `test_phase6.cpp` | 4 | Möbius + law of cosines: exact distances, disk interior, off-origin |
| `Normalisation` | `test_phase6.cpp` | 4 | Euclidean centroid, length ratios, Möbius centring |
| `MobiusMap` | `test_phase7.cpp` | 8 | Identity, inverse, compose, `from_three`, `apply(Vector2d)` |
| `BestRootFace` | `test_phase7.cpp` | 2 | Valid root face selection, interior bonus |
| `HalfedgeUV` | `test_phase7.cpp` | 4 | Size = number of half-edges, seam consistency, boundary half-edges = 0 |
| `PriorityBFS` | `test_phase7.cpp` | 3 | Success, no seam on open meshes, all vertices placed |
| `NormaliseEuclidean` | `test_phase7.cpp` | 2 | UV centroid = 0, halfedge_uv centroid = 0 |
| `PeriodMatrix` | `test_phase7.cpp` | 8 | τ ∈ , SL(2,) reduction, exception outside , Java `normalizeModulus` golden oracle |
| `FundamentalDomain` | `test_phase7.cpp` | 7 | Genus-1 parallelogram CCW, generators, g > 1 empty |
| `TilingCopy/Neighbourhood` | `test_phase7.cpp` | 4 | Translation correct, tile count |
| `HolonomyEndToEnd` | `test_phase7.cpp` | 3 | Full pipeline τ on tori of revolution (4×4, hex 6×6, 8×8) vs analytic modulus i·√(R²r²)/r |
| `CuttingUtility` | `test_geometry_utils.cpp` | 3 | `point_in_triangle_2d`: false, true, unit triangle (Java CuttingUtilityTest) |
| `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) |
| `EuclideanLayout` | `test_geometry_utils.cpp` | 2 | Euclidean layout round-trip edge lengths |
| `SphericalLayout` | `test_geometry_utils.cpp` | 1 | Spherical layout on unit sphere |
| `HomologyGenerators` | `test_geometry_utils.cpp` | 1 | Genus-2 cut graph: χ = 2, 4 cut edges (`brezel2.obj`) |
| `SmokeEuclidean` | `test_scalability_smoke.cpp` | 3 | Smoke tests on real meshes: CatHead (open), Brezel genus-1, Brezel2 genus-2 |
| `CGALConformalTraits` | `test_cgal_traits_mvp.cpp` | 2 | Phase 8a MVP traits + Default model |
| `CGALDiscreteConformalMap` | `test_cgal_traits_mvp.cpp` | 6 | Phase 8a MVP wrapper smoke tests |
| `CPEuclideanFunctional` | `test_cp_euclidean_functional.cpp` | 10 | Phase 9a.1 — BPS-2010 face-based packing (Java parity) |
| `InversiveDistanceFunctional` | `test_inversive_distance_functional.cpp` | 11 | Phase 9a.2 — Luo-2004 vertex-based packing (from literature) |
| `HyperIdealHessian` | `test_hyper_ideal_hessian.cpp` | 7 | Phase 9b — block-FD vs full-FD cross-validation + PSD + speed-up |
| `NewtonPhase9a` | `test_newton_phase9a.cpp` | 7 | Phase 9a-Newton — convergence for the two new circle-packing solvers |
| `CGALPhase8bLite` | `test_cgal_phase8b_lite.cpp` | 17 | Phase 8b-Lite — CGAL entries for all 5 DCE models + `output_uv_map` (Euclidean, Spherical, HyperIdeal, Inversive-Distance) + CP-Euclidean throws-clearly + pipe-operator chaining |
**Total: 246 tests, 0 skipped.**
---
## Running tests
```bash
# All CGAL tests
ctest --test-dir build -R "^cgal\." --output-on-failure
# One suite
./build/conformallab_cgal_tests --gtest_filter="PeriodMatrix*"
# One specific test
./build/conformallab_cgal_tests --gtest_filter="PeriodMatrix.TauInUpperHalfPlane"
# Verbose output with timing
./build/conformallab_cgal_tests --gtest_filter="NewtonSolver*" --gtest_print_time=1
```