Files
sim-numerics/diag_fun9_slope_sign.py

56 lines
2.2 KiB
Python

"""Why the proposed rule loses on fun9 (exp(x) - 2 - 0.01/x^2 + 2e-6/x^3, brackets from
[2e-4, 1] to [2e-4, 81]) - and whether the cause is a distinguishing sign.
On fun9.4 the two negative powers nearly cancel at the left end: f(2e-4) = -1 against
5e11 at the right end, so the rule reads the root as near the left end, while f dives to
-3.7e4 before it turns up to the root at 0.703. 17 model steps in a row DOUBLE |f|: the
local slope has the sign opposite to the one the bracket demands (f must rise from its
negative end to its positive end).
The sign considered: the local secant of the last two points, (fx - fp)/(x - xp), against
the bracket's, (FB - FA)/(B - A). Opposite signs = the local picture contradicts the
bracket. Per state (trace hook, proposed rule, no regime) and per problem, per group.
Nothing in the method changes.
python -u diag_fun9_slope_sign.py
"""
from __future__ import annotations
from collections import defaultdict
from simroot.pure import pure_root
from sweep_full import MAXFEV, XTOL, load_problems
FLAT = ("fun3", "fun4", "fun5", "fun6")
def main():
per = defaultdict(lambda: [0, 0, 0, 0]) # problems, with any contradiction, states, contradicting
for s, pid, f, a, b, _root in load_problems():
st = {"trace": []}
pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
guard="project", stats=st)
fam = pid.split(".")[0]
g = "APS" if s == "APS" else ("CHA-flat" if fam in FLAT else f"CHA-{fam}")
bad = 0
for t in st["trace"]:
if t["x"] == t["xp"]:
continue
loc = (t["fx"] - t["fp"]) / (t["x"] - t["xp"])
brk = (t["FB"] - t["FA"]) / (t["B"] - t["A"])
per[g][2] += 1
if loc != 0.0 and (loc > 0.0) != (brk > 0.0):
bad += 1
per[g][0] += 1
per[g][1] += bad > 0
per[g][3] += bad
print(f"{'group':<10} {'problems':>8} {'any contradiction':>18} {'states':>7} {'contradicting':>14}")
for g in sorted(per):
n, anyc, sts, c = per[g]
print(f"{g:<10} {n:8d} {anyc:18d} {sts:7d} {c:14d}")
print("diag done")
if __name__ == "__main__":
main()