- regular_uniformization.xml / LetterB01_canonical_group.xml are genus≥2 hyperbolic Fuchsian-group uniformizations (12-edge fundamental polygon), not genus-1 → Phase 13, not Tier 2. - Tier-2 is therefore exhausted (only Wente, deferred to Phase 9f quad/cyclic). - Tier-3 Lawson HyperIdeal golden vectors require a low-level halfedge genus-2 multi-edge generator (4 verts/12 edges) + jtem Triangulator replication; scoped as a dedicated follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
14 KiB
Cross-validation potential of the Java @Ignored tests
Purpose. The upstream Java library (
de.varylab.discreteconformal) has 22 test files with@Ignored tests. This document classifies them by why they are ignored and by their cross-validation value for the C++ port, so that the highest-value golden oracles get ported first.Created: 2026-05-29 (external-reviewer pass). See also
doc/reviewer/java-port-audit.mdand PR #27 (tests/java-golden-oracles).
1 — Two root causes for @Ignore
| Cause | Count | Meaning for the C++ port |
|---|---|---|
requires ARM64 PETSc native lib (class-level) |
15 files | Not a logic problem. Java solves via PETSc/TAO (native lib) which does not run on ARM64. The C++ port uses Eigen (no PETSc) and can run these scenarios — iff the feature is ported and the Java test carries a hard-coded expected value. |
| Logic / known-issue (method-level) | ~8 methods | Mostly mark Java gaps (no Hessian, layout unfinished) or ARM64 FP flakiness. Usually not reliable oracles. |
A critical distinction: PR #27 cross-validates functional evaluations
(energy/gradient — no solver, so no PETSc needed). The full-solve golden
values exist only as hard-coded vectors recorded from a historical x86
PETSc run — and those live exclusively in HyperIdealConvergenceTest.
2 — Already locked by PR #27 (do not duplicate)
tests/java-golden-oracles pins, bit-for-bit (1e-12), against compiled Java:
HyperIdealGoldenJava— Clausen/Л/ImLi₂, ζ₁₃/₁₄/₁₅/ζ, both tetrahedron-volume formulas.EuclideanGoldenJava/SphericalGoldenJava— angle formulas, β relations, Л energy terms, small full-mesh oracles on a tetrahedron (gradientΘ−Σα,ΔE = E(x)−E(0)).SphericalGoldenJava.FullMeshEdgeDofGradient— edge-DOF gradient.PeriodMatrix.NormalizeModulus_GoldenJava— τ-reduction fold convention.
These cover the unit math cores and functional evaluation. They do not cover solver/convergence or full uniformization.
3 — Priority ranking for new cross-validation
🟢 HIGH — real golden oracle, feature already in C++
| Item | Java source | Oracle | Blocker / effort |
|---|---|---|---|
| HyperIdeal Lawson convergence | HyperIdealConvergenceTest.testHyperIdealConvergence |
hard-coded golden u* (perfectly symmetric — robust to DOF order) | needs a low-level half-edge generator (make_lawson_square_tiled); CGAL add_face cannot build it (multi-edges, see §5). Effort: medium (1–2 d). |
Golden solution (Lawson square-tiled, BLMVM, tol 1e-10), 22 DOFs:
vertices (×4, θ=2π) : 1.1462158341786262
edges (×12, θ=π/2) : 1.7627471737467797 / …7866 (symmetric pair)
edges (×6, θ=π aux): 2.633915794495759
Assertion strategy: because the values are symmetric per DOF-class, assert per class (every vertex DOF ≈ 1.14621…, every π/2-edge ≈ 1.76274…, every π-edge ≈ 2.63391…) to 1e-6 — no DOF-order fidelity required.
🟡 MEDIUM — golden/strong oracle, needs asset or near-term phase
| Item | Java source | Oracle | Blocker |
|---|---|---|---|
| Genus-1 uniformization | UniformizerTest.testGenus1 (Wente, 1240 V) |
angle-sum = 2π + vertex count (self-consistency) | needs wente.obj asset + a "load OBJ → uniformize" path; C++ Euclidean solver exists. |
| HyperIdeal Lawson + branch points | …WithBranchPoints |
hard-coded golden u* (near-symmetric — DOF order matters more) | same generator as HIGH + branch-point variant. |
| HyperIdeal layout | HyperIdealLayoutTest |
layout positions | needs the generator + layout.hpp hyper-ideal path exercised. |
| Euclidean big-model scale | EuclideanUnwrapperPetscTest.testStaticUnwrapBigModel |
mostly self-check | scale/robustness cross-check; low oracle strength. |
🔵 LATER — feature not yet in C++ (Phase 9d.2 / 10c / 13 / 11)
| Item | Java source | Maps to |
|---|---|---|
| Genus-2 uniformization | UniformizerTest.testGenus2 (Lawson 2498) |
Phase 10c / 13 |
| HyperIdeal hyperelliptic convergence | …HyperEllipticCurveLawson (has golden u*) |
Phase 13 |
| Hyperbolic disk uniformization | HyperbolicDiskUniformizationTest |
Phase 10c (gated on holonomy bug) |
| Möbius centring (grad/Hessian/convergence golden) | MobiusCenteringFunctionalTest |
Phase 9d.4 |
| Quasi-isothermic suite (SinCondition, SNES, Utility, Layout, ConformalStructure) | …quasiisothermic.* |
Phase 10e |
| Schottky uniformisation | SchottkyUtilityTest |
Phase 11a |
| Circle-domain (multiply-connected) | CircleDomainUnwrapperTest |
Phase 11c |
| Electrostatic-sphere baseline | ElectrostaticSphereFunctionalTest |
Phase 10c′ (optional) |
⚪ NON-ORACLE — do not port as cross-validation
| Item | Why it is not an oracle |
|---|---|
HyperIdealFunctionalTest.testHessian (@Ignore@Override, empty) |
Java has no HyperIdeal Hessian (hasHessian()==false). C++ adds it (block-FD, Phase 9b) → validate against C++ FD, not Java. Documents the C++ delta. |
ElectrostaticSphereFunctionalTest.testHessian |
same — Hessian not implemented in Java. |
HyperbolicLayoutTest.testDoLayout |
throws "Not implemented correctly yet!" — Java itself unfinished; no reference to validate against. |
SurfaceCurveUtilityTest.testCreateSurfaceCurves |
known issue: non-deterministic edge count on ARM64 — flaky, not a stable oracle. |
HyperbolicCyclicConvergenceTest.testEuclideanConvergence |
known issue: ARM64 FP accumulation, angle sum outside 1e-8 — flaky. |
HyperIdealUtilityTest.testZeta13 |
asserts ζ₁₃(0.1,0.1,0.1)=0.1, which looks wrong; the other volume/ζ tests already run and are ported. Verify the correct value before any use. |
HyperIdealPluginTest |
plugin/TAO-application wiring, not pure math. |
TwoHoleExample.testLetterB |
demo/example, no assertion of record. |
SphericalUnwrapperTest PETSc variants |
the MTJ variants (not ignored) already cover the same cases on cathead. |
3b — Effort-adjusted tiering (2026-05-29 inventory)
A broader scan (not just
@Ignored tests) revealed that the §3 ranking was effort-blind: cheaper, equally-valuable oracles exist than the Lawson generator. Re-tiered by value / cost:
| Tier | Oracle | Mesh / asset | Solver | Golden | C++ status | Cost |
|---|---|---|---|---|---|---|
| 1 | EuclideanCyclicConvergenceTest |
cathead.obj (already in C++) |
MTJ BiCGstab (no PETSc) | α_opp+α_opp = π−0.1 @1e-12 (per-edge φ target) |
euclidean_functional ✅, phi_e ✅, cathead ✅ |
near-zero |
| 1 | SphericalConvergenceTest |
octahedron | MTJ Newton (no PETSc) | self-consistency (const. curvature) | spherical ✅, make_octahedron_face ✅ |
low |
| 2 | Wente genus-1 uniformization | wente_torus02.obj + wente_uniformization.xml |
— (stored result) | exact IsometryPSL2R uniformizing-group generators |
holonomy/MobiusMap ✅; needs XML reader |
medium |
regular_uniformization.xml, LetterB01_canonical_group.xml |
(stored) | — | full IsometryPSL2R Fuchsian group + 12-edge FundamentalPolygon |
genus ≥ 2 hyperbolic (not genus-1) → Phase 13 | future | |
| 3 | HyperIdeal Lawson convergence (3 golden vectors) | combinatorial createLawsonSquareTiled |
— (hard-coded u*) | symmetric u* | needs low-level half-edge generator (§5) | high |
| 4 | genus-2 (genus2.xml/lawson2498.obj), holomorphic forms (HolomorphicEuclideanUniformization_*.xml), Schottky (genus2.xml), hyperelliptic |
assets present in Java | — | various | Phases 10a/10c/11/13 | future |
Tier-2 status (2026-05-30): exhausted. The only genus-1 case is Wente
(deferred to Phase 9f, quad/cyclic). regular_uniformization.xml and
LetterB01_canonical_group.xml are genus ≥ 2 hyperbolic uniformizations
(full PSL(2,ℝ) Fuchsian groups + a 12-edge fundamental polygon) → Phase 13, not
Tier 2.
Tier-3 status: a dedicated mini-project (gated on a mesh generator). The
Lawson golden vectors require createLawsonSquareTiled: a genus-2 surface with
4 vertices / 12 edges → multi-edges (≥2 edges per vertex pair). CGAL
add_face / polygon-soup / OFF are all vertex-pair-keyed and cannot build
it; it needs hand-wired low-level Surface_mesh halfedge construction
(add_edge + explicit set_next/set_vertex/set_face, then is_valid),
plus replicating the external jtem Triangulator diagonal choice. The golden
vector is perfectly symmetric (4×1.1462 / 12×1.7627 / 6×2.6339), so a
symmetry-preserving triangulation may reproduce the three values without an
exact Triangulator match — but that is unverified. Recommended as its own
focused PR (make_lawson_square_tiled + golden-vector oracle), not a quick add.
Key correction: the Lawson generator (originally flagged HIGH) is actually Tier 3 — higher effort than Tier 1/2. Cheapest first wins:
- Tier 1 —
EuclideanCyclicConvergenceTeston cathead (asset already present; the C++ edge gradientG_e = α_opp(f⁺)+α_opp(f⁻) − φ_emakes the Java assertionα_opp+α_opp = π−0.1exactly the convergedG_e = 0condition withphi_e = π−0.1). Fails if the solver ignores a non-defaultφ, so it is a genuine check, not a tautology. - Tier 1 —
SphericalConvergenceTeston the octahedron. - Tier 2 — Wente genus-1 uniformization (needs a small
UniformizationDataXML reader; strongest deterministic pipeline oracle that maps to landed C++). - Tier 3 — Lawson generator (only after Tiers 1–2).
Build-verification finding (2026-05-29) → resolved (2026-05-30)
Attempting the Tier-1 EuclideanCyclicConvergenceTest port build-verified a
blocker first: newton_euclidean → euclidean_hessian threw "edge DOFs are
not supported". The cyclic functional needs vertex + edge DOFs (the
gradient supported them; the analytic cotangent Hessian did not). That is
why PR #27 cross-validated only the cyclic evaluation, never a solve.
Resolved (2026-05-30): implemented a block-FD edge-DOF Euclidean Hessian
(euclidean_hessian_block_fd / _sym in euclidean_hessian.hpp, mirroring
hyper_ideal_hessian_block_fd); newton_euclidean now routes cyclic layouts
(edge DOFs present) through it, vertex-only layouts still use the analytic
cotangent Laplacian.
Landed (test_euclidean_functional.cpp, all GREEN, 243/243 cgal tests pass):
- ✅
CyclicCircularEdge_PhiEntersGradient_CatHead— solver-free check that the circular-edge φ enters the gradient exactly (ΔG_e = −Δφ_e@1e-12). - ✅
CyclicCircularEdge_CatHead_JavaXVal— the full Java convergence oracle: prescribe φ = π−0.1 on one interior ("circular") edge of cathead, solve the cyclic Newton, assert the realisedα_opp+α_opp = π−0.1@1e-9. - ✅
CyclicHessian_BlockFD_MatchesGradientFD_Tetrahedron— the block-FD edge-DOF Hessian matches the column-wise gradient FD on the full cyclic layout.
DOF note: only the single circular edge gets an edge DOF (as in Java's one
circularHoleEdge). Giving every edge a DOF makes λ_e redundant with u_i+u_j (a V-dim null space) and stalls Newton.
Spherical convergence (Tier-1 #2) was found already covered by
test_newton_solver (Spherical_ConvergesFromPerturbation et al.), and
make_octahedron_face() is a single face, not a closed octahedron — so it adds
little.
Tier-2 (Wente) finding (2026-05-30) — needs a quad/cyclic pipeline
wente_torus02.obj is a quad mesh (1240 quads, genus 1), and the Java
wente_uniformization.xml golden (uniformizing group → τ = (√2+i√6)/(2√2) =
½ + i·√3/2, the hexagonal torus) comes from Java's cyclic (quad) net
uniformization. The C++ period-matrix pipeline (run_torus_pipeline) is
triangle-based, so a faithful bit-vs-Java comparison would require triangulating
(which changes the discrete conformal structure → no exact match) or a
quad/cyclic period-matrix pipeline — that belongs to Phase 9f (general
polygon meshes), not the triangle path. → Tier 2 deferred to Phase 9f; the
hexagonal golden τ is recorded here for when that lands.
Done instead (2026-05-30): full analytic edge-DOF Hessian
With Tier-2 gated on a quad pipeline, the higher-value clean win was upgrading
the cyclic Hessian from block-FD to fully analytic (closed-form
∂α_i/∂s_i = ℓ_i²/4A, ∂α_i/∂s_j = ½cot α_i − ℓ_j²/4A), satisfying the
novelty-statement.md §3.2 "analytic Hessians, not finite difference" claim for
the Euclidean path. Verified against block-FD and gradient-FD.
Other generators in the Java tree
HyperellipticCurveGenerator (→ Phase 13), SchottkyGenerator (→ Phase 11a),
FunctionalTest.createOctahedron/createTetrahedron (trivial — C++ has
make_octahedron_face / make_tetrahedron).
4 — Recommended order of work
- Port
make_lawson_square_tiled()(low-level half-edge; see §5) → unblocks the single HIGH oracle and the MED branch-point variant in one go. - Add
HyperIdealLawsonGoldenJavatest using the per-class symmetric assertion above (robust, no DOF-order matching). - Add
wente.objasset → genus-1 uniformization self-consistency (MED). - Defer LATER items to their phases; revisit golden vectors then (branch-point and hyperelliptic golden u* are already recorded in the Java tests and can be reused verbatim once the generator exists).
5 — Why the Lawson mesh needs a low-level generator
HyperIdealGenerator.createLawsonSquareTiledBase() builds a genus-2
surface with 4 vertices and 12 edges (24 half-edges), then triangulates
6 quad faces (adding 6 diagonal "aux" edges, θ=π; the 12 originals get θ=π/2).
With only 4 vertices and 12 edges, most vertex pairs carry more than one
edge (multi-edges). CGAL Surface_mesh::add_face and polygon-soup builders
key edges by their endpoint vertex pair and therefore cannot represent
multi-edges — they would either fail or glue the surface into the wrong
topology. Java sidesteps this with explicit half-edge IDs and
linkOppositeEdge / linkNextEdge.
The C++ port must replicate this with the low-level half-edge API
(add_vertex, add_edge, and explicit set_next / set_target /
set_face connectivity), mirroring the exact opposite/next links from
createLawsonSquareTiledBase() (edges 0–23). The symmetric golden vector
then makes the resulting test robust even though CGAL's DOF ordering differs
from Java's.