Repository navigation
SolveNt does not find all roots of equation #115
Description
Activity
- added a commit that references this issue
on Aug 4, 2026 - added a commit that references this issue
on Aug 4, 2026 Still open — your case is not fixed.
arcsin(x) - x*pi/3still answers{ 0 }and not{ -1/2, 0, 1/2 }. Leaving this open deliberately, but recording what the investigation found, since two other defects were behind the same symptom and both are now fixed.Fixed, #695. The Newton grid collapsed to a single point. The shares that lay out the starting grid were computed with
EDecimal's bare/, which carries no precision context and returns NaN for any quotient that does not terminate in base ten. Only step counts of the form 2^a·5^b divide exactly, so for 3, 6, 7, 9, 12, 21 and most other values every share but the first came out NaN, and with it every starting point — the grid quietly shrank to the corner where x and y are both zero. The default of 10 divides exactly, which is why it went unseen, and why asking for a finer search made the answer worse.x^3 - 2xgave all three roots at 10 steps and one at 21.Fixed, #696. Compiled
arcsinreturned the conjugate of the arcsine off the real axis — a five-year-old defect. Newton's method felt it as divergence away from a root it had been started on, which matters here because your equation is an arcsine.Not fixed, and the reason yours still fails. The default grid is 10 steps over a region that does not tighten around the interval where the roots live. All three of your roots lie in (-1, 1), which the grid steps over; raising
StepCountfinds them, and now genuinely does since #695:MathS.Settings.NewtonSolver.As( new MathS.Settings.NewtonSetting { From = (-1, -1), To = (1, 1), StepCount = (20, 20) }, () => "arcsin(x) - x*pi/3".ToEntity().SolveEquation("x")); // { -1/2, 0, 1/2 }
Making that the default is a cost decision — every solve pays for it — so it is the maintainers' call rather than mine. Three options as I see them: raise the default step count; choose the region from the expression rather than fixing it; or leave it and document the setting. Happy to implement whichever.
- added a commit that references this issue
on Aug 5, 2026 Now fixed, in #729, merged to master as 552e825. This supersedes the comment above.
before after "arcsin(x) - x*pi/3".SolveEquation("x"){ 0 }{ -1/2, 0, 1/2 }the same via SolveNt1 root 3 roots Which is the desired output in the report, exactly.
The comment above had the diagnosis right — "the default grid is 10 steps over a region that does not tighten around the interval where the roots live" — but read it as something only a finer grid could fix. It is worth saying why that was too pessimistic.
The grid is two-dimensional: a step count of N costs N² Newton runs but lays real starting points only
(To - From) / Napart. At the default that is 2, and the three roots span one unit in total, so they shared a single starting point. Buying real-axis resolution by raising N costs N², which is what made this look expensive.But a sign change is a far cheaper witness of a root than a Newton run is — one evaluation against the sixty an iteration to precision 30 costs. So the real axis is now scanned at
StepCount.Re * StepCount.Impoints, as many as the grid has starting points, and Newton runs only from the brackets it finds. The spacing that matters for a real root becomes(To - From) / N²rather than(To - From) / N— 0.2 at the default rather than 2 — for about 2% of what the grid already spends. No setting has to change.One thing the comment above got wrong and worth correcting: it treated close roots as generally unreachable. They are not.
x*(x - 1/2)*(x + 1/2)has roots the same 0.5 apart and gave all three even before this, because a polynomial's basins interleave across the whole plane.arcsinis the hard case because outside [-1, 1] every starting point hands it a complex value and the iteration wanders off — so the failure was specific to an expression that is real only on a small interval, not to close roots as such.The fix is additive and the grid is untouched. A sign change witnesses a root of odd multiplicity on an interval where the expression is real, so repeated roots (
x^2 + 2x + 1) and roots off the real axis (x^2 + 1) stay the grid's to find; tests pin both. Regression tests inSolverRegressionTest.csandNewtonGridTest.cs. Full suite green, 117-problem corpus unchanged.- added a commit that references this issue
on Aug 8, 2026
Yes, this equation does not have analytical solution, but
SolveNt()can (and should!) find all roots, as their number is finiteOutput:
{0}Desired output:
{-1/2, 0, 1/2}