title: root finding in python
body: <p>Edit: A big issue here is that <code>scipy.optimize.brentq</code> requires that the limits of the search interval have opposite sign. If you slice up your search interval into arbitrary sections and run <code>brentq</code> on each section as I do below and as Dan does in the comments, you wind up throwing a lot of useless ValueErrors. Is there a slick way to deal with this in Python?</p>
  
  <p>Original post:
  I'm repeatedly searching functions for their largest zero in python. Right now I'm using <a href="//docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html" rel="nofollow noreferrer"><code>scipy.optimize.brentq</code></a> to look for a root and then using a brutish search method if my initial bounds don't work:</p>
  
  <pre><code>#function to find the largest root of f
  def bigRoot(func, pars):
      try:
          root = brentq(func,0.001,4,pars)
      except ValueError:
          s = 0.1
          while True:
              try:
                  root = brentq(func,4-s,4,pars)
                  break
              except ValueError:
                  s += 0.1
                  continue
      return root
  </code></pre>
  
  <p>There are two big problems with this.</p>
  
  <p>First I assume that if there are multiple roots in an interval, brentq will return the largest. I did some simple testing and I've never seen it return anything except the largest root but I don't know if that's true in all cases.</p>
  
  <p>The second problem is that in the script I'm using this function will always return zero in certain cases even though the function I pass to <code>bigRoot</code> diverges at 0. If I change the step size of the search from 0.1 to 0.01 then it will return a constant nonzero value in those cases. I realize the details of that depend on the function I'm passing to <code>bigRoot</code> but I think the problem might be with the way I'm doing the search. </p>
  
  <p>The question is, what's a smarter way to look for the largest root of a function in python?</p>
  
  <hr>
  
  <p>Thanks Dan; a little more info is below as requested.</p>
  
  <p>The functions I'm searching are well behaved in the regions I'm interested in. An example is plotted below (code at the end of the post).</p>
  
  <p><img src="https://i.stack.imgur.com/GjD0e.png" alt="I&#39;d like to find the largest root of this function"></p>
  
  <p>The only singular point is at 0 (the peak that goes off the top of the plot is finite) and there are either two or three roots. The largest root usually isn't greater than 1 but it never does anything like run away to infinity. The intervals between roots get smaller at the low end of the domain but they'll never become extremely small (I'd say they'll always be larger than 10^-3).</p>
  
  <pre><code>from numpy import exp as e
  #this isn't the function I plotted
  def V(r):
      return  27.2*(
                  23.2*e(-43.8*r) + 
                  8.74E-9*e(-32.9*r)/r**6 - 
                  5.98E-6*e(-0.116*r)/r**4 + 
                  0.0529*( 23*e(-62.5*r) - 6.44*e(-32*r) )/r -
                  29.3*e(-59.5*r)
              )
  
  #this is the definition of the function in the plot
  def f(r,b,E):
      return 1 - b**2/r**2 - V(r)/E
  
  #the plot is of f(r,0.1,0.06)
  </code></pre>