UNPKG

brent-local-min-generator

Version:

Brent's local minimum finding algorithm, as a generator function.

120 lines (88 loc) 4.47 kB
# brent-local-min-generator This module implements Brent's algorithm to find a local minimum of a function *f* in an interval. This algorithm can also be used to find a maximum. If there is only a single minimum/maximum in the interval, that minimum/maximum will be found. The algorithm is implemented as a generator function `local_min_generator()`. This not only allows an asynchronous function to be minimized using the algorithm, but also gives a lot of flexibility (see example below). The module also provides a simple function `local_min()` to run the generator function to minimize synchronous functions, passed as a callback, and simplify its use. ## Installation Use the package manager to install the package `brent-local-min-generator`. ```bash npm install brent-local-min-generator ``` ## Usage The JavaScript code for the generator `local_min_generator()` follows Brent's original code of the Algol 60 procedure `local_min()` very closely. ### Parameters In the first comment in his code, Brent describes procedure `local_min()` as: > If the function *f* is defined on the interval (*a*, *b*), then `local_min()` finds an approximation *x* to the point at which *f* attains its minimum (or the appropriate limit point), and returns the value of *f* at *x*. *t* and *eps* define a tolerance *tol = eps |x| + t*, and *f* is never evaluated at two points closer together than *tol*. > |parameter | description |----------|------------ |f | the function `f()` for which the minimum is sought. Only for the utility function `local_min()`. |a | the finite lower bound of the interval in which to search the minimum |b | the finite upper bound of the interval in which to search the minimum |eps | the relative tolerance. `eps` should be no smaller than `2 * Number.EPSILON`, and preferably not much less than `Math.sqrt(Number.EPSILON)`. (optional, default: `2 * Number.EPSILON`) |t | the absolute tolerance, should be positive. (optional, default: `0.0`) ### Functions - `local_min_generator(a, b, eps, t)`, and - `local_min(f, a, b, eps, t)`. Both functions return an object with 2 properties: - `x`: the x value for which the minimum was found, - `fx`: the function `f` value in the minimum. ## Examples The examples assume the module has been loaded ``` js const brents = require('brent-local-min-generator'); ``` Consider the following function: ``` js const f = x => x**3 + 1.5 * x**2 - 18 * x + 4; ``` ![function image](https://bieshaar.org/images/local-min-example.png)] ### Example 1: simple minimization ``` js // minimize f(x) in the interval [0.5, 4] console.log( brents.local_min(f, 0.5, 4) ); // expect: {x: 2, fx: -18} ``` ### Example 2: simple maximization ``` js // maximize f(x) in the interval [-5, -2] const point = brents.local_min(x => -f(x), -5, -2); point.fx *= -1; console.log(point); // expect {x: -3, fx: 44.5}. ``` ### Example 3: using the generator ``` js // minimize f(x) in (0.5, 4) const gen = brents.local_min_generator(0.5, 4); let result = gen.next(); while ( ! result.done ) { const x = result.value; const y = f(x); result = gen.next(y) } console.log( result.value ); // expect {x: 2, fx: -18} ``` ### Example 4: customized minimum Often implementations have an additional parameters for maximum number of iterations (`max_iter`). Brent's original code does not have this option, but using the generator function, they are easily implemented, as the following example function shows: ``` js function myLocalMin(f, a, b, max_iter) { const gen = local_min_generator(a, b); let result = gen.next(); for (let i=0; i<max_iter && ! result.done; ++i) { const x = result.value; const y = f(x); result = gen.next(y) } return result.value; } ``` ## Further Documentation The ultimate documentation on this algorithm can be found on Emeritus Professor Richard P. Brent's [homepage](https://maths-people.anu.edu.au/~brent/), and his page dedicated to his book [Algorithms for Minimization Without Derivatives](https://maths-people.anu.edu.au/~brent/pub/pub011.html). On the page for the book, not only the errata for the different editions of the book are available, but also scanned copy of the Prentice-Hall edition. C, C++, Fortran77 and Fortran90 codes can be found on John Burkardt's [homepage](https://people.sc.fsu.edu/~jburkardt/). ## License [ISC](https://choosealicense.com/licenses/isc/)