Skip to content

Commit 0ff1c91

Browse files
hmgaudeckerclaude
andcommitted
Scale right-germ host-agreement tolerances to the active precision
The germ read and its scalar host reference rerun identical interpolation arithmetic, so they agree only to the active float precision's roundoff — and the k-th germ component divides by the bracket width to the k-th power, amplifying that roundoff by one power of 1/h per derivative order. The float32 CI job tripped the float64-tight bounds; the two host-agreement tests carry per-precision (and, for the germ components, per-order) bounds with an order-of-magnitude margin over the measured float32 error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0123hk3uzBgBeZown4eBBQ2C
1 parent c3423c9 commit 0ff1c91

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

tests/solution/test_egm_interp.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@
2929
import pytest
3030

3131
from _lcm.egm import interp
32+
from tests.conftest import X64_ENABLED
33+
34+
# The germ read and its host reference rerun identical interpolation
35+
# arithmetic, so the two sides agree to the active float precision's
36+
# roundoff, not better. The k-th germ component divides by the bracket
37+
# width to the k-th power, amplifying that roundoff by one power of `1/h`
38+
# per derivative order — so the higher components carry correspondingly
39+
# looser float32 bounds.
40+
_GERM_ATOL = 1e-9 if X64_ENABLED else 2e-5
41+
if X64_ENABLED:
42+
_GERM_COMPONENT_RTOL_ATOL = dict.fromkeys((1, 2, 3), (1e-07, 1e-09))
43+
else:
44+
_GERM_COMPONENT_RTOL_ATOL = {
45+
1: (1e-3, 3e-4),
46+
2: (1e-3, 1e-2),
47+
3: (1e-3, 3e-1),
48+
}
3249

3350

3451
def test_matches_numpy_interp_on_clean_grid():
@@ -444,7 +461,7 @@ def test_right_germ_at_a_node_uses_the_right_brackets_limited_slope():
444461
x_query=jnp.array([1.0]), xp=xp, fp=fp, fp_slopes=slopes
445462
)
446463

447-
np.testing.assert_allclose(float(first[0]), 0.3, atol=1e-12)
464+
np.testing.assert_allclose(float(first[0]), 0.3, atol=_GERM_ATOL)
448465

449466

450467
def test_right_germ_is_flat_and_finite_on_the_clamp_rays():
@@ -518,8 +535,10 @@ def test_right_germ_matches_scalar_host_on_random_rows():
518535
expected = [_host_right_germ(xp, fp, slopes, q) for q in queries]
519536
np.testing.assert_array_equal(np.asarray(got[0]), [e[0] for e in expected])
520537
for component in (1, 2, 3):
538+
rtol, atol = _GERM_COMPONENT_RTOL_ATOL[component]
521539
np.testing.assert_allclose(
522540
np.asarray(got[component]),
523541
[e[component] for e in expected],
524-
atol=1e-9,
542+
rtol=rtol,
543+
atol=atol,
525544
)

0 commit comments

Comments
 (0)