Function bracketRoot

Bracket a root of the function f.

RootBracket!(T,ReturnType!F) bracketRoot(F, T) (
  scope F f,
  in T x0,
  in T scale,
  in T xMin = -T.infinity,
  in T xMax = T.infinity
)
if (isFloatingPoint!T && isUnaryFunction!(F, T));

If a function f(x) is continuous on an interval [x1,x2], and f(x1) and f(x2) have opposite sign, we know the function must pass through zero somewhere in the interval. The points x1 and x2 are then said to 'bracket' the root. This is usually the first step in locating the root of a function.

If this function succeeds, it returns a RootBracket containing the points x1 and x2, together with the function values f(x1) and f(x2). If it fails, an exception is thrown. Note that this library considers the points to be bracketing a root also if the root is located exactly at x1 and/or x2, i.e. if f(x1)=0 and/or f(x2)=0.

Details

This function will start by evaluating f(x) in the points x0 and x0+scale and see if those points bracket a root of the given function. If not, the interval is expanded geometrically (i.e. the distance between the points is multiplied by a constant factor), always in the direction where f(x) is smallest, until the points bracket a root.

You may optionally specify a limiting interval [xMin, xMax], and the algorithm will never search outside it. This is useful, for instance, for functions that are only defined for certain values of x. If you do specify such an interval, the initial point x0 must lie inside it.

It is usually worthwhile analysing the behaviour of the function in order to find appropriate values for x0 and scale. The closer x0 is to the actual root, the fewer steps (i.e. the fewer evaluations of f) this algorithm will require to succeed. If scale is too large, and the function has several roots, there is a chance that it will just step across both roots and not find any of them. On the other hand, if it is too small, it may again cause the algorithm to take more steps than would otherwise be necessary.