Perhaps someone who knows how NSolve
works will comment on my speculations or even answer. But since this question has languished, I'll share how it appears to me.
It appears to me that increasing the precision of the approximations of the roots is a minor expense relative to finding the roots. It is perhaps so minor that a PrecisionGoal
option seemed pointless to the developers. There is a jump in timing when the precision reaches machine precision, but that may be because arithmetic becomes more expensive.
Indeed, the computed solutions at precisions below machine precision are identical, except that the returned solutions have different precisions. The underlying numbers appear to be the same. We can examine them by setting the precision of the solutions to infinity.
The following converts a set of approximate solutions to the (exact) rational numbers computed.
solbits[wp_: MachinePrecision] := x /. SetPrecision[
NSolve[x^5 - 3 x^4 + 3 x^3 - 4 x^2 + 15 x == 7, x,
WorkingPrecision -> wp],
Infinity]
Below I compare the numbers computed for increasing settings for WorkingPrecision
. The second set of differences show the lengths of the runs
of the settings for which the numbers computed for the approximate solutions are the same. The initial 15
shows that the numbers computed at working precisions below machine precision are identical.
solpos = SparseArray[
Max /@ Abs@Differences@Table[solbits[wp], {wp, 1, 100}]
]["NonzeroPositions"]
Differences@Flatten[{0, solpos}]
(*
{{15}, {16}, {19}, {20}, {21}, {22}, {31}, {32}, {33}, {38}, {39}, {41}, \
{42}, {43}, {45}, {46}, {54}, {55}, {56}, {57}, {58}, {63}, {64}, {65}, {66}, \
{67}, {77}, {85}, {94}, {95}, {96}}
{15, 1, 3, 1, 1, 1, 9, 1, 1, 5, 1, 2, 1, 1, 2, 1, 8, 1, 1, 1, 1, 5, 1, 1, 1, \
1, 10, 8, 9, 1, 1}
*)
The plot below shows that the time spent by NSolve
is roughly the same for working precisions below machine precision, after which the timing rises. The timing continues to rise as working precision is increased beyond machine precision, although the rate is slow.
Needs["GeneralUtilities`"]
g[n_] := NSolve[x^15 - 3 x^4 + 3 x^3 - 4 x^2 + 15 x == 7, x, WorkingPrecision -> n];
BenchmarkPlot[{g[#] &},
# &,
Range[4, 24, 2],
PlotRange -> {{3, 31}, All}]

Conclusion
I do not think you can compute all solutions faster than with MachinePrecision
. The setting of WorkingPrecision
seems to have an palpable effect only for settings above machine precision, something I did not appreciate before. I suspect that having a separate PrecisionGoal
would not meaningfully speed up the computation, mainly because I assume once you're close to the root, a couple of iterations of Newton's method yields results accurate to machine precision. For polynomials this would not be a time-consuming calculation. But it's only a guess.
Caveat: In this exploration I looked only at univariate polynomial equations. Different types of systems probably use different algorithms, which probably have different behaviors.
Note: There is a SystemOptions[]
option "NSolveOptions" -> {"Tolerance" -> 0}
, but changing the setting made no difference. I do not know what the option is for.