"""Pins for the diagnostic trace hook in pure_root (diag_model_order.py relies on it).""" from __future__ import annotations import math import pytest from simroot.pure import pure_root PROBS = ( (lambda t: t ** 3 - 2.0 * t - 5.0, 1.0, 4.0), (lambda t: math.exp(t) - 2.0, 0.0, 3.0), (lambda t: (t - 3.0) ** 3, 0.0, 10.0), ) CFG = dict(similarity="ratio", scale="derived3", guard="safe", prestep="slope", direction="dissimilar") @pytest.mark.parametrize("f,a,b", PROBS) def test_trace_is_behaviour_neutral(f, a, b): """Asking for a trace must not change a single evaluation.""" plain = pure_root(f, a, b, 1e-12, 200, **CFG) st = {"trace": []} traced = pure_root(f, a, b, 1e-12, 200, stats=st, **CFG) assert plain == traced @pytest.mark.parametrize("f,a,b", PROBS) def test_trace_records_every_similarity_step(f, a, b): st = {"trace": []} _x, n, ok = pure_root(f, a, b, 1e-12, 200, stats=st, **CFG) assert ok and 0 < len(st["trace"]) < n for s in st["trace"]: lo, hi = min(s["A"], s["B"]), max(s["A"], s["B"]) assert lo <= s["x"] <= hi assert s["far"] in (s["A"], s["B"]) def test_no_trace_key_means_no_trace(): st = {} pure_root(lambda t: t - 1.0, 0.0, 3.0, 1e-10, 100, stats=st, **CFG) assert "trace" not in st