Tarik Moussa
a3ee9576d4
fix+test: Euclidean holonomy/τ end-to-end + spherical edge-DOF oracle (2026-05-29 audit)
...
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m3s
Markdown link check / check (pull_request) Successful in 44s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m11s
Bundles the 2026-05-29 Java↔C++ math-correctness audit (doc/reviewer/
java-port-audit.md, 11 findings) with two follow-up fixes.
Audit code changes:
- Finding 3 (spherical_functional): edge-DOF replacement parameterization via
spher_eff_lambda; edge gradient α_opp⁺+α_opp⁻−θ_e (drops additive −(S⁺+S⁻)/2)
- Finding 4 (spherical_hessian): always-compiled edge-DOF throw guard
- Finding 6 (period_matrix): faithful normalizeModulus (0≤Re≤½, Im≥0, |τ|≥1)
- Finding 9 (inversive_distance): degenerate-face limiting angles, no skip
- Findings 1/2 (euclidean): degenerate gradient limiting angles + Hessian guard
Euclidean holonomy/τ fix: develop the cut surface across the dual spanning tree
only (cut_graph now exposes is_dual_tree), so genus-1 cut edges yield
non-degenerate lattice generators. Previously τ came out 0 / NaN / 1e13 on the
bundled tori; now matches the analytic revolution modulus i·√(R²−r²)/r. Re-enabled
τ reporting in the Euclidean CLI; rewrote validation.md §3/§4 accordingly.
Tests (240 CGAL, 0 skipped):
- HolonomyEndToEnd ×3 — tori of revolution (4×4, hex 6×6, 8×8) vs analytic modulus
- SphericalFunctional.EdgeGradient_RegularTetClosedForm — independent closed-form
π/3 oracle locking the Finding-3 edge formula (the path-integral FD check cannot
detect a wrong-but-conservative gradient)
Also documents the latent spherical/hyperbolic holonomy-extraction bug (same
single-development pattern, dead code today) in research-track.md (Phase 9c/10),
and adds favour/normalisations to the codespell ignore list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-29 12:50:16 +02:00
704f42bbfd
Merge pull request 'ci+quality: structural gates (CI: 3 new; local: 7 new + .clang-tidy)' ( #18 ) from ci/structural-tests into main
C++ Tests / test-fast (push) Has started running
C++ Tests / test-cgal (push) Has been cancelled
API Docs / doc-build (push) Has been cancelled
Doxygen → Codeberg Pages / publish (push) Has been cancelled
Markdown link check / check (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
2026-05-26 09:14:45 +00:00
Tarik Moussa
d3c08b3bc0
quality: 2 new gates (cmake-format, codespell) + SPDX rollout (60 files)
...
C++ Tests / test-fast (pull_request) Successful in 2m2s
API Docs / doc-build (pull_request) Successful in 58s
Markdown link check / check (pull_request) Successful in 45s
C++ Tests / test-cgal (pull_request) Failing after 13m14s
This commit closes the remaining red gates so `run-all.sh --fast` is
green end-to-end on the canonical dev machine.
New gates
─────────
1. cmake-format / cmake-lint
* scripts/quality/cmake-format.sh — dry-run by default,
--strict to fail on drift, --fix to apply
* .cmake-format.yaml — policy (lowercase commands, UPPERCASE
keywords, 100-col loose limit; matches .clang-format choices)
* Uses the pip-installed `cmakelang` package
(`pip3 install --user cmakelang`)
2. codespell
* scripts/quality/codespell.sh — exit 1 on any typo, --fix
interactively
* .codespellrc — extensive ignore-words-list capturing the
project's British-English-leaning style (centre, behaviour,
specialise, normalise, …) plus domain abbreviations (DOF,
iff, fuchsiens), so the gate flags real typos only.
* Validated: 0 typos across docs + code/include + scripts +
code/{src,tests}.
SPDX rollout (license-headers --fix)
────────────────────────────────────
license-headers.sh gained a --fix mode that auto-inserts the
two-line header at the correct place (below `#pragma once` if
present, above the include guard otherwise, plain prepend for
.cpp). Ran it on 60 of 66 files — 100 %-licensed now.
Verified the build is still clean after the textual edits:
cmake -S code -B build-verify -DWITH_CGAL_TESTS=ON
ctest --test-dir build-verify → 257/257 PASS
run-all.sh + README updated to include the two new gates.
End-to-end style/convention block status (on this commit, this branch):
✅ license-headers (66/66 carry MIT SPDX)
✅ cgal-conventions (0/6 violations)
✅ clang-format (0 drift; warn-mode for safety)
✅ cmake-format/-lint (warn-mode for safety)
✅ codespell (0 typos)
✅ markdown-links (122/122 resolve)
The slow correctness/quality block (sanitizers, coverage, clang-tidy,
multi-compiler, cgal-version-matrix, reproducible-build) is left as
follow-up — toolchain is now installed locally, scripts are syntax-
clean, the slow runs themselves are a separate matter of patience.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-24 09:15:34 +02:00
Tarik Moussa
62b02f88b9
docs(doxygen): 100% public-API coverage (228 → 0 undocumented)
...
C++ Tests / test-fast (pull_request) Successful in 2m40s
API Docs / doc-build (pull_request) Successful in 1m2s
C++ Tests / test-cgal (pull_request) Failing after 11m52s
Completes the work begun in the previous commit on this branch. Every
public symbol under code/include/ now carries a brief Doxygen comment
(0 undocumented per scripts/doxygen-coverage.sh, with the `detail::`
implementation namespaces excluded as before).
Trajectory on this branch:
start (after Doxyfile fix): 24.0 % (165 / 437 in the no-detail set
was 105 / 437 when detail counted)
after PR #17 base commit : 42.4 % (165 / 396)
this commit : 100.0 % (396 / 396)
Files touched (all .hpp / .h headers under code/include/):
* cgal/Conformal_map_traits.h
* clausen.hpp, conformal_mesh.hpp, constants.hpp (already docd)
* cp_euclidean_functional.hpp, cut_graph.hpp, discrete_elliptic_utility.hpp
* euclidean_functional.hpp, euclidean_geometry.hpp, euclidean_hessian.hpp
* fundamental_domain.hpp, gauss_bonnet.hpp
* hyper_ideal_{functional,geometry,hessian,utility,visualization_utility}.hpp
* inversive_distance_functional.hpp, layout.hpp
* matrix_utility.hpp, mesh_builder.hpp, mesh_io.hpp
* newton_solver.hpp, p2_utility.hpp, period_matrix.hpp, projective_math.hpp
* serialization.hpp, spherical_functional.hpp, spherical_geometry.hpp
* spherical_hessian.hpp, viewer_utils.h
CI:
.gitea/workflows/doxygen-pages.yml now enforces
`scripts/doxygen-coverage.sh --threshold 100`, so any future regression
(a new public function landed without a `///` brief) fails the build
before the Doxygen HTML is published to Codeberg Pages.
Doxygen warnings remain at 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-24 04:22:49 +02:00
Tarik Moussa
88a99d8bd1
fix: correct 16 inconsistencies found by consistency audit
...
C++ Tests / test-fast (push) Successful in 1m59s
C++ Tests / test-cgal (push) Has been skipped
Math / code:
- layout.hpp: add explanatory comment for Möbius deck transformation
(from_three with z1=w1, z2=w2 encodes T fixing cut-edge endpoints)
- layout.hpp: document spherical holonomy limitation — Vector2d stores
only (x,y) of 3-D position diff; full SO(3) representation deferred
Gradient sign convention (CLAUDE.md was wrong):
- Euclidean and Spherical both use G_v = Θ_v − actual (target minus actual)
- HyperIdeal uses G_v = actual − Θ_v
- Hessian sign differs: Euclidean PSD, Spherical NSD → −H, HyperIdeal PSD
Test counts (were inconsistent across all files):
- Actual: 176 CGAL tests, 2 GTEST_SKIP (not 173/170/174, not 1 skip)
- The 2 skips are EuclideanFunctional + SphericalFunctional Hessian gradient
checks (Java @Ignore ports) — not HyperIdeal Hessian as previously stated
- doc/api/tests.md: add missing SmokeEuclidean suite (3 tests),
EuclideanLayout (2), SphericalLayout (1), fix GaussBonnet 8→12,
MeshIO 9→6, Layout 8→6, EuclideanFunctional 11→12,
HomologyGenerators no longer a GTEST_SKIP stub (live test on brezel2.obj)
- doc/roadmap/phases.md: Phase 7 cumulative 158→176 tests
- doc/roadmap/phases.md: Phase 3 clarified — HyperIdeal Hessian is FD
- CLAUDE.md: suite count 28→34, test ref 173+36→174+36
- scripts/try_it.sh: expected output 173/1 skipped → 174/2 skipped
CI table (CLAUDE.md):
- test-cgal now triggers on pull requests only (not main/dev pushes)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-18 23:24:44 +02:00
Tarik Moussa
b235666725
docs: Doxygen-API + Validierungsprotokoll + Porting-Tutorial
...
C++ Tests / test-fast (push) Successful in 2m15s
C++ Tests / test-cgal (push) Has been skipped
Für einen Mathematiker der unabhängig validieren und eigene Forschung
einbringen möchte.
Doxygen-Kommentare (code/include/):
newton_solver.hpp — newton_euclidean(), newton_spherical(), newton_hyper_ideal()
je mit \param, \return, \note, \see inkl. mathematischer Begründung
(Konvexität, Vorzeichenkonvention, SparseQR-Fallback-Erklärung)
layout.hpp — euclidean_layout(), spherical_layout(), hyper_ideal_layout()
mit vollständiger Parameter-Doku, halfedge_uv-Semantik, Poincaré-Disk-Note
Neues Dokument:
doc/math/validation-protocol.md
7 reproduzierbare Checks mit konkreten Befehlen und erwartetem Output:
0. 170 Tests, 1 Skip
1. Gauss–Bonnet exakt (1e-10)
2. FD-Gradientencheck < 1e-6 für alle 3 Geometrien
3. Newton-Konvergenz < 50 Iterationen
4. τ ∈ SL(2,ℤ)-Fundamentaldomäne (3 Invarianten)
5. Möbius-Arithmetik (Inverse, Compose, from_three)
6. End-to-End-Pipeline
7. Manueller τ-Check für torus_4x4.off (Codebeispiel)
Neues Tutorial:
doc/tutorials/add-inversive-distance.md
Vollständiger Step-by-Step-Port von Phase 9a (Luo 2004):
Header anlegen, Energie/Gradient implementieren, FD-Check,
Newton-Wrapper, CMakeLists, Java-Referenzvergleich, Checkliste.
doc/getting-started.md:
Abschnitt "Known issues": macOS-Finder-Duplikate (rm-Befehl),
Warnung "First build 30–90s" (Tarball-Extraktion)
README.md:
Zwei neue Links in der Dokumentationstabelle (validation-protocol,
tutorial)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-18 01:19:44 +02:00
Tarik Moussa
e7dfaed56c
feat(phase7): Java-parity layout — priority BFS, halfedge_uv, Möbius holonomy, period matrix, fundamental domain — 158 tests
...
Phase 7 adds seven features ported from the original Java ConformalLab:
layout.hpp
- Priority BFS (min-heap on BFS depth) replaces FIFO queue, minimising
trilateration error accumulation from the root face outward.
- MobiusMap struct: T(z)=(az+b)/(cz+d), identity/inverse/compose,
from_three (3×3 complex least-squares fit), apply(Vector2d).
- halfedge_uv[h.idx()] = UV of source(h) in face(h); seam halfedges
carry the virtual unfolded position, enabling proper GPU texture atlases.
- Hyperbolic holonomy stored as MobiusMap per cut edge (SU(1,1) isometry).
- best_root_face: largest 3-D area face, 1.5× interior bonus.
- normalise_euclidean also transforms halfedge_uv (centroid + PCA).
- Face-area-weighted iterative Möbius centering (Fréchet mean, Phase 7).
period_matrix.hpp (new)
- PeriodData: lattice generators ω_i as complex numbers, τ = ω₂/ω₁ ∈ ℍ.
- reduce_to_fundamental_domain: SL(2,ℤ) reduction via alternating S/T steps.
- is_in_fundamental_domain, compute_period_matrix.
- NOTE: Siegel matrix Ω for genus g>1 intentionally deferred.
fundamental_domain.hpp (new)
- FundamentalDomain: CCW parallelogram {0, ω₁, ω₁+ω₂, ω₂} for genus 1.
- edge_identifications, generators stored.
- 4g-polygon boundary-walk for g>1 marked TODO(Phase 8) with full algorithm
outline and literature references.
- tiling_copy / tiling_neighbourhood for universal cover visualisation.
Tests: 121 → 158 (+37 Phase 7 tests covering all new features).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-13 07:57:13 +02:00
Tarik Moussa
4fc48b39f0
feat(phase6): exact hyperbolic layout, Gauss–Bonnet, cut graph, normalisation — 121 tests
...
New files:
- gauss_bonnet.hpp: euler_characteristic, genus, Σ(2π-Θ_v) sum/rhs/deficit,
check_gauss_bonnet (throws), enforce_gauss_bonnet (correct sign: Δ=(lhs-rhs)/V)
- cut_graph.hpp: CutGraph struct + compute_cut_graph (tree-cotree, Erickson–Whittlesey
2005); boundary edges correctly excluded from cut set
- test_phase6.cpp: 26 new tests (GaussBonnet ×8, CutGraph ×6, HyperbolicTrilateration
×4, Normalisation ×4 — all pass)
layout.hpp (Phase 6 rewrite):
- detail::trilaterate_hyp: exact Möbius + hyperbolic law of cosines replacing old tanh(d/2)
- detail::center_poincare_disk: Möbius centering for hyperbolic normalisation
- normalise_euclidean: centroid → origin + PCA major-axis rotation
- normalise_hyperbolic: Möbius centering in the Poincaré disk
- normalise_spherical: Rodrigues rotation → north pole
- euclidean_layout / hyper_ideal_layout: optional CutGraph* + HolonomyData* + normalise
Bug fixes caught by new tests:
- gauss_bonnet.hpp: enforce_gauss_bonnet had wrong sign for delta
- cut_graph.hpp: boundary edges were incorrectly marked as cut edges
121 tests pass, 2 skipped (Hessian stubs).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-13 01:15:41 +02:00
Tarik Moussa
b7593e3f6d
feat(phase5): Layout, CLI, JSON/XML serialisation — 95 tests
...
Phase 5 complete:
layout.hpp
- euclidean_layout(): BFS unfolding in ℝ² using trilaterate_2d
- spherical_layout(): BFS on S² using trilaterate_sph (spherical law of cosines)
- hyper_ideal_layout(): BFS in Poincaré disk (tanh(d/2) Euclidean approx)
- save_layout_off(): convenience OFF writer for 2-D and 3-D layouts
serialization.hpp
- save/load_result_json(): nlohmann/json; stores DOF vector + uv/pos layout
- save/load_result_xml(): hand-written writer/parser; same schema
conformallab_cli.cpp (rewritten)
- CLI11 interface: -i/-o/-g/-j/-x/-s/-v
- Dispatches to euclidean / spherical / hyper_ideal pipeline
- Runs Newton, computes layout, saves OFF + JSON + XML
examples/example_layout.cpp
- Full round-trip demo: solve → layout → JSON/XML → reload → verify
tests/cgal/test_layout.cpp (8 tests)
- Euclidean_PreservesEdgeLengths, CorrectVertexCount, TriangleIsNonDegenerate
- Spherical_PreservesArcLengths, PositionsOnUnitSphere
- HyperIdeal_SuccessAndFinitePositions
- Serialization.JSON_RoundTrip, XML_RoundTrip
All 95 CGAL tests pass (2 skipped — Hessian stubs unchanged).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-13 00:53:47 +02:00