findRoot

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

  1. Real[] findRoot(Func f, Real[] guess, Real epsRel, int maxFuncEvals, Real[] buffer)
    Real[]
    findRoot
    (
    Real
    Func
    )
    (
    scope Func f
    ,
    Real[] guess
    ,
    Real epsRel
    ,
    int maxFuncEvals = 0
    ,
    Real[] buffer = null
    )
    if (
    isFloatingPoint!Real &&
    isVectorField!(Func, Real)
    )
  2. T findRoot(F f, T x0, T scale, T xMin, T xMax, int precision)
  3. T findRoot(F f, T x0, T scale, int precision)
  4. T findRoot(F f, T x0, T scale, T xMin, T xMax)

Parameters

f Func

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 Real[]

A starting point for the algorithm. The closer this guess is to the true root, the greater chance that the algorithm converges.

epsRel Real

Success criterion: The algorithm stops when the relative error between two consecutive iterations is at most epsRel.

maxFuncEvals int

(optional) The maximum number of function evaluations. If maxFuncEvals<1, it is set to 200*(N+1).

buffer Real[]

(optional) A buffer of length at least N, for the return value.

Examples

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!

Meta