From 8feb5a96dd1edc16fa59fbd824eafb5942956d2b Mon Sep 17 00:00:00 2001 From: Eran Assaf Date: Fri, 7 Sep 2018 11:07:28 +0100 Subject: [PATCH] Fixed bug in find_root when full_output=True (size check assumed it was false) Also fixed the doctesting in expression.pyx for 1/tan(x) --- src/sage/numerical/optimize.py | 9 +++++++-- src/sage/symbolic/expression.pyx | 12 +++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index efaf7c9765d..b3b7a481a2d 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -141,15 +141,20 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals a = s import scipy.optimize - root = scipy.optimize.brentq(f, a, b, + brentqRes = scipy.optimize.brentq(f, a, b, full_output=full_output, xtol=xtol, rtol=rtol, maxiter=maxiter) # A check following ticket 4942, to ensure we actually found a root # Maybe should use a different tolerance here? # The idea is to take roughly the derivative and multiply by estimated # value of the root + root = 0 + if (full_output): + root = brentqRes[0] + else: + root = brentqRes if (abs(f(root)) > max(abs(root * rtol * (right - left) / (b - a)), 1e-6)): raise RuntimeError("Brent's method failed to find a zero for f on the interval") - return root + return brentqRes def find_local_maximum(f, a, b, tol=1.48e-08, maxfun=500): """ diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 7e1c62f1f8b..4e839da60bd 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -11733,8 +11733,18 @@ cdef class Expression(CommutativeRingElement): -0.588532743981862... sage: sin(x).find_root(-1,1) 0.0 - sage: (1/tan(x)).find_root(3,3.5) + + This example was ixed along with ticket 4942 - + there was an error in the example + pi is a root for tan(x), but an asymptote to 1/tan(x) + added an example to show handling of both cases:: + + sage: (tan(x)).find_root(3,3.5) 3.1415926535... + sage: (1/tan(x)).find_root(3, 3.5) + Traceback (most recent call last): + ... + RuntimeError: Brent's method failed to find a zero for f on the interval An example with a square root::