|
37 | 37 | interp_right_germ_on_padded_grid, |
38 | 38 | prepare_padded_grid, |
39 | 39 | ) |
| 40 | +from _lcm.egm.outer_envelope import outer_envelope_at_query |
40 | 41 |
|
41 | 42 |
|
42 | 43 | def test_exact_node_continuation_gradient_matches_carry_marginal(): |
@@ -189,6 +190,32 @@ def read(fp): |
189 | 190 | np.testing.assert_allclose(float(weights[2]), 0.0, atol=1e-12) |
190 | 191 |
|
191 | 192 |
|
| 193 | +def test_terminal_tie_between_right_identical_candidates_is_owned_by_index(): |
| 194 | + """A tie exactly at a shared terminal abscissa follows the index convention. |
| 195 | +
|
| 196 | + Two candidates ending at the same abscissa with equal terminal values are |
| 197 | + right-identical there (both clamp: right-finite, all germ derivatives |
| 198 | + zero), even when their left-neighborhood economics differ — the boundary |
| 199 | + subgradient is not unique, so ownership is the documented deterministic |
| 200 | + convention: the lowest index wins and its marginal is published. This pins |
| 201 | + the convention so a future change cannot silently reinterpret the |
| 202 | + terminal boundary. |
| 203 | + """ |
| 204 | + candidate_endog = jnp.array([[0.0, 1.0, 2.0], [0.0, 1.0, 2.0]]) |
| 205 | + candidate_value = jnp.array([[0.0, 1.0, 2.0], [-2.0, 0.0, 2.0]]) |
| 206 | + candidate_marginal = jnp.array([[1.0, 1.0, 1.0], [2.0, 2.0, 2.0]]) |
| 207 | + |
| 208 | + value, marginal = outer_envelope_at_query( |
| 209 | + candidate_endog=candidate_endog, |
| 210 | + candidate_value=candidate_value, |
| 211 | + candidate_marginal=candidate_marginal, |
| 212 | + x_query=jnp.array([2.0]), |
| 213 | + ) |
| 214 | + |
| 215 | + np.testing.assert_allclose(float(value[0]), 2.0, atol=1e-12) |
| 216 | + np.testing.assert_allclose(float(marginal[0]), 1.0, atol=1e-12) |
| 217 | + |
| 218 | + |
192 | 219 | def test_singleton_query_gradient_stays_zero_under_the_analytic_rule(): |
193 | 220 | """A singleton row keeps its zero query derivative under the analytic rule.""" |
194 | 221 | xp = jnp.array([1.0, jnp.nan, jnp.nan]) |
|
0 commit comments