fix(num): Num.equal/compare report distinct close roots as equal #23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Num.equal/Num.comparedecide two distinct algebraic numbers as equal when they lie close together. Repro: among the four real roots of x⁴ − 5x² + ε for ε = 5e-8 are x ≈ +10⁻⁴ and y ≈ −10⁻⁴;Num.equal x yreturnstrueandNum.compare x yreturns0(must befalse/+1). Exact sign determination is the one guarantee the real-algebraic kernel (ADR 0012) exists to provide — everything downstream (incidence checks, solution selection, dedup) leans on it.Likely cause: comparison decided by an interval/precision cutoff without an exact fallback. Equality should be decided exactly (sign of the difference via the minimal-polynomial machinery), with intervals only as a fast path refined until separation or an exact decision.
Related:
Num.real_rootshits a wall as root separation shrinks — 0.07s → 0.39s → 3.47s → timeout (>150s) for ε = 5e-12 … 5e-20 on the same quartic. Root isolation likely needs Descartes/VCA instead of plain bisection.Stages:
real_rootsisolation wallAll three stages landed on main (
325bc90..1ae7cac):select_rootdecides zero via isolating intervals now (the close-roots repro is checked in as a regression test), the rational-root search replaces trial division with a continued-fraction search below the 1/an^2 separation bound, andisolate_rootsuses Descartes/VCA instead of Sturm bisection. The e-ladder (5e-8 … 5e-20) runs at <1s per rung, was >150s at the last rung — the final second turned out to bereal_rootsre-sorting already-ascending roots with exact compare, also removed.