Repository: scipy/scipy

Issue:
Is Brent's method for minimizing the value of a function implemented twice in SciPy?
Copied from the mailing list question http://mail.scipy.org/pipermail/scipy-dev/2014-July/019959.html.

```
Hello,

while studying the SciPy documentation, I noticed that the 'brent' and
the 'fminbound' function in the 'scipy.optimize' package both seem to
implement Brent's method for function minimization.

Both functions have been implemented by Travis Oliphant (see commit
infos below).

One minor difference is, that the 'brent' function _optionally_ allows
for auto bracketing via the help of the 'bracket' function, when
supplied only with two bounds via the 'brack' parameter instead of a
triplet as required by Brent's algorithm.

So is it possible, that Brent's method has been implemented twice?


'fminbound' was added in 2001:

https://github.com/scipy/scipy/commit/3f44f63b481abf676a0b344fc836acf76bc86b35

'brent' was added approximately three-quarters of a year later in 2002:

https://github.com/scipy/scipy/commit/b94c30dcb1ba9ad0b4c3e2090f5e99a8a21275ab

The 'brent' code has later been moved into a separate internal class:

https://github.com/scipy/scipy/commit/675ad592465be178cde88a89e9e362fdd5237004


Sincerely,
Alexander Behringer
```



Discussion:
Without looking at the implementations,  `brent` does not ensure that the located minimum is within the initial interval.  `bound` does ensure this, even if it uses Brent's method to find the minimum.

Perhaps there are things that could be shared between them or the implementations merged, but I don't know that it would really gain us anything.

whatever the difference is should be in the docstrings at least

okay, labeling this issue as a doc improvement task


Resolving patch:
diff --git a/scipy/optimize/optimize.py b/scipy/optimize/optimize.py
--- a/scipy/optimize/optimize.py
+++ b/scipy/optimize/optimize.py
@@ -1953,9 +1953,9 @@ def get_result(self, full_output=False):
 
 def brent(func, args=(), brack=None, tol=1.48e-8, full_output=0, maxiter=500):
     """
-    Given a function of one-variable and a possible bracketing interval,
-    return the minimum of the function isolated to a fractional precision of
-    tol.
+    Given a function of one-variable and a possible bracket, return
+    the local minimum of the function isolated to a fractional precision
+    of tol.
 
     Parameters
     ----------
@@ -1998,6 +1998,28 @@ def brent(func, args=(), brack=None, tol=1.48e-8, full_output=0, maxiter=500):
     Uses inverse parabolic interpolation when possible to speed up
     convergence of golden section method.
 
+    Does not ensure that the minimum lies in the range specified by
+    `brack`. See `fminbound`.
+    
+    Examples
+    --------
+    We illustrate the behaviour of the function when `brack` is of
+    size 2 and 3 respectively. In the case where `brack` is of the
+    form (xa,xb), we can see for the given values, the output need
+    not necessarily lie in the range (xa,xb).
+
+    >>> def f(x):
+    ...     return x**2
+    
+    >>> from scipy import optimize
+
+    >>> minimum = optimize.brent(f,brack=(1,2))
+    >>> minimum
+    0.0
+    >>> minimum = optimize.brent(f,brack=(-1,0.5,2))
+    >>> minimum
+    -2.7755575615628914e-17
+
     """
     options = {'xtol': tol,
                'maxiter': maxiter}


Test patch: