title: Finding multiple roots on an interval with Python
body: <p>I'm looking for an efficient method to find all the roots of a function f on an interval [a,b]. 
  The problem I have is that all the nice methods from scipy.optimize require either that f(a) and f(b) have different signs, or that I provide an initial guess x0, but I know nothing about my roots before running the code.</p>
  
  <p><strong>Note:</strong> The function f is smooth (at least C1), and doesn't have a pathological behaviour [nothing like sin(1/x)]. However, it requires building a matrix A(x) and finding its eigenvalues, and is therefore time-consuming. It is expected to have between 0 and 10 roots on [a,b], whose position is completely arbitrary. I can't afford missing any of them (e.g. I can't take 100 initial guesses x0 and just hope that i'll catch all the roots).</p>
  
  <p>I was thinking about implementing something like this:</p>
  
  <ol>
  <li>Find all the extrema {m_1, m_2.., m_k} of f with scipy.optimize [maybe fmin, but I don't know which method is the most efficient]:
  
  <ul>
  <li>Search for a minimum m_1 starting from point a [initial guess for gradient algorithm]</li>
  <li>Search for a maximum m_2 starting from point m_1 + dx [forcing the gradient algorithm to go forward]</li>
  <li>Search for a minimum m_3...</li>
  </ul></li>
  <li>If two consecutive extrema m_i and m_(i+1) have opposite signs, apply brentq on interval [m_i, m_(i+1)] to find a root.</li>
  </ol>
  
  <hr>
  
  <ul>
  <li><p>Is there a better way of solving this problem?</p></li>
  <li><p>If not, are fmin and brentq the best choices among the scipy.optimize library in order to minimize the number of calls to my function f?</p></li>
  </ul>