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>
This commit is contained in:
@@ -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 <gtest/gtest.h>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
@@ -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<double> x(static_cast<std::size_t>(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";
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -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 <gtest/gtest.h>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
@@ -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<double> x(static_cast<std::size_t>(n), -0.2);
|
||||
|
||||
EXPECT_TRUE(hessian_check_spherical(mesh, x, maps))
|
||||
<< "Cross-module: spherical_gradient() and spherical_hessian() are inconsistent";
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user