From 1442de9c8d1e07a928a8656c111611c8087d6a35 Mon Sep 17 00:00:00 2001 From: Tarik Moussa Date: Mon, 18 May 2026 23:31:40 +0200 Subject: [PATCH] Port GradientCheck_Hessian tests: replace GTEST_SKIP stubs with real cross-module checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- code/tests/cgal/test_euclidean_functional.cpp | 26 ++++++++++++++++--- code/tests/cgal/test_spherical_functional.cpp | 24 ++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/code/tests/cgal/test_euclidean_functional.cpp b/code/tests/cgal/test_euclidean_functional.cpp index 9337f4c..e6f3773 100644 --- a/code/tests/cgal/test_euclidean_functional.cpp +++ b/code/tests/cgal/test_euclidean_functional.cpp @@ -6,7 +6,7 @@ // // Test map (Java → C++) // ────────────────────── -// testHessian (Ignored) → GradientCheck_Hessian (SKIPPED) +// testHessian (Ignored) → GradientCheck_Hessian (ported) // testGradient…Triangle → GradientCheck_TriangleVertex (ported) // testGradient…QuadStrip → GradientCheck_QuadStripVertex (ported) // testGradient…Tetrahedron → GradientCheck_TetrahedronVertex (ported) @@ -22,6 +22,7 @@ #include "mesh_builder.hpp" #include "euclidean_geometry.hpp" #include "euclidean_functional.hpp" +#include "euclidean_hessian.hpp" #include #include #include @@ -29,12 +30,31 @@ using namespace conformallab; // ════════════════════════════════════════════════════════════════════════════ -// @Ignore in Java: no Hessian implemented yet +// Cross-module Hessian check: euclidean_gradient() ↔ euclidean_hessian() +// +// Java @Ignore reason: "no Hessian implemented yet" — the Java functional +// test was written before the Hessian existed. In C++ the analytic +// cotangent-Laplace Hessian (euclidean_hessian.hpp, Phase 3f) is complete. +// +// This test verifies cross-module consistency: +// H[i,j] ≈ (G_i(x+ε·eⱼ) − G_i(x−ε·eⱼ)) / (2ε) +// using the gradient from euclidean_functional.hpp and the Hessian from +// euclidean_hessian.hpp. A bug in DOF-index mapping or sign convention +// that affects both modules independently would only be caught here. // ════════════════════════════════════════════════════════════════════════════ TEST(EuclideanFunctional, GradientCheck_Hessian) { - GTEST_SKIP() << "@Ignore in Java – Hessian not yet implemented"; + auto mesh = make_triangle(); + auto maps = setup_euclidean_maps(mesh); + compute_euclidean_lambda0_from_mesh(mesh, maps); + int n = assign_euclidean_vertex_dof_indices(mesh, maps); + + std::vector x(static_cast(n), -0.1); + + // hessian_check_euclidean: H[i,j] ≈ FD(G)[i,j] using euclidean_gradient() + EXPECT_TRUE(hessian_check_euclidean(mesh, x, maps)) + << "Cross-module: euclidean_gradient() and euclidean_hessian() are inconsistent"; } // ════════════════════════════════════════════════════════════════════════════ diff --git a/code/tests/cgal/test_spherical_functional.cpp b/code/tests/cgal/test_spherical_functional.cpp index 4e5533d..dd4df6b 100644 --- a/code/tests/cgal/test_spherical_functional.cpp +++ b/code/tests/cgal/test_spherical_functional.cpp @@ -6,7 +6,7 @@ // // Test map (Java → C++) // ────────────────────── -// testHessian (Ignored) → GradientCheck_Hessian (SKIPPED) +// testHessian (Ignored) → GradientCheck_Hessian (ported) // testGradientWithHyperIdeal… → GradientCheck_OctaFaceVertex (ported) // testGradientInExtendedDomain → GradientCheck_SpherTetVertex (ported) // testGradientWithHyperelliptic → GradientCheck_SpherTetAllDofs (ported) @@ -23,6 +23,7 @@ #include "conformal_mesh.hpp" #include "mesh_builder.hpp" #include "spherical_functional.hpp" +#include "spherical_hessian.hpp" #include #include #include @@ -30,12 +31,29 @@ using namespace conformallab; // ════════════════════════════════════════════════════════════════════════════ -// @Ignore in Java: no Hessian implemented +// Cross-module Hessian check: spherical_gradient() ↔ spherical_hessian() +// +// Java @Ignore reason: "no Hessian implemented" — the Java functional test +// was written before the Hessian existed. In C++ the analytic spherical +// Hessian (spherical_hessian.hpp, Phase 3f) is complete. +// +// This test verifies cross-module consistency between the functional and +// the Hessian module. The spherical Hessian is NSD (negative semi-definite) +// because the spherical energy is concave — hessian_check_spherical() uses +// the sign-corrected FD check appropriate for the spherical case. // ════════════════════════════════════════════════════════════════════════════ TEST(SphericalFunctional, GradientCheck_Hessian) { - GTEST_SKIP() << "@Ignore in Java – Hessian not implemented"; + auto mesh = make_spherical_tetrahedron(); + auto maps = setup_spherical_maps(mesh); + compute_lambda0_from_mesh(mesh, maps); + int n = assign_vertex_dof_indices(mesh, maps); + + std::vector x(static_cast(n), -0.2); + + EXPECT_TRUE(hessian_check_spherical(mesh, x, maps)) + << "Cross-module: spherical_gradient() and spherical_hessian() are inconsistent"; } // ════════════════════════════════════════════════════════════════════════════