# find_root does not fulfill tolerance

In Sage 7.3 the result of:

find_root((4*x^4-x^2).function(x),-0.25,0.4,xtol=1e-13,rtol=1e-13)


is

1.6619679287440101e-10


One would expect that the error with the exact solution (x=0) would be lower than 1e-13. I imagine that the multiplicity of the root produces this effect. Does somebody know the numerical algorithm behind find_root?

UPDATE: Thanks to @kcrisman, I see that find_root calls brentq. The documentation of such function says:

Safer algorithms are brentq, brenth, ridder, and bisect, but they all require that the root first be bracketed in an interval where the function changes sign. The brentq algorithm is recommended for general use in one dimensional problems when such an interval has been found.

Since 4x^4-x^2 has a root in 0 with multiplicity 2, this condition is not fulfilled. Is there any other command in Sage different from find_root to numerically calculate roots for general functions that can handle with roots with multiplicity bigger than 1?

edit retag close merge delete

Sort by » oldest newest most voted

If you do find_root?? you will see that the final line of code is a Scipy algorithm:

return scipy.optimize.brentq(f, a, b,
full_output=full_output, xtol=xtol, rtol=rtol, maxiter=maxiter)


The Scipy doc indicates it should indeed return within the tolerance expected, so I'm not sure what is going on, but at least this is where you should start your search.

more

brentq requires a sign change of $f$ in the given interval, but this cannot be achieved in $[-0.25, 0.4]$ (note that $f$ is tangent to $y=0$ at $0$). Maybe that's the reason?

( 2017-02-09 13:08:04 -0500 )edit

Maybe - I see what you mean here. But some experimentation with some perturbations of your example don't give me confidence, since it doesn't satisfy its own documentation - http://sagecell.sagemath.org/?z=eJxtj...

( 2017-02-09 14:36:28 -0500 )edit

..still i think this is a border case, because the root cannot be properly "enclosed". For completeness: it is also possible to do R.<x> = RDF[], f = 4*x^4 - x^2, f.roots().

( 2017-02-09 15:59:37 -0500 )edit

Hmm, but RDF doesn't even do more than a certain tolerance. Maybe it only supports tol up to a certain point?

( 2017-02-09 16:53:34 -0500 )edit
1

@kcrisman Yes, I think that's the case; some experiments with the function 4*x^4-x^2+0.01 around the exact root -1/2*sqrt(-1/10*sqrt(21) + 1/2) (this time in $[-0.25, 0.0]$) show it works ok until rtol is too small, giving ValueError: rtol too small (1e-16 < 4.44089e-16). But alternatively for the OP's question, let us now that using Newton's method, as in newton(4*x^4-x^2, -0.25, tol=1e-14, maxiter=3000), it will pass the tests with 1e-13 (and smaller).

( 2017-02-12 12:49:49 -0500 )edit