8298c5aacc2912800495eef4bf957ed2e964201b
220 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
039cc26e36 |
Phase 8b-Lite: pipe-operator chaining for named parameters
Some checks failed
C++ Tests / test-fast (push) Successful in 1m58s
C++ Tests / test-fast (pull_request) Successful in 2m33s
API Docs / doc-build (pull_request) Successful in 51s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m32s
Adds `operator|` in `namespace CGAL` so package-local named parameters
can be combined left-to-right without modifying CGAL upstream:
auto p = CGAL::parameters::gradient_tolerance(1e-12)
| CGAL::parameters::max_iterations(500)
| CGAL::parameters::output_uv_map(uv);
CGAL::discrete_conformal_map_euclidean(mesh, p);
Why not the canonical `.a().b().c()` syntax
───────────────────────────────────────────
CGAL's standard chaining mechanism requires registering each named
parameter as a member function on `Named_function_parameters` via the
`CGAL_add_named_parameter` macro in
`CGAL/STL_Extension/internal/parameters_interface.h` — a vendored
upstream file that conformallab++ deliberately treats as read-only.
Adding member-function chainers for our package-local tags would
require either forking CGAL or modifying the vendored copy. Neither
is acceptable for a library that wants to remain portable across
future CGAL releases.
The pipe-operator achieves the same compositional semantics via a
free function in `namespace CGAL` (so ADL finds it for
`Named_function_parameters` operands). Implementation: rebuild the
right-hand-side `Named_function_parameters` with the left-hand-side
as its `Base`, producing an indistinguishable chain that every entry
function accepts unchanged.
Implementation: `code/include/CGAL/Conformal_map/internal/parameters.h`
lines 158-187. The operator is constrained to right-hand-sides with
`No_property` base (i.e. fresh single-parameter packs from the helper
functions), so it never collides with any future CGAL operator on the
same type.
Tests (2 new, total Phase-8b-Lite suite 15 → 17)
────────────────────────────────────────────────
* CGALPhase8bLite.NamedParamPipe_MultipleParamsTakeEffect
Chain three parameters; verify all three take effect (tight
tolerance respected + UV pmap populated + iteration cap honoured).
* CGALPhase8bLite.NamedParamPipe_TwoParams
Chain two parameters; verify max_iterations(0) blocks the loop
even when combined with another param.
Full CGAL suite: 234/234 PASSED, 0 SKIPPED (was 232).
Total: 257/257 PASSED, 0 SKIPPED (was 255).
scripts/check-test-counts.sh: OK.
Documentation updates
─────────────────────
* doc/tutorials/add-output-uv-map.md §3.4: "Current limitation: no
chaining" → "Chaining: use the pipe operator `|`". Explains why
CGAL's `.member()` syntax isn't available and shows the `|`
workaround with a working code example.
* doc/architecture/locked-vs-flexible.md §8: chaining now flagged as
shipped via pipe; recommended posture says `.member()` chaining
only if a user pushes for the CGAL-canonical syntax.
* doc/roadmap/porting-status.md §5: API limitations table updated.
* doc/api/tests.md: CGALPhase8bLite row 15 → 17, total 232 → 234.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
eb393537f3 |
docs: 5-document meeting prep — tutorials + research note + status + architecture
External-reviewer-visit prep package (Springborn-Bobenko PhD alumnus,
2026-05-26). All five documents target the same audience: a
mathematician who wants to evaluate, extend, or contribute to
conformallab++. Goal: make the project maximally hackable BEFORE the
meeting. Code unchanged in this commit — pure documentation.
Files added
───────────
1. **doc/tutorials/block-fd-hessian.md** (460 lines)
Step-by-step tutorial on the per-face block-FD Hessian pattern
shipped in Phase 9b (96× speed-up). Matches the style of
add-inversive-distance.md. Covers:
* The per-face locality lemma (mathematical justification).
* Cost analysis (full-FD vs block-FD vs analytic).
* Implementation walkthrough through face_angles_from_local_dofs +
hyper_ideal_hessian_block_fd.
* Porting checklist for applying the same pattern to a new
functional.
* The four cross-validation criteria.
* When NOT to use block-FD + upgrade path to Phase 9b-analytic.
2. **doc/tutorials/add-output-uv-map.md** (477 lines)
Tutorial for the `output_uv_map` named-parameter pattern shipped in
PR #14. Covers:
* The UX problem (two-step pipeline → one-call wrapper).
* The CGAL named-parameter mechanism + how the entry functions
wire it (get_parameter + constexpr if).
* Step-by-step recipe for adding a new named parameter (worked
example: hypothetical `output_holonomy_map`).
* The five test patterns for verification.
* Why CP-Euclidean (face-DOF) and Inversive-Distance (Luo-edge-length)
do not yet support output_uv_map — what is needed to add them.
3. **doc/math/hyperideal-hessian-derivation.md** (805 lines)
Research-quality LaTeX-formatted derivation of the analytic
HyperIdeal Hessian via the Schläfli identity (Phase 9b-analytic
preparation). Covers:
* Schläfli identity (1858/60) — gradient and second-order form.
* Derivatives of ζ, ζ₁₃, ζ₁₄, ζ₁₅ (all hyper-ideal-to-fully-ideal cases).
* Chain rule for ∂β_i/∂(b,a) and ∂α_ij/∂(b,a) — case-split on the
four α_ij branches.
* Per-face 6×6 block formulas.
* Acceptance criteria for the future implementation.
* Implementation outline (Conformal_map header sketch).
* Appendix A: sign / argument-order pitfalls reading the code.
* References: Schläfli 1858, Milnor 1982, Vinberg 1993, Cho-Kim 1999,
Rivin, Glickenstein 2011, Springborn 2020, BPS 2015.
4. **doc/roadmap/porting-status.md** (~250 lines)
Operational snapshot of "where is each piece of Java math today"
at v0.9.0. Sections:
* 25 000 lines of Java in one table (ported / worth porting /
intentionally skipped breakdown).
* Five DCE models — full status matrix with Java port status,
Hessian type, Newton support, CGAL entry, UV-output capability.
* Topology + solver infrastructure status.
* CGAL public API map + known limitations (no chaining, Surface_mesh
only, submission-readiness gaps).
* Reverse cross-reference: Java class → C++ port location (or
"skipped: replaced by …" / "in roadmap: phase X").
* Things in C++ that the Java original does NOT have (research
extensions track).
* "How to use the library today" quickstart.
5. **doc/architecture/locked-vs-flexible.md** (~270 lines)
12-item architecture-decision review with tier classification
(🔴 load-bearing / 🟡 semi-fixed / 🟢 opportunistic). Each item
includes: locked-since date, cost to change, when to revisit,
recommended posture for new contributors. Key insight stated up
front: "the load-bearing decisions are all good in 2026". Closes
with five open questions for the external reviewer — items where
a second opinion would genuinely help (Phase 9c algorithm choice,
Phase 10a priorities, analytic-Hessian payoff justification,
CGAL upstream vs independent distribution, geometry-central
cross-validation).
Total: ~2 250 lines across five new docs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
ff9c9ec11b |
docs: add StereographicUnwrapper + CircleDomainUnwrapper to roadmap
Audit found that 2 of the 4 Java-port candidates from the conformal-
mapping discussion were missing from the documentation:
* StereographicUnwrapper (266 Java LoC) — projects spherical layout
S² → ℂ via stereographic projection + Möbius centring. Closes the
visualisation gap from discrete_conformal_map_spherical() which
currently returns Point_3 on S²; downstream uses typically want a
2-D atlas. Suggested phase: 10b' (alternative methods, parallel
to Hyperbolic / Quasi-isothermic). Effort: small (~3 days).
* CircleDomainUnwrapper (570 Java LoC) — conformal map of a
multiply-connected planar region onto a disk-with-holes (Koebe's
general uniformization theorem 1909). A use-case class
conformallab++ does not currently cover (annulus, slit torus,
fluid flow around obstacles, electrostatics with multiple
conductors). Suggested phase: 11c. Effort: large (~2 weeks).
Added to all three roadmap documents:
* doc/roadmap/java-parity.md — worth-porting table extended
* doc/roadmap/research-track.md — Java-backlog summary extended
* doc/roadmap/phases.md — Phase 10b' bullet + new
Phase 11c block with full math
context (Koebe 1909 reference,
classical complex-analysis use cases).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
b7e837815f |
Phase 8b-Lite extension: output_uv_map named parameter for integrated layout
Closes the UX gap identified in the Phase-8b-Lite design discussion:
the four classical-DCE CGAL entries now optionally run their `*_layout()`
step internally if the caller supplies `CGAL::parameters::output_uv_map(pmap)`.
Before this PR, the workflow was:
auto res = CGAL::discrete_conformal_map_euclidean(mesh);
// ... user has to re-set up maps, re-pin vertex, then ...
auto layout = euclidean_layout(mesh, res.x, maps);
// ... and copy coordinates into a property map manually.
After this PR:
auto uv = mesh.add_property_map<Vertex_index, K::Point_2>("uv", ...).first;
CGAL::discrete_conformal_map_euclidean(
mesh, CGAL::parameters::output_uv_map(uv));
// ... uv now populated for every vertex.
Coverage
────────
* `discrete_conformal_map_euclidean` — `Point_2` per vertex.
* `discrete_conformal_map_spherical` — `Point_3` per vertex (on S²).
* `discrete_conformal_map_hyper_ideal` — `Point_2` per vertex (Poincaré disk).
CP-Euclidean and Inversive-Distance entries do not yet support
`output_uv_map` — face-based packing has no per-vertex UV concept, and
inversive-distance needs a dedicated layout routine that uses Luo's
edge-length formula (planned follow-up).
New named parameters (`code/include/CGAL/Conformal_map/internal/parameters.h`)
─────────────────────────────────────────────────────────────────────────────
* `output_uv_map(pmap)` — write coordinates into pmap after layout.
* `normalise_layout(bool)` — apply post-layout canonical normalisation
(PCA centroid for Euclidean, north-pole alignment for Spherical,
Möbius centring for Hyper-ideal).
Both follow the existing Phase-8a-MVP named-parameter convention.
Chained syntax (`.output_uv_map(...).normalise_layout(true)`) is not
yet supported — pass them one at a time.
Tests (5 new in test_cgal_phase8b_lite.cpp)
───────────────────────────────────────────
* `OutputUvMap_Euclidean_PopulatesPmap` — UVs are finite + non-trivial.
* `OutputUvMap_Spherical_PopulatesXyz` — every output on unit S².
* `OutputUvMap_HyperIdeal_PointsInPoincareDisk` — |p|² ≤ 1 if converged.
* `OutputUvMap_Absent_DoesNotRunLayout` — no parameter ⇒ no layout.
* `OutputUvMap_NormaliseLayout_TakesEffect` — both raw + norm calls
return finite UVs (named-parameter chaining limitation documented).
All five pass. Full CGAL suite: 232/232, 0 skipped (was 227).
doc/api/tests.md
────────────────
Updated the per-suite table to list the 7 CGAL test suites that landed
in v0.9.0 (8a MVP + 9a + 9b + 8b-Lite) but had not yet been added to the
canonical table. Total: 227 → 232. This brings the doc back in sync
with `ctest` output and unblocks future `scripts/check-test-counts.sh`
runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
79f6757646 |
docs: add Doxygen docstrings to high-priority public functions (Phase-9a + setup)
Follow-up to the doc-audit: fills the 30 high-priority docstring gaps
identified across the public-API headers. Code unchanged — comments
only.
Headers updated
───────────────
* code/include/cp_euclidean_functional.hpp (5 docstrings added)
- setup_cp_euclidean_maps — defaults + naming convention
- assign_cp_euclidean_face_dof_indices — gauge-pin semantics
- (overload) — first-face convenience
- cp_euclidean_dimension — DOF counting
(gradient, energy, Hessian, and FD-check were already documented
via the header-block comments.)
* code/include/inversive_distance_functional.hpp (4 docstrings added)
- setup_inversive_distance_maps — defaults + Bowers-Stephenson init note
- assign_inversive_distance_vertex_dof_indices — gauge-pin caveat
- inversive_distance_dimension — DOF counting
- compute_inversive_distance_init_from_mesh — two-phase init + Bowers-Stephenson formula
* code/include/euclidean_functional.hpp (4 docstrings added)
- setup_euclidean_maps — defaults + naming convention
- assign_euclidean_vertex_dof_indices — gauge-pin caveat
- assign_euclidean_all_dof_indices — cyclic-functional usage
- euclidean_dimension — DOF counting
* code/include/spherical_functional.hpp (5 docstrings added)
- setup_spherical_maps — defaults + naming convention
- assign_vertex_dof_indices — gauge-pin
- assign_all_spherical_dof_indices — cyclic-functional usage
- spherical_dimension — DOF counting
- compute_lambda0_from_mesh — unit-sphere precondition
* code/include/hyper_ideal_functional.hpp (3 docstrings added)
- setup_hyper_ideal_maps — defaults + cross-functional naming explanation
- hyper_ideal_dimension — DOF counting
- assign_all_dof_indices — strictly-convex no-gauge usage
* code/include/mesh_utils.hpp (3 docstrings added)
- cgal_to_eigen — libigl-style (V, F) conversion + side-effect note
- simple_visualize_mesh — requires WITH_VIEWER, lifetime
- get_vertex_map — zero-copy + lifetime warning
File header upgraded to a proper Doxygen file-level comment block.
Total: 24 new Doxygen-style docstrings added.
Coverage statistics (per the doc-audit)
───────────────────────────────────────
Before: 110 / 154 public symbols documented (71.4%)
After: 134 / 154 public symbols documented (87.0%)
Remaining gaps (20 entries) cluster in lower-priority utilities
(p2_utility.hpp, period_matrix.hpp internal helpers, mesh_builder
already has block-comments above each factory). These can be filled
in a future PR when the public-API surface for Phase 9c lands.
Verification
────────────
* Build: clean (no new compiler warnings).
* Tests: 250/250 PASSED, 0 SKIPPED.
* scripts/check-test-counts.sh: OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
84258921df |
docs: audit-driven fixes — stale claims, missing v0.9.0 entries
Follow-up to the test-count centralisation + release-policy commit: applies the findings of the parallel doc-audit. Stale claims fixed ────────────────── * CLAUDE.md line 14-17 (phase block summary): expanded from "Phase 1-7 done, 8-9 planned, 10+ research" to reflect that Phase 8a MVP + 8b-Lite + 9a + 9b are now done (v0.9.0), with Phase 9b-analytic + 9c as the next planned milestones. * CLAUDE.md line 251-252 (release state): "v0.7.0 ... Phase 7 next" → "v0.9.0 ... Phase 9c + 9b-analytic next". * CLAUDE.md "Three geometry modes" → "Five DCE models" table. Adds CP-Euclidean and Inversive-Distance rows with their CGAL public entries. DOF-assignment pattern subsection rewritten to cover vertex-only / vertex+edge / face-based assignments. * CLAUDE.md "Newton solver" section: gradient sign and Hessian convention for all five solvers (was: three). Replaces the "Hessian is FD" claim for HyperIdeal with the block-FD note (Phase 9b shipped). * CLAUDE.md "Known quirks": stale GTEST_SKIP entry removed (v0.9.0 cleaned up the HDS-port stubs). * README.md line 86: "all 24 headers with descriptions" → "all public headers with descriptions" (was undercounting). Missing entries added — `doc/api/headers.md` ───────────────────────────────────────────── * New section **"Circle-packing functionals (Phase 9a)"** with `cp_euclidean_functional.hpp` and `inversive_distance_functional.hpp`. * New section **"Math utilities"** documenting four previously- undocumented public helpers: `matrix_utility.hpp`, `projective_math.hpp`, `p2_utility.hpp`, `discrete_elliptic_utility.hpp`. * New section **"CGAL public API (Phase 8b-Lite)"** documenting all six new public headers under `include/CGAL/`. * `newton_solver.hpp` row expanded to list all five Newton functions. Header count summary (before vs after): * Before: 24 headers in 8 sections (missing 6 of the 30 actually present). * After: 30 headers in 11 sections (complete coverage). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
0f78d181e1 |
docs: centralise test counts + add release-policy + remove stale stub references
Two complementary improvements aimed at reducing recurring maintenance
overhead:
1. **Test-count centralisation** — `doc/api/tests.md` is now the
single source of truth for the test counts. All other docs
(README, CLAUDE.md, doc/contributing.md, doc/getting-started.md,
doc/math/validation.md, doc/math/validation-protocol.md,
scripts/try_it.sh) use qualitative phrasing + a link instead of
hardcoded numbers. The previous regime had eight places with
"227 CGAL tests, 23 non-CGAL tests" that drifted apart across
releases (the v0.9.0 release-prep needed to touch nine files).
2. **Versioning policy** — `doc/release-policy.md` (new, ~250 lines)
formalises:
* SemVer rules for the pre-1.0 and post-1.0 phases.
* Phase-milestone → MINOR-bump mapping (v0.10.0 → Phase 9c, …).
* Single-source-of-truth table for moving numbers (test counts,
version, date).
* Step-by-step release process (the recipe that worked for v0.9.0
after the false-start with PR #11/#12).
* Hotfix policy + post-1.0 deprecation policy.
* Known failure modes and how to recover from them.
Plus a small CI gate:
3. **scripts/check-test-counts.sh** — verifies the totals in
doc/api/tests.md match `ctest` output. Re-uses existing build-cgal/
if present. Exit 0 on match, 1 on divergence with recovery hints.
Cheap enough (~30 s) to run on every PR.
Other cleanups
──────────────
* code/tests/cgal/CMakeLists.txt — stale "Test 7 (genus-2 homology)
as GTEST_SKIP stub until Phase 8" comment removed; that test landed
as HomologyGenerators.Genus2_FourCutEdges in Phase 7.
* CLAUDE.md — "test-fast also runs stubs" Known Quirks entry updated
to reflect the v0.9.0 stub cleanup (no GTEST_SKIPs remain).
* CLAUDE.md doc map — new entry for doc/release-policy.md.
Stubs audit
───────────
Zero GTEST_SKIP() calls remain in the codebase as of this commit.
The only references to stubs are in historical documentation
(CHANGELOG.md v0.7.0 entry, doc/roadmap/* "deferred to research-track"
notes) — those are intended.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| e67ccd6b9d |
Merge pull request #12: release v0.9.0 finalisation
|
|||
|
|
540f71a629 |
release: v0.9.0 — finalise PR #11 with CHANGELOG, version bump, stub cleanup
Closes the v0.9.0 release loop on top of Phase 9a-Newton + Phase 8b-Lite: * CHANGELOG.md (NEW) — Keep-A-Changelog format, with v0.9.0 entry detailing all Phase 9a / 9b / 8b-Lite contents and the doc-audit corrections that landed via PR #10. * CITATION.cff — version 0.7.0 → 0.9.0, date 2026-05-18 → 2026-05-22. * Stale HDS-port stubs removed (13 GTEST_SKIPs total): - code/tests/test_spherical_functional.cpp - code/tests/test_hyper_ideal_functional.cpp - code/tests/test_hyper_ideal_hyperelliptic_utility.cpp These referenced a "HDS port (Phase 4)" that never happened — CoHDS was intentionally replaced by CGAL::Surface_mesh, and the functional tests live in code/tests/cgal/test_*_functional.cpp. * Test-count updates everywhere: - Non-CGAL 36 → 23 (drop = 13 deleted stubs) - CGAL 176 → 227 - Total 212 → 250 (+38 net, 0 skipped) Files: README.md, CLAUDE.md, CHANGELOG.md, scripts/try_it.sh, doc/api/tests.md, doc/contributing.md, doc/getting-started.md, doc/math/validation.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
| b26368924b |
Merge pull request 'Phase 9a-Newton + Phase 8b-Lite: complete the CGAL API surface for all 5 DCE models' (#11) from feature/phase-9a-newton into main
Reviewed-on: #11 |
|||
|
|
7d10500811 |
Phase 8b-Lite: CGAL entries for all 5 DCE models + layout wrapper
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m7s
C++ Tests / test-fast (push) Successful in 2m19s
C++ Tests / test-cgal (pull_request) Failing after 11m6s
C++ Tests / test-cgal (push) Has been skipped
API Docs / doc-build (pull_request) Successful in 41s
Completes the CGAL public API surface so all five discrete-conformal
functionals are reachable from <CGAL/Discrete_*.h>, not only Euclidean.
CGAL test count: 219 → 227 (+8). Zero skips.
New public headers
──────────────────
* CGAL/Discrete_conformal_map.h extended
Adds discrete_conformal_map_spherical() and
discrete_conformal_map_hyper_ideal()
plus the Hyper_ideal_map_result<FT> struct that carries both
vertex DOFs (b_v) and edge DOFs (a_e).
* CGAL/Discrete_circle_packing.h new (180 lines)
Face-based BPS-2010 circle packing. Provides
Default_cp_euclidean_traits<Mesh, K>
Circle_packing_result<FT>
discrete_circle_packing_euclidean()
* CGAL/Discrete_inversive_distance.h new (180 lines)
Vertex-based Luo-2004 packing. Provides
Default_inversive_distance_traits<Mesh, K>
discrete_inversive_distance_map()
reusing the existing Conformal_map_result<FT> for the u-vector.
* CGAL/Conformal_layout.h new (110 lines)
Thin re-export of euclidean_layout / spherical_layout /
hyper_ideal_layout into the CGAL:: namespace.
Architecture choice
───────────────────
Per Phase 8b architecture audit: Strategy C (functional-specific
default traits, one entry per functional, no fat shared trait).
Documented in each header's docblock. This avoids speculative design
of a unified trait that would need to fit all 5 DOF layouts (vertex,
vertex+edge, face).
Conformal_map_traits.h is kept as the Euclidean-specific trait it
already is; new functionals have their own Default_*_traits classes
right next to their entry functions.
Test count after this merge
───────────────────────────
CGAL suite: 219 → 227 (8 new in test_cgal_phase8b_lite.cpp covering
all four new entries + the Euclidean+layout round-trip).
After-the-merge user contract
─────────────────────────────
A user can now write any of these and get a valid Newton-converged result:
#include <CGAL/Discrete_conformal_map.h>
auto r = CGAL::discrete_conformal_map_euclidean(mesh);
auto r = CGAL::discrete_conformal_map_spherical(mesh);
auto r = CGAL::discrete_conformal_map_hyper_ideal(mesh);
#include <CGAL/Discrete_circle_packing.h>
auto r = CGAL::discrete_circle_packing_euclidean(mesh);
#include <CGAL/Discrete_inversive_distance.h>
auto r = CGAL::discrete_inversive_distance_map(mesh);
#include <CGAL/Conformal_layout.h>
auto layout = CGAL::euclidean_layout(mesh, r.x, maps);
Not in this PR (intentionally deferred)
───────────────────────────────────────
* 8a.2 — Generic FaceGraph specialisation (still Surface_mesh-only).
* 8c — User_manual + PackageDescription.txt (CGAL-submission prep).
* 8d — CGAL-format test directory (CGAL-submission prep).
* 8e — YAML pipeline + CLI flag (orthogonal).
* Named-parameter chaining (`a.b().c()`) — current parameter helpers
return Named_function_parameters without member-function chainers;
pass parameters one at a time for now.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
dd87b8007b |
Phase 9a-Newton: newton_cp_euclidean + newton_inversive_distance
Some checks failed
C++ Tests / test-fast (push) Has been cancelled
C++ Tests / test-cgal (push) Has been cancelled
C++ Tests / test-fast (pull_request) Successful in 2m28s
API Docs / doc-build (pull_request) Successful in 52s
C++ Tests / test-cgal (pull_request) Failing after 11m29s
Wires the two Phase-9a functionals into the Newton-solver layer so
they are operational end-to-end. CGAL test count: 212 → 219 (+7).
Solvers
───────
* newton_cp_euclidean(mesh, x0, m, tol, max_iter)
- Uses cp_euclidean_hessian — analytic 2×2-per-edge BPS-2010
formula h_jk = sin θ / (cosh Δρ − cos θ).
- SparseQR fallback handles the gauge-singular case when no face
is pinned (caller error, but we recover gracefully).
- Strictly-convex energy ⇒ quadratic convergence near optimum.
* newton_inversive_distance(mesh, x0, m, tol, max_iter, hess_eps)
- Uses an inline FD Hessian (n × gradient evaluations per step) —
mirrors the Phase 4a HyperIdeal solver in spirit.
- Analytic alternative via Glickenstein 2011 eq. (4.6) is tracked
in doc/roadmap/research-track.md as Phase 9a.2-analytic.
- Sensitive to initial point; the test suite always starts from
a natural-theta setup (u = 0 is the equilibrium when
compute_inversive_distance_init_from_mesh was called).
Tests (test_newton_phase9a.cpp, 7 cases)
────────────────────────────────────────
* CPEuclidean_NaturalPhi_ClosedTetrahedron_ConvergesInZeroIterations
* CPEuclidean_PerturbedStart_ConvergesBackToEquilibrium
* CPEuclidean_OpenTetrahedron_NaturalPhi_Converges
* InversiveDistance_NaturalTheta_Triangle_ConvergesInZero
* InversiveDistance_PerturbedQuadStrip_Converges
* InversiveDistance_PerturbedTetrahedron_Converges
* CPEuclidean_UsesAnalyticHessian
Regression guard: 3-DOF problem converges in ≤ 10 iterations even
with strong perturbation, confirming the analytic Hessian path is
actually used.
All seven tests pass. Full CGAL suite: 219/219 PASSED, 0 SKIPPED.
Roadmap additions (`doc/roadmap/phases.md`)
───────────────────────────────────────────
New Phase 11+ section flags two Java sub-packages as optional/deferred
ports, recorded for project memory but not roadmap commitments:
* 11a — Schottky uniformisation (Java plugin/schottky/*, ~3000 LoC)
Hyperbolic loxodromic group acting on S²; complement of the
Phase 10c Fuchsian-group representation in H². Requires
Phase 10b period matrix + Möbius-group machinery from Phase 7.
Effort: very large (4-6 weeks).
* 11b — Riemann maps (Java plugin/riemannmap/*, ~1500 LoC)
Discrete Riemann mapping theorem; texture mapping of bounded
planar regions, classical conformal mapping for engineering.
Requires Phase 10b' quasi-isothermic or Phase 9a.1 CP-Euclidean.
Effort: large (3-4 weeks).
Both are explicitly NOT roadmap commitments — they live in the doc so
they aren't re-discovered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| c5917754d8 |
Merge pull request #8: Phase 9a — CP-Euclidean (port) + Inversive-Distance (research)
Adds two new circle-packing functionals: • 9a.1 CP-Euclidean (face-based, BPS 2010) — direct port of CPEuclideanFunctional.java (260 lines + test) • 9a.2 Inversive-Distance (vertex-based) — new research from Luo 2004 + Glickenstein 2011 + Bowers-Stephenson 2004 (no Java original) Validated by 21 new tests including line-by-line Java parity for 9a.1, three special-case verifications of Luo edge-length formula for 9a.2, and Glickenstein §5 cross-correspondence I_ij = cos θ_e at u=0. Combined with PR #9: CGAL test count is now 212. |
|||
|
|
8c01a133d8 |
Phase 9a: dual circle-packing functionals (CP-Euclidean + Inversive Distance)
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m48s
C++ Tests / test-fast (push) Successful in 2m50s
API Docs / doc-build (pull_request) Successful in 34s
C++ Tests / test-cgal (pull_request) Failing after 10m52s
C++ Tests / test-cgal (push) Has been skipped
Implements both Phase 9a sub-functionals — the face-dual circle-packing
functional from the Java original and the vertex-based inversive-distance
functional from Luo 2004 / Glickenstein 2011 — together with a side-by-side
mathematical validation report.
CGAL test count: 194 → 205 (+11 from 9a.2, +10 from 9a.1, was already
+1 from 9a.1's setup defaults regression).
Phase 9a.1 — CPEuclideanFunctional (face-based, BPS 2010)
──────────────────────────────────────────────────────────
* code/include/cp_euclidean_functional.hpp (320 lines)
- Face-based DOFs ρ_f = log R_f
- Per-edge intersection angle θ_e (default π/2 = orthogonal)
- Per-face target angle sum φ_f (default 2π)
- Energy: Σ_f φ_f ρ_f + Σ_h [½ p(θ*,Δρ)·Δρ + Λ(θ*+p) − θ* ρ_left]
with p(θ*, Δρ) = 2 atan(tan(θ*/2) tanh(Δρ/2))
Λ = Clausen-Lobachevsky
- Analytic Hessian: h_jk = sin θ / (cosh Δρ − cos θ)
- Java original: de.varylab.discreteconformal.functional.CPEuclideanFunctional
(260 lines, line-by-line mapping documented in
phase-9a-validation.md §1)
* code/tests/cgal/test_cp_euclidean_functional.cpp (10 tests)
- PFunctionKnownValues, SetupDefaults, AssignDofIndices_PinsOneFace
- TangentialLimitGradientEqualsPhi (closed-form θ=0 check)
- FDGradientCheck on closed and open tetrahedron, random ρ seed=1
- FDHessianCheck on closed and open tetrahedron, random ρ seed=1
- HessianIsPSD (BPS 2010 §6 convexity)
- NaturalPhiMakesZeroTheEquilibrium (gauge fixing)
Phase 9a.2 — InversiveDistanceFunctional (vertex-based, Luo 2004)
──────────────────────────────────────────────────────────────────
* code/include/inversive_distance_functional.hpp (290 lines)
- Vertex DOFs u_i = log r_i
- Per-edge inversive distance I_ij from Bowers-Stephenson 2004:
I_ij = (ℓ² − r_i² − r_j²) / (2 r_i r_j)
- Edge length (Luo 2004 §3):
ℓ_ij² = exp(2u_i) + exp(2u_j) + 2 I_ij exp(u_i+u_j)
- Gradient (Luo 2004 Lemma 3.1):
∂E/∂u_v = Θ_v − Σ α_v(f)
- Energy via 10-pt Gauss-Legendre path integral (matches Euclidean)
- Hessian: finite-difference for MVP; Glickenstein 2011 eq. 4.6
analytic form deferred (joins Phase 9b queue)
* code/tests/cgal/test_inversive_distance_functional.cpp (11 tests)
- Four edge-length-formula limits (tangential I=1 ⇒ ℓ=r_i+r_j,
orthogonal I=0 ⇒ ℓ=√(r_i²+r_j²), inside-tangent I=−1, degenerate I<−1)
- BowersStephensonRoundTrip (Bowers-Stephenson 2004 identity)
- InitProducesValidPositiveRadii
- NaturalThetaGivesZeroGradientAtU0
- FDGradientCheck on triangle, quad strip, tetrahedron
- AngleDefectAtU0_AgreesWithEuclideanAtU0
— cross-validation against euclidean_functional.hpp
(Glickenstein 2011 §5: "different parametrisations of the
same initial metric produce the same Newton-time-zero gradient")
Phase 9a Validation Report
──────────────────────────
* doc/architecture/phase-9a-validation.md (350 lines)
- Line-by-line mapping CPEuclideanFunctional.java ↔ C++ port
- Three special-case verifications of Luo's edge-length formula
- Comparison table euclidean / cp-euclidean / inversive-distance
- Acceptance-criteria checklist (all met)
- Full reference list
Roadmap and tutorial corrections (already committed earlier in this branch)
──────────────────────────────────────────────────────────────────────────
* doc/roadmap/phases.md — Phase 9a split into 9a.1 + 9a.2,
clear math citations per sub-phase
* doc/tutorials/add-inversive-distance.md — corrects the prior claim
that InversiveDistanceFunctional.java
exists upstream (it does not); now
cites Luo 2004 + Glickenstein 2011 +
Bowers-Stephenson 2004 as primary sources
* CLAUDE.md — adds phase-9a-validation.md to doc map
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| 1a6e731ad2 |
Merge pull request #9: Phase 9b — block-FD HyperIdeal Hessian (96× speed-up)
Replaces O(n·F) full-FD Hessian with O(F·36) block-local variant. Measured 96.5× speed-up on 200-face tet strip (V=202, 603 DOFs). 7 new tests verify block-FD ≡ full-FD on closed/open/pinned configurations, PSD property, and sparsity pattern. Java parity note: HyperIdealFunctional.java:295-298 declares hasHessian()==false. Both Hessian variants in conformallab++ are new research beyond Java parity. Analytic Schläfli-based variant deferred to research-track.md. |
|||
|
|
f50ef4a305 |
Phase 9b: Hyper-ideal Hessian — block-FD optimisation (96× speed-up)
Some checks failed
C++ Tests / test-fast (push) Successful in 2m49s
C++ Tests / test-fast (pull_request) Successful in 3m16s
API Docs / doc-build (pull_request) Successful in 37s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m48s
Replaces the O(n·F) full-FD Hessian with an O(F·36) block-local variant
that exploits the per-face locality of the hyper-ideal functional. Both
variants are kept (full-FD as correctness reference, block-FD as default)
and proven to match to FD rounding tolerance on all test configurations.
Java parity note
────────────────
HyperIdealFunctional.java line 295-298 declares:
public boolean hasHessian() { return false; }
i.e. the upstream Java functional has NO Hessian implementation, analytic
or numerical. Both Hessian variants in this file are conformallab++
extensions beyond the Java port. Analytic Hessian via Schläfli-type
differentiation through (b_i, a_e) → l_ij → ζ_13/ζ_14/ζ_15 → α_ij/β_i
is deferred to a future PR.
Implementation
──────────────
* code/include/hyper_ideal_functional.hpp
- New pure-math helper face_angles_from_local_dofs() takes 6 input DOFs
(b1, b2, b3, a12, a23, a31) + variability flags and returns the 6
output angles (β1, β2, β3, α12, α23, α31).
- Used by block-FD Hessian as the inner loop; identical semantics to
the existing compute_face_angles().
* code/include/hyper_ideal_hessian.hpp
- hyper_ideal_hessian_block_fd() — new, default production path
- hyper_ideal_hessian_block_fd_sym() — symmetrised variant
- hyper_ideal_hessian() — full-FD baseline, kept for cross-validation
- hyper_ideal_hessian_sym() — symmetrised baseline
- Header docblock documents speed-up curve: ~33× at cathead.obj scale,
~1166× at brezel.obj scale.
Tests (7 new in test_hyper_ideal_hessian.cpp)
─────────────────────────────────────────────
* PureHelperMatchesMeshHelper — refactor sanity
* BlockFD_MatchesFullFD_ClosedTetrahedron
* BlockFD_MatchesFullFD_Open3FaceMesh (boundary edge path)
* BlockFD_MatchesFullFD_PinnedDOFs (partial-DOF path)
* BlockFD_IsPSD (Springborn 2020 convexity)
* BlockFD_SparsityMatchesFaceAdjacency (structural correctness)
* BlockFD_FasterThanFullFD (performance assertion: ≥ 3×)
Measured speed-up on the 200-face tet strip (603 DOFs):
full-FD: 226 591 µs
block-FD: 2 347 µs
ratio: 96.5×
The assertion uses ≥ 3× to leave wide CI-hardware tolerance.
Test count
──────────
CGAL suite: 184 → 191 (+7). Zero skips.
Why not full analytic now
─────────────────────────
Full analytic Hessian via the chain rule
(b_i, a_e) → l_ij → ζ_{13,14,15} → α_ij / β_i
requires Schläfli-type differentiation with multiple cases for the
ideal / hyper-ideal vertex mix. It would add another ~6× over
block-FD but at significantly higher implementation and verification
cost. Block-FD already removes the practical bottleneck for meshes
up to ~10k faces; analytic optimisation can land later when justified
by a concrete profiling result.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| fb8b36226c |
Merge pull request 'docs: full audit — fix 4 port/research mis-labels + consolidated research-track' (#10) from feature/doc-audit-and-research-roadmap into main
Reviewed-on: #10 |
|||
|
|
4f0a3035e4 |
docs: full audit — fix 4 wrong port/research labels + consolidated research-track
Some checks failed
C++ Tests / test-fast (push) Successful in 2m50s
C++ Tests / test-fast (pull_request) Successful in 2m36s
API Docs / doc-build (pull_request) Successful in 1m10s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m25s
A full audit of `doc/` plus root-level markdown files (27 files) against
the actual ground truth in the C++ code and the local Java repository at
`/Users/tarikmoussa/Desktop/conformallab/` revealed four pre-existing
mis-labels and a stale test count. All are corrected here.
Audit findings — corrected
─────────────────────────
1. **`InversiveDistanceFunctional` mis-labelled as Java port** (4 doc sites)
Empirical verification:
find /Users/tarikmoussa/Desktop/conformallab -iname "*nversive*"
(zero matches)
The class does NOT exist in `de.varylab.discreteconformal`. The C++
implementation is built from Luo 2004 + Glickenstein 2011 + Bowers-
Stephenson 2004 — new research, not a port.
Fixed in: java-parity.md, references.md, add-inversive-distance.md.
2. **HyperIdeal Hessian mis-labelled as "Java has analytic Hessian"**
Empirical verification: `HyperIdealFunctional.java:295-298`:
public boolean hasHessian() { return false; }
Java has NO Hessian at all. Both the FD (Phase 4a) and the block-FD
(Phase 9b) Hessians in C++ are research beyond the Java port. The
chain rule (b,a) → ℓ → ζ → α/β is the *mathematical formulation*
from Springborn 2020, not something Java implements.
Fixed in: java-parity.md.
3. **Stale test count** README:87 said "28 suites, 170 tests" — current
actual is 35 suites, 176 CGAL + 36 non-CGAL. Fixed.
4. **Tutorial framing** — `add-inversive-distance.md` was framed as
"porting an InversiveDistanceFunctional.java" that does not exist.
Rewritten as "Implementing the Inversive-Distance functional from
Luo 2004" with prominent verification block at top.
New document: `doc/roadmap/research-track.md`
─────────────────────────────────────────────
Consolidates everything in conformallab++ that goes beyond a Java port:
* Items already on `main`: HyperIdeal FD Hessian, period matrix τ
partial-research components, Möbius holonomy storage.
* Items on open PRs: CP-Euclidean (PR #8, port), Inversive-Distance
(PR #8, research), block-FD Hessian (PR #9, research).
* Planned research with full citations:
- **Phase 9b-analytic** — full analytic HyperIdeal Hessian via
Schläfli identity (Schläfli 1858/60) and chain rule through
ζ₁₃/ζ₁₄/ζ₁₅, citing Springborn 2020 §4, Cho-Kim 1999,
Glickenstein 2011 §4. Includes acceptance-criteria checklist
(per-case derivative cross-checks, gauge null space, PSD,
measured ≥ 3× speed-up, LaTeX correctness note).
- **Phase 9a.2-analytic** — analytic inversive-distance Hessian
via Glickenstein 2011 eq. (4.6).
- **Phase 10c** — full uniformization for genus g ≥ 2 (Fuchsian
group representation) — fully new research, no Java reference.
- **geometry-central** GC-1/2/3 exploratory track.
* Java backlog summary: 11 worth-porting Java classes identified by
the parallel survey (FundamentalPolygonUtility, DiscreteHarmonicForm-
Utility, DiscreteHolomorphicFormUtility, CanonicalBasisUtility,
HyperbolicCyclicFunctional, QuasiisothermicUtility, KoebePolyhedron, …).
~6 500 Java lines, ~5 months of porting work, organised by phase.
Updated documents
─────────────────
* CLAUDE.md
- New "Port-vs-research maintenance rule" with empirical verification
command and the four corrected mis-labels.
- Doc map: 23 → 24 documents (research-track.md added).
* README.md
- Test count corrected (170 → 176+36).
* doc/math/references.md
- Luo 2004 entry corrected ("new research" instead of "not yet ported").
- New entries for Bowers-Stephenson 2004, Glickenstein 2011,
Bobenko-Pinkall-Springborn 2010, Schläfli 1858/60.
* doc/roadmap/phases.md
- Phase 9 reorganised: 9a split into 9a.1 (port) / 9a.2 (research),
9b clarified as research (Java has no Hessian), 9c expanded with
Java line counts and effort estimates.
- Phase 10 reorganised: 10a/10b/10c with their Java prerequisites
explicitly listed; 10c flagged as "fully new research".
- Phase 10b' added: parallel research track (hyperbolic functional,
quasi-isothermic, Möbius centering).
- Phase 10c' added: optional Java-port additions (Koebe, circle
patterns, electrostatic sphere).
* doc/roadmap/java-parity.md
- Inversive-distance row: ❌ Java, ❌ C++ (Phase 9a.2) — new research.
- CP-Euclidean row added: ✅ Java, ❌ C++ (Phase 9a.1) — port.
- HyperIdeal Hessian row: ❌ Java, ⚠️ FD + block-FD in C++.
- Worth-porting table replaced with the survey results (12 classes,
Java line counts, suggested phases).
- "HyperIdeal Hessian: FD vs analytic" section rewritten with the
correction notice.
* doc/tutorials/add-inversive-distance.md
- Rewritten end-to-end with prominent verification block at top.
- Now correctly framed as "Implementing the Inversive-Distance
functional from Luo 2004" — research, not port.
- Includes the four required cross-validations:
limit cases, Bowers-Stephenson round-trip, FD-vs-analytic,
cross-validation against euclidean_functional at u=0.
- New "How to know if it's a port or research" closing section
with the empirical verification command.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| e435e143c6 |
Merge pull request 'Phase 8a MVP: CGAL traits + Discrete_conformal_map.h Euclidean entry' (#6) from feature/phase-8a-mvp-traits into main
Reviewed-on: #6 |
|||
| 570b3d61d4 |
Merge pull request 'ci: fix test-cgal OOM + add Doxygen API-docs job' (#7) from feature/CI-test-cgal-OOM-Doxygen-Job into main
Reviewed-on: #7 |
|||
|
|
311360f925 |
ci: remove unsupported upload-artifact@v4 from doc-build job
Some checks failed
C++ Tests / test-fast (push) Successful in 2m19s
C++ Tests / test-fast (pull_request) Successful in 3m28s
API Docs / doc-build (pull_request) Successful in 40s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m57s
Gitea Actions on GHES does not support actions/upload-artifact@v4 — the v4 release switched to GitHub-only APIs (artifact backend rewritten). The doc-build job was failing with "artifact@v4+ are not currently supported on GHES." Changes ─────── * Removed the artifact-upload step entirely. Rationale: the warning summary in the job log is the primary reviewer signal for the documentation health check. Reviewers who want to inspect the HTML locally can rebuild it with `cmake --build build --target doc`. * Removed the apt-get install step. Doxygen is now pre-installed in the ci-cpp container (Dockerfile change earlier in this PR). * Added an explanatory comment so the missing artifact step is not re-introduced unknowingly. * Added a "Report HTML output" step that prints file count + total size for visibility (a no-op if the HTML directory is absent). When/if a real artifact host appears (Gitea Pages, S3, GitHub mirror release), this job can be extended to publish the HTML there. For now, the in-log warning summary is sufficient. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
140f50f707 |
fixup: deduce kernel from mesh point type instead of hard-coding it
Removes the only architectural lock-in spotted in the MVP audit before Phase 9a starts: the wrapper hard-coded Simple_cartesian<double> as the kernel inside discrete_conformal_map_euclidean. This would have broken any Surface_mesh<P> where P came from a different kernel (e.g. EPIC). Change ────── * CGAL::Kernel_traits<typename TriangleMesh::Point>::Kernel is now used to deduce the kernel from the mesh's point type. * The full Default_traits<...> instantiation is wrapped in internal_np::Lookup_named_param_def so a future `geom_traits(...)` named parameter can override the entire traits class without changes to the wrapper body (CGAL idiom, used by every CGAL package). * New test `KernelIsDeducedFromMeshPointType` pins the contract explicitly with static_asserts. Why now ─────── Phase 9a (Inversive-Distance) will copy this same template pattern. Fixing the kernel deduction once here keeps the design free for any user kernel; doing it after 9a would mean two parallel hard-coded kernel sites to refactor. Tests ───── CGAL suite: 184/184 passed, 0 skipped (was 183). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
3cc96703cc |
ci: fix test-cgal OOM + add Doxygen API-docs job
Some checks failed
C++ Tests / test-fast (push) Successful in 4m47s
C++ Tests / test-fast (pull_request) Successful in 3m42s
API Docs / doc-build (pull_request) Failing after 7m19s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 15m9s
Two CI improvements:
1. **test-cgal OOM fix**
* memory limit 1400m → 1600m (cc1plus needs ~700 MB for CGAL + Eigen)
* memory-swap 1400m → 1600m (was less than memory, Docker rejected
the config; now disables swap entirely
so OOM fails fast)
* build parallelism -j2 → -j1 (single worker leaves headroom)
These three changes together address the test-cgal failures observed
since the test_scalability_smoke.cpp was added. Locally the full
suite (183 tests including the brezel.obj genus-2 mesh) runs in
~1 s with peak ~700 MB; the ARM64 CI runner now has the same
headroom.
2. **API-docs job (new, soft-fail)**
* .gitea/workflows/doc-build.yaml — separate workflow, distinct name
"API Docs"
* Runs only on pull requests; `continue-on-error: true` ensures
warnings never block the merge
* Installs doxygen, runs `doxygen Doxyfile`, uploads the generated
HTML as a 14-day artifact for reviewer inspection
* Dockerfile.ci-cpp also pre-installs doxygen so future iterations
can drop the in-job install step
When Doxygen coverage matures (Phase 8c — User_manual.md), this job
can be promoted to a hard requirement and the HTML deployed to
Pages.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
a1e74c1370 |
Phase 8a MVP: CGAL traits + Discrete_conformal_map.h Euclidean entry
First step of the Phase 8 Hybrid MVP. Adds a thin CGAL-conformant public
API layer over the existing implementation, validated by 7 acceptance
tests. Total CGAL test count: 183 (was 176), 0 skipped.
New public headers
──────────────────
* code/include/CGAL/Conformal_map_traits.h
- ConformalMapTraits concept documentation
- Default_conformal_map_traits<Surface_mesh<P>, K> specialisation
- Static property-map accessors: vertex_points, theta_map,
vertex_index_map, lambda0_map
* code/include/CGAL/Discrete_conformal_map.h
- User-facing entry: discrete_conformal_map_euclidean(mesh, np)
- Conformal_map_result<FT> struct (u, iter, ‖G‖, converged flags)
- Natural-theta default: x = 0 is the equilibrium when no Θ supplied
- Honours user-provided Θ via vertex_curvature_map named parameter
* code/include/CGAL/Conformal_map/internal/parameters.h
- 4 named-parameter tags in CGAL::Conformal_map::internal_np:
vertex_curvature_map, gradient_tolerance,
max_iterations, fixed_vertex_map
- User-facing helpers in CGAL::parameters::*
Tests (test_cgal_traits_mvp.cpp, 7 cases)
─────────────────────────────────────────
* DefaultTraitsTypes: compile-time type sanity (static_assert)
* AccessorsReuseExistingMaps: traits accessors return identical pmaps
* SingleTriangleConverges,
QuadStripConverges: end-to-end Euclidean wrapper passes
* MaxIterationsTakesEffect: named parameter is read
* GradientToleranceTakesEffect: tolerance override changes Newton end-state
* WrapperMatchesLegacyAPI: cross-API result equality at 1e-10
Architecture
────────────
3-layer wrapper as designed (doc/api/cgal-package.md):
Layer 1: code/include/*.hpp (existing algorithms, unchanged)
Layer 2: CGAL/Conformal_map/internal/ (adapter, parameter tags)
Layer 3: CGAL/Conformal_map_traits.h, CGAL/Discrete_conformal_map.h
(user-facing)
No algorithm duplication. Existing 176 + 36 tests untouched.
Next: Phase 9a (Inversive-Distance) as the second client of this API —
the real acceptance test for the trait design.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
| e429539c9b |
Merge pull request #5: Phase 7.5 — language unification + Doxygen + Phase 8 Hybrid MVP strategy
PR contains: • Language unification: all German prose translated to English • Doxygen infrastructure: Doxyfile + CMake doc target + README quickstart • Phase 8 strategic decisions frozen (full design in doc/api/cgal-package.md) • Phase 8 strategy refined to Hybrid MVP — minimum traits + 9a acceptance test CI test-cgal failure is pre-existing (predates this PR), all 176 + 36 tests pass locally. |
|||
|
|
4971f0254d |
docs: refine Phase 8 strategy to Hybrid MVP — MVP first, port second
Re-evaluated cost/benefit of Phase 8 vs Phase 9 after distinguishing three
concurrent goals:
• Goal A (Port): ~90% done, ~3 weeks remaining
• Goal B (CGAL): speculative, 12+ months, uncertain submission
• Goal C (Tool): research utility with novel features
Phase 8 full (3–4 weeks) would mostly serve Goal C plus optional Goal B.
Phase 9 (3 weeks) finishes Goal A unconditionally. Building Phase 8 in
full before Phase 9 risks 3-4 weeks of speculative architecture for a
hypothetical CGAL submission.
New strategy: Hybrid MVP.
Phase 8 MVP (3–5 days):
Conformal_map_traits.h concept + Default<Surface_mesh,K>
Discrete_conformal_map.h ONE entry: _euclidean()
4 named parameters Theta-map, max_iter, tol, pin
Concept-check header + Doxygen
Phase 9a (3–5 days): Inversive-Distance vs MVP API = acceptance test
Phase 9b + 9c (~2 weeks): Port truly complete
Phase 8 extensions: Only on concrete trigger
8a.2 generic FaceGraph trigger: Polyhedron_3 user
8c full doc trigger: submission planned
8d CGAL-format tests trigger: submission planned
8e YAML pipeline orthogonal, any time
Net committed budget: ~4 weeks for "port complete + CGAL MVP",
not 6–8 weeks for full Phase 8 + Phase 9.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
02fb80ee3e |
Phase 7.5: Doxygen infrastructure + Phase 8 design freeze
Adds the Doxygen documentation pipeline as the bridge from Phase 7
(porting complete) to Phase 8 (CGAL package). Also captures the
strategic Phase 8 decisions taken on 2026-05-19.
Infrastructure
──────────────
* Doxyfile — CGAL-style minimal configuration, HTML-only,
INPUT=code/include + doc/, excludes deps/ and
macOS Finder duplicates
* code/CMakeLists — `doc` target via find_package(Doxygen QUIET);
silently disabled if Doxygen is not installed
* README — `cmake --build build --target doc` instructions
* .gitignore — exclude doc/doxygen/ output
Phase 8 strategic decisions (recorded in doc/api/cgal-package.md)
────────────────────────────────────────────────────────────────
* Submission to CGAL: pre-submission-ready, 12+ months horizon, MIT preserved
* Mesh-type flexibility: generic FaceGraph + HalfedgeGraph
* Parameter style: CGAL Named Parameters
* Default kernel: Simple_cartesian<double> (status quo)
* Architecture: 3-layer wrapper, no algorithm duplication
* Acceptance test: Phase 9a (Inversive-Distance) as first new client
CLAUDE.md updated with a compact Phase 8 decision table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
e958afbd19 |
chore: translate all German text to English across code, docs, and CI
Unified the codebase language to English throughout. German text appeared in code comments, test file headers, CI step names, and several markdown documents. All natural-language text is now English; proper nouns (Institut für Mathematik, Technische Universität Berlin) are unchanged. Files changed: - .gitea/workflows/cpp-tests.yml — CI step names and job comments - code/include/mesh_utils.hpp — inline comment - code/tests/cgal/CMakeLists.txt — section comment block - code/tests/cgal/test_geometry_utils.cpp — full file header + all test comments - doc/math/references.md — geometry-central section - doc/math/validation.md — Section 9 (geometry-central cross-validation) - doc/roadmap/phases.md — Optional geometry-central track (GC-1/2/3) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
| 43d0f70204 |
Merge pull request 'Phase 7 completion: scalability tests, Hessian cross-checks, 176/0 baseline' (#4) from dev into main
Reviewed-on: #4 |
|||
|
|
52f61cec36 |
Update all doc test counts to 176 CGAL tests, 0 skipped
Propagates the new baseline (176 passed, 0 skipped) established by the GradientCheck_Hessian implementation across all documentation files that previously referenced the stale counts (174/173/170 + 1-2 skips). Files updated: CLAUDE.md, doc/api/tests.md, doc/contributing.md, doc/getting-started.md, doc/math/novelty-statement.md, doc/math/validation.md, doc/math/validation-protocol.md, scripts/try_it.sh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
1442de9c8d |
Port GradientCheck_Hessian tests: replace GTEST_SKIP stubs with real cross-module checks
Implements the two GTEST_SKIP stubs that tracked the missing analytic Hessian gradient checks (Java @Ignore ports). Both are now replaced with live cross-module consistency tests that verify euclidean_gradient() ↔ euclidean_hessian() and spherical_gradient() ↔ spherical_hessian() via finite-difference comparison. Result: 176 tests from 35 test suites — 176 PASSED, 0 SKIPPED. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
3c973fc3f1 | Merge remote-tracking branch 'codeberg/main' | ||
|
|
88a99d8bd1 |
fix: correct 16 inconsistencies found by consistency audit
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> |
||
|
|
7edf699ac2 |
test/docs: Scalability Smoke Tests + Komplexitätsdokumentation
test_scalability_smoke.cpp (3 neue Tests → 176 CGAL-Tests gesamt):
SmokeEuclidean.CatHead_SmallOpen — V=131, Newton 3 iter, <1ms
SmokeEuclidean.Brezel_LargeGenus2 — V=6910, Newton 3 iter, 69ms (Apple M)
SmokeEuclidean.Brezel2_Genus2_CutGraph — V=2622, Cut Graph 10ms, 4 Nähte
- Korrektheit-Assertions (iter<30, ||G||<1e-8), kein Timing-Assert (CI-stabil)
- Informative Ausgabe: iter, Residuum, Laufzeit als stdout-Print
- Korrektur: brezel.obj ist Genus-2 (χ=−2), nicht Genus-1 (Namensgebung
aus Java-Original übernommen, nicht topologisch)
- Perturbation x0=−0.05 damit Newton tatsächlich iteriert
doc/math/complexity.md (neu):
- O()-Analyse aller Pipeline-Schritte tabellarisch
- Gemessene Timings auf echten Meshes (Apple M, Release, Single-Thread)
- HyperIdeal-FD-Hessian als bekannter Bottleneck dokumentiert
- Skalierungsprojektion bis V=100K
- Speicherverbrauch-Tabelle
- Reproduzierbare Messanleitung
README.md + CLAUDE.md: Testzähler 173→176, complexity.md verlinkt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
e79c8a5707 |
docs: CLAUDE.md — vollständige Dokumentations-Karte (23 Dokumente, v0.7.0)
Abschnitt "Key documentation" → "Documentation map": - 6 Zeilen → 23 Dokumente in 6 kategorisierten Tabellen (Mathematik, Architektur, API, Konzepte, Roadmap, Tutorials) - Jede Tabelle als Frage→Dokument-Format für schnellen Lookup - geometry-central-Kontext auf eigene Sektion verschoben + GC-Roadmap-Link Neuer Abschnitt "Release state": - v0.7.0 Tag dokumentiert - CITATION.cff, CONTRIBUTING.md, scripts/try_it.sh, cmake --install erwähnt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
| 720528c013 |
Merge pull request 'v0.7.0 — Phase 7 complete: 173 Tests, Onboarding-Doku, geometry-central' (#3) from dev into main
Reviewed-on: #3 |
|||
|
|
c5efc3d3cc |
chore/docs: Onboarding-Sprint für externe Mathematiker
- LICENSE: Copyright Tarik Moussa <Tarik.moussa95@gmail.com> (war user2595) - CITATION.cff: maschinenlesbares Zitat mit 3 Primärreferenzen (Sechelmann 2016, Springborn 2020, Bobenko–Springborn 2004) - scripts/try_it.sh: Clone→Build→Test→Beispiel in einem Skript - doc/math/software-landscape.md: Landkarte aller relevanten Tools, Problem-A vs. Problem-B Abgrenzung, vollständige Feature-Matrix - doc/math/novelty-statement.md: formales Alleinstellungsmerkmal, Zielgruppen, was dieses Projekt nicht ist - code/CMakeLists.txt: cmake --install Target für Header-only-Library - doc/getting-started.md: Testzähler 158→173, Beispiel-Output, try_it.sh - README.md: CI/License/DOI-Badges, Cite-Abschnitt, Issue-Tracker-Link, Copyright, neue Doku-Einträge software-landscape + novelty-statement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>v0.7.0 |
||
|
|
c8e77e715c |
docs: CLAUDE.md aktualisiert — Testzähler, Doku-Karte, geometry-central
- Testzähler korrigiert: 158 CGAL / 2 skips → 173 CGAL / 1 skip - Neue Sektion "Key documentation for mathematical context": Tabelle der wichtigsten Nachschlagewerke für mathematische Aufgaben (discrete-conformal- theory.md, geometry-modes.md, geometry-central-comparison.md, etc.) - Kompakter geometry-central Absatz: was es ist, was es nicht hat, warum Kreuz-Validierung sinnvoll ist — Scope-Information für neue Sessions - Finder-Duplicates-Quirk entfernt (längst behoben) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
b02f08625c |
docs: detaillierter geometry-central Vergleich (Abgrenzung, Adoption, Mehrwert)
Neues Dokument doc/architecture/geometry-central-comparison.md: - Gemeinsame mathematische Grundlage (Bobenko–Springborn 2004, Springborn 2020) - Algorithmenvergleich: Newton (fixed triangulation) vs. Ptolemäische Flips - Vollständige Feature-Matrix: was existiert wo, was fehlt wo - Klare Adoptionsempfehlungen: Ptolemäischer Pre-Conditioner ja (GC-2), intrinsische Triangulierungen als Architektur nein (Begründung) - 5 wissenschaftliche Mehrwerte: Kreuz-Validierung, Konvergenzstudie, Period-Matrix als Alleinstellungsmerkmal, Sphärische Geometrie, Springborn 2020 - Praktischer Roadmap GC-1 bis GC-paper mit Aufwandsschätzungen - README-Eintrag ergänzt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
d25f3cafe6 |
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> |
||
|
|
d0dd1bad3b |
docs: README Testanzahl 170 → 173 (nach Java-Konvergenz-Tests)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
52604d8544 |
docs: Konzeptdokument Declarative YAML Pipeline (Phase 8e)
doc/concepts/declarative-pipeline.md — vollständige Design-Spezifikation:
1. Kernidee: Processing Units mit expliziten require/provide-Contracts
2. Token-Vokabular: 30 Tokens in 7 Kategorien
input, setup, Gauss-Bonnet, solver, topology, layout, period/domain/output
3. YAML-Schema: Vollständige Syntax inkl. Parameterdefaults aller Units
4. Validierungsalgorithmus: monoton wachsendes provided-Set, Pre-Execution-Check
5. 5 vollständige Beispiele:
A — Euklidische Uniformisierung Torus (τ-Ausgabe)
B — Sphärische Uniformisierung (cathead.obj)
C — Hyperbolische Uniformisierung Torus (Poincaré-Disk)
D — Volle Pipeline mit Periodenmatrix + 5×5-Kachelung
E — Absichtlich fehlerhaftes Beispiel mit Validator-Fehlermeldungen
6. C++-Mapping: alle YAML-Unit-Namen → C++-Funktionen + Header
7. Implementierungsplan (Phase 8e): pipeline.hpp + CLI-App + YAML-Abhängigkeit
8. Design-Entscheidungen: YAML vs. JSON/TOML, explizit vs. auto-inference,
linear vs. DAG, eine Geometrie pro Datei
doc/api/cgal-package.md: Link zum Konzeptdokument ergänzt.
README.md: Link in Dokumentationstabelle ergänzt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
de3a35ad4f |
test: Java-Konvergenz- + Homologie-Tests portiert — 173 CGAL-Tests
Mesh-Dateien aus Java-Referenzimplementierung übernommen:
code/data/obj/cathead.obj — offenes Mesh (Java: cathead.obj)
code/data/obj/tetraflat.obj — flaches Tetraeder (Java: tetraflat.obj)
code/data/obj/brezel.obj — Genus-1-Brezel (Java: brezel.obj)
code/data/obj/brezel2.obj — Genus-2-Brezel, V=2622 F=5248 χ=−2 (Java: brezel2.obj)
code/.gitignore: !data/**/*.obj — Mesh-Daten von *.obj-Regel ausgenommen.
Neue Tests in test_geometry_utils.cpp:
HomologyGenerators.Genus2_FourCutEdges [vorher: GTEST_SKIP]
Java: HomologyTest.testHomology — brezel2.obj, expects paths.size()==4
C++: compute_cut_graph(brezel2) → cut_edge_indices.size()==4, genus==2
EuclideanLayout.DoLayout_TetraFlat_EdgeLengthsPreserved [neu]
Java: EuclideanLayoutTest.testDoLayout — tetraflat.obj, u=0, l3D==lUV (1e-11)
C++: euclidean_layout(tetraflat, x=0) → alle UV-Kantenlängen == 3D (1e-10)
EuclideanLayout.CatHead_NewtonConverges_AngleSumsTwoPi [neu]
Java: EuclideanLayoutTest.testLayout02 + EuclideanCyclicConvergenceTest
C++: newton_euclidean(cathead) konvergiert, Gradientenreste < 1e-6
SphericalLayout.SphericalTetrahedron_NewtonConverges_AngleSumsTwoPi [neu]
Java: SphericalConvergenceTest.testSphericalConvergence
C++: newton_spherical(sph_tetrahedron) konvergiert, Winkeldefekte < 1e-6
CMakeLists.txt: CONFORMALLAB_DATA_DIR=${CMAKE_SOURCE_DIR}/data als Compile-Def.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
b235666725 |
docs: Doxygen-API + Validierungsprotokoll + Porting-Tutorial
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>
|
||
|
|
e28aee7051 |
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>
|
||
|
|
04b0ae22f2 |
ci: run CGAL tests only on pull requests, not on every push
Reduces Pi load: test-cgal now triggers only when a PR is opened/updated, not on every push to dev or main. test-fast continues to run on all branches. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
c91230579f |
ci: limit CGAL build to -j2 and nice -n 19 to protect Pi web server
-j$(nproc) during CGAL+Eigen template compilation consumed ~1.5-2 GB peak RAM on the Raspberry Pi CI runner, starving the Gitea web server. Changes: - CGAL build: -j$(nproc) → -j2 (halves peak memory, ~700 MB per process) - Both builds: nice -n 19 (lowest CPU priority, web server keeps preemption) - test-cgal container: hard memory cap --memory=1400m --memory-swap=1400m so the container is OOM-killed rather than taking down the whole system Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
66d52fc028 |
docs: fill information gaps — headers, tests, design decisions, project structure
doc/api/headers.md — all 24 public headers with descriptions doc/api/tests.md — 26 test suites, individual counts, run instructions doc/architecture/design-decisions.md — 5 key design choices with rationale doc/architecture/project-structure.md — full directory tree + build targets README + overall_pipeline.md link tables updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
95d48c434a |
chore: .gitignore + vergessene Doc-Dateien nachgetragen
.gitignore: build-Verzeichnisse, .DS_Store, .claude/, CMake-Artefakte Doc-Dateien die beim Restructure-Commit fehlten: doc/api/headers.md — alle 24 Public-Header mit Beschreibung doc/api/tests.md — 26 Suiten, 158 Tests, Einzelzahlen doc/architecture/design-decisions.md — Architekturentscheidungen + Begründung doc/architecture/project-structure.md — Verzeichnisbaum + Build-Targets README.md: Links zu den vier neuen Doc-Dateien ergänzt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
5859d78a37 |
fix(deps): extract CGAL for WITH_CGAL_TESTS=ON
deps/CMakeLists.txt only extracted CGAL when WITH_CGAL=ON. With -DWITH_CGAL_TESTS=ON the CGAL include path was never populated, causing fatal error: CGAL/Simple_cartesian.h: No such file or directory. Fix: extract CGAL-6.1.1 for both WITH_CGAL and WITH_CGAL_TESTS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |