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>
This commit is contained in:
@@ -139,9 +139,29 @@ inline std::vector<double> line_search(
|
||||
} // namespace detail
|
||||
|
||||
// ── Euclidean Newton solver ────────────────────────────────────────────────────
|
||||
//
|
||||
// Minimises the Euclidean discrete conformal energy by solving G(x) = 0.
|
||||
// The Hessian H is PSD; Eigen::SimplicialLDLT is used directly.
|
||||
|
||||
/// Solve the Euclidean discrete conformal problem: find u ∈ ℝ^V such that
|
||||
/// Σ_{faces adj v} α_v(u) = Θ_v for all vertices v.
|
||||
///
|
||||
/// Starting from x0, Newton's method minimises E(u) (the Euclidean DCE energy,
|
||||
/// which is convex) by iterating u ← u − H⁻¹·G with backtracking line search.
|
||||
/// The Hessian H is the cotangent Laplacian — PSD with one zero eigenvalue on
|
||||
/// closed surfaces (gauge mode). A SparseQR fallback handles this automatically.
|
||||
///
|
||||
/// \param mesh Input triangulated surface (edges must carry lambda0 + theta_v).
|
||||
/// \param x0 Initial DOF vector (length = number of free vertices).
|
||||
/// Pass all-zeros for a flat start (typical).
|
||||
/// \param m EuclideanMaps: lambda0[e], theta_v[v], v_idx[v] must be set.
|
||||
/// Call setup_euclidean_maps() + compute_euclidean_lambda0_from_mesh()
|
||||
/// + enforce_gauss_bonnet() before passing here.
|
||||
/// \param tol Convergence threshold on max |G_i|. Default: 1e-8.
|
||||
/// \param max_iter Maximum Newton iterations. Default: 200.
|
||||
/// \return NewtonResult{x*, iterations, grad_inf_norm, converged}.
|
||||
///
|
||||
/// \note On closed meshes without a pinned vertex, SimplicialLDLT detects the
|
||||
/// gauge singularity and falls back to SparseQR automatically.
|
||||
///
|
||||
/// \see doc/math/discrete-conformal-theory.md §3 for the mathematical background.
|
||||
inline NewtonResult newton_euclidean(
|
||||
ConformalMesh& mesh,
|
||||
std::vector<double> x0,
|
||||
@@ -199,10 +219,28 @@ inline NewtonResult newton_euclidean(
|
||||
}
|
||||
|
||||
// ── Spherical Newton solver ───────────────────────────────────────────────────
|
||||
//
|
||||
// Solves G(x) = 0 for the spherical discrete conformal functional.
|
||||
// The Hessian H is NSD at the solution; −H is PSD, so we factorise −H and
|
||||
// solve (−H)·Δx = G ⟺ H·Δx = −G.
|
||||
|
||||
/// Solve the spherical discrete conformal problem: find u ∈ ℝ^V such that
|
||||
/// Σ_{faces adj v} α_v(u) = Θ_v for all vertices v (genus-0 / sphere-like surfaces).
|
||||
///
|
||||
/// The spherical DCE energy is *concave*, so the Hessian H is NSD at the solution.
|
||||
/// The solver factorises −H (which is PSD) and solves (−H)·Δx = G.
|
||||
/// A gauge vertex must be pinned (set v_idx = -1) to remove the rotational mode.
|
||||
///
|
||||
/// \param mesh Input triangulated surface, genus 0.
|
||||
/// \param x0 Initial DOF vector (length = free vertices, excluding gauge_vertex).
|
||||
/// All-zeros is a good start.
|
||||
/// \param m SphericalMaps: lambda0[e], theta_v[v], v_idx[v], gauge_vertex set.
|
||||
/// Call setup_spherical_maps() + compute_spherical_lambda0_from_mesh()
|
||||
/// + enforce_gauss_bonnet() (checks Σ(2π-Θ) > 0) before passing here.
|
||||
/// \param tol Convergence threshold on max |G_i|. Default: 1e-8.
|
||||
/// \param max_iter Maximum Newton iterations. Default: 200.
|
||||
/// \return NewtonResult{x*, iterations, grad_inf_norm, converged}.
|
||||
///
|
||||
/// \note Unlike the Euclidean solver, the spherical solver does NOT need a SparseQR
|
||||
/// fallback — the gauge vertex pins the null mode directly.
|
||||
///
|
||||
/// \see doc/math/geometry-modes.md §Spherical for sign-convention details.
|
||||
inline NewtonResult newton_spherical(
|
||||
ConformalMesh& mesh,
|
||||
std::vector<double> x0,
|
||||
@@ -258,17 +296,31 @@ inline NewtonResult newton_spherical(
|
||||
}
|
||||
|
||||
// ── HyperIdeal Newton solver ──────────────────────────────────────────────────
|
||||
//
|
||||
// Solves G(x) = 0 for the hyper-ideal discrete conformal functional.
|
||||
//
|
||||
// Gradient sign convention (opposite to Euclidean/Spherical):
|
||||
// G_v = Σ β_v − Θ_v, G_e = Σ α_e − θ_e (actual − target)
|
||||
//
|
||||
// The hyper-ideal energy is strictly convex (Springborn 2020), so H is PSD
|
||||
// and SimplicialLDLT (with SparseQR fallback) applies directly.
|
||||
//
|
||||
// The Hessian is computed by symmetric finite differences of G (see
|
||||
// hyper_ideal_hessian.hpp); replace with an analytical Hessian in Phase 5.
|
||||
|
||||
/// Solve the hyper-ideal discrete conformal problem: find (b, a) ∈ ℝ^{V+E} such that
|
||||
/// Σ β_v(b,a) = Θ_v and Σ α_e(b,a) = θ_e for all vertices v and edges e.
|
||||
///
|
||||
/// Used for genus-g surfaces (g ≥ 1) under hyperbolic cone metrics.
|
||||
/// The energy is *strictly convex* (Springborn 2020, Theorem 1.3), so Newton
|
||||
/// converges globally from any starting point.
|
||||
///
|
||||
/// DOF layout: first V_free entries are vertex variables b_v (hyper-ideal radii),
|
||||
/// followed by E entries for edge variables a_e (intersection angles).
|
||||
/// Use assign_all_dof_indices(mesh, maps) to set v_idx and e_idx automatically —
|
||||
/// no vertex needs to be pinned.
|
||||
///
|
||||
/// \param mesh Input triangulated surface, genus g ≥ 1.
|
||||
/// \param x0 Initial DOF vector (length = V + E). All-zeros typical.
|
||||
/// \param m HyperIdealMaps: lambda0[e], theta_v[v], v_idx[v], e_idx[e] set.
|
||||
/// Call setup_hyper_ideal_maps() + compute_hyper_ideal_lambda0_from_mesh().
|
||||
/// \param tol Convergence threshold on max |G_i|. Default: 1e-8.
|
||||
/// \param max_iter Maximum Newton iterations. Default: 200.
|
||||
/// \param hess_eps Finite-difference step for Hessian approximation. Default: 1e-5.
|
||||
/// (Phase 9b will replace this with an analytic Hessian.)
|
||||
/// \return NewtonResult{x*, iterations, grad_inf_norm, converged}.
|
||||
///
|
||||
/// \see Springborn (2020), Theorem 1.3 for the strict convexity proof.
|
||||
/// \see doc/math/geometry-modes.md §Hyper-ideal for DOF layout details.
|
||||
inline NewtonResult newton_hyper_ideal(
|
||||
ConformalMesh& mesh,
|
||||
std::vector<double> x0,
|
||||
|
||||
Reference in New Issue
Block a user