Solve for roots in given interval using scipy.optimize
<p>I have the function <code>f1 = lambda x: 1 - 1.12 * (x ** 0.5) * ((1-x) ** 0.02)</code>, and I wish to solve for its roots in the interval (0, 1). I have tried using the <code>scipy.optimize.brentq</code> and <code>scipy.optimize.fsolve</code> to do this, but both methods run into issues. Based on some experimentation, I got that the roots of this equation are approximately equal to 0.86322414 and 0.9961936895432034 (we know there are at most 2 roots because the function has one inflection point in this interval):</p>

<pre><code>f1 = lambda x: 1 - 1.12 * (x ** 0.5) * ((1-x) ** 0.02)
print(fsolve(f1, 0.5))
print(f1(0.99))
print(f1(0.999))
print(brentq(f1, 0.99, 0.999))
</code></pre>

<p>Output: </p>

<pre><code>[ 0.86322414]
-0.016332046983897452
0.025008640855473052
0.9961936895432034
</code></pre>

<p>The issue here is that in order for brentq to work, the values of the function must be of opposite signs at the specified endpoints. Furthermore, when I started fsolve at values of <code>x</code> close to 1, I got runtime warning messages:</p>

<pre><code>print(fsolve(f1, 0.97))
print(fsolve(f1, 0.98))
</code></pre>

<p>Output:</p>

<pre><code>[ 0.97]
[ 0.98]
C:/Users/Alexander/Google Drive/Programming/Projects/Root Finding/roots.py:6: RuntimeWarning: invalid value encountered in power

C:\Users\Alexander\Anaconda3\lib\site-packages\scipy\optimize\minpack.py:161: RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last ten iterations.
</code></pre>

<p>Does anyone if there is a more systematic way to solve for roots of this equation, and why fsolve is not working on <code>x = 0.97, 0.98</code>?</p>

<p>fsolve does not support root-finding on an interval. It likely wanders off to either x&lt;0 or x>1, hence RuntimeWarning (once) and garbage for the answer. You can check it by instrumenting your function with print(x).</p>

<p>Brentq's behavior is undefined if the interval contains more then one root.</p>

<p>If you know the inflection point, or know that there's only one, then you can find it via brentq and use it to bracket your two roots.</p>

python optimization scipy polynomial-math