findRoot - multiple declarations

Function findRoot

Searches for a root of N functions of N variables using a variant of the Powell Hybrid Method (the HYBRD routine from MINPACK).

Real[] findRoot(Real, Func) (
  scope Func f,
  Real[] guess,
  Real epsRel,
  int maxFuncEvals = 0,
  Real[] buffer = null
)
if (isFloatingPoint!Real && isVectorField!(Func, Real));

Parameters

NameDescription
f The set of equations, given as a function, delegate or functor that takes an array of length N as input and returns an array of length N. If the function has an additional array input parameter this will be assumed to be a buffer for the output value.
guess A starting point for the algorithm. The closer this guess is to the true root, the greater chance that the algorithm converges.
epsRel Success criterion: The algorithm stops when the relative error between two consecutive iterations is at most epsRel.
maxFuncEvals (optional) The maximum number of function evaluations. If maxFuncEvals<1, it is set to 200*(N+1).
buffer (optional) A buffer of length at least N, for the return value.

Example

The Rosenbrock function is a commonly used test problem for optimisation algorithms. It has a global minimum at (1,1) that is hard to locate numerically because it lies in a long, narrow valley. Instead of using an optimisation algorithm, let us try to locate the minimum by finding the root of the Rosenbrock function's gradient.

// The Rosenbrock function is defined as
//     f(x,y) = (1-x)^2 + 100 (y-x^2)^2.
// Thus, its gradient is:
real[] dRosenbrock(real[] v, real[] buf)
{
    auto x = v[0], y = v[1];
    buf[0] = -2*(1-x) - 400*x*(y-x*x);
    buf[1] = 200 * (y-x*x);

    return buf;
}

real[] guess = [ 2.0, 2.0 ];
auto root = findRoot(&dRosenbrock, guess, 0.0L);

writeln(root);  // Prints "1 1". Yay!

Function findRoot

Find a root of the function f.

T findRoot(F, T) (
  scope F f,
  T x0,
  T scale,
  T xMin,
  T xMax,
  int precision
)
if (isUnaryFunction!(F, T) && isFloatingPoint!T);

T findRoot(F, T) (
  scope F f,
  T x0,
  T scale,
  int precision
)
if (isUnaryFunction!(F, T) && isFloatingPoint!T);

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

This function first calls bracketRoot to obtain an interval inside which there must be a root, and then calls std.numeric.findRoot() to pin down the location of the root.

The parameters x0, scale, xMin, and xMax are just passed on to bracketRoot, and they are described in detail in its documentation. In brief, x0 should be an estimate of the root's location, while scale should be a characteristic scale for the function, i.e. a distance over which the function changes significantly. [xMin,xMax] is the interval inside which the algorithm is allowed to search.

You may specify the desired (minimum) number of digits of precision in the answer. If this is left out, the algorithm will attempt to achieve full machine precision.