Fix float64 overflow in inductive sensor's sech^2 bump function

cosh(z)**2 overflows past |z|~355, which happens routinely once solve_ivp
evaluates the sensor event far from x_sensor over a wide time budget --
correct result (bump->0) but with a RuntimeWarning on every call, which
would flood stderr across a million-run sweep. Clamp the argument to
±20 (already ~1e-17, physically indistinguishable from further growth)
before computing cosh. Caught by running a real 500-run sweep through
Docker as part of Stage 8 verification, not by unit tests alone -- added
a regression test asserting no warning and a finite result far from the
sensor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-07-06 20:55:59 +05:00
parent 65d8b633ad
commit 57a83cd4f8
2 changed files with 26 additions and 1 deletions

View File

@@ -1,3 +1,5 @@
import warnings
import numpy as np
from scipy.integrate import solve_ivp
@@ -48,3 +50,17 @@ def test_inductive_sensor_never_fires_below_threshold_speed():
event = make_inductive_sensor_event(x_sensor, sensitivity, threshold, width)
sol = solve_ivp(_ballistic, (0, 1.0), [-0.05, 1.0], events=event)
assert len(sol.t_events[0]) == 0
def test_inductive_event_far_from_sensor_is_finite_and_does_not_warn():
"""Регрессия: cosh(z)**2 переполнял float64 для больших |x - x_sensor| /
width_m (типично при интегрировании на широком временном бюджете) —
результат физически верный (bump -> 0), но с RuntimeWarning на каждый
вызов, что при миллионах прогонов sweep превращается в лавину спама."""
event = make_inductive_sensor_event(x_sensor_m=0.02, sensitivity_v_per_mps=0.05, threshold_v=0.3, width_m=0.005)
far_state = np.array([-5.0, 20.0]) # 5 м от датчика при ширине чувствительности 5мм
with warnings.catch_warnings():
warnings.simplefilter("error")
value = event(0.0, far_state)
assert np.isfinite(value)
assert value == -0.3 # bump практически 0 -> событие = 0 - порог