brent-local-min-generator
Version:
Brent's local minimum finding algorithm, as a generator function.
100 lines (74 loc) • 2.73 kB
JavaScript
const local_mins = require('../local_min_generator.js');
const local_min = local_mins.local_min;
let counter = 0;
function count(f) {
counter = 0;
return function (x) {
counter++;
const fx = f(x);
// console.log('%d: f(%d) = %d', counter, x, fx);
return fx;
}
}
const eps = 10.0 * Math.sqrt(Number.EPSILON);
const g_01 = x => (x - 2) * (x - 2) + 1;
test(g_01 + ' in [0, pi]', () => {
const point = local_min(count(g_01), 0, Math.PI, eps, eps);
expect(point.x).toBeCloseTo(2.000000, 6);
expect(point.fx).toBeCloseTo(1.000000, 6);
expect(counter).toBe(6);
});
const g_02 = x => x * x + Math.exp(-x);
test(g_02 + ' in [0, 1]', () => {
const point = local_min(count(g_02), 0, 1, eps, eps);
expect(point.x).toBeCloseTo(0.351734, 6);
expect(point.fx).toBeCloseTo(0.827184, 6);
expect(counter).toBe(9);
});
const g_03 = x => x**4 + 2*x**2 + x + 3;
// const g_03 = x => ((x*x + 2) * x + 1) * x + 3;
test(g_03 + ' in [-2, 2]', () => {
const point = local_min(count(g_03), -2, 2, eps, eps);
expect(point.x).toBeCloseTo(-0.236733, 6);
expect(point.fx).toBeCloseTo(2.878493, 6);
expect(counter).toBe(11);
});
const g_04 = x => Math.exp(x) + 1 / (100 * x);
test(g_04 + ' in [0.0001, 1]', () => {
const point = local_min(count(g_04), 0.0001, 1, eps, eps);
expect(point.x).toBeCloseTo(0.095345, 6);
expect(point.fx).toBeCloseTo(1.204921, 6);
expect(counter).toBe(13);
});
const g_05 = x => Math.exp(x) - 2 * x + 1 / (100 * x) - 1 / (1000000 * x ^ 2);
test(g_05 + ' in [0.0002, 2]', () => {
const point = local_min(count(g_05), 0.0002, 2, eps, eps);
expect(point.x).toBeCloseTo(0.703205, 5);
expect(point.fx).toBeCloseTo(0.628026, 6);
expect(counter).toBe(11);
});
const hb_01 = x => 1 / x + x;
test(hb_01 + ' in [0.1, 10]', () => {
let point = local_min(count(hb_01), 0.1, 10, eps, eps);
expect(point.x).toBeCloseTo(1, 6);
expect(point.fx).toBeCloseTo(2, 6);
expect(counter).toBe(14);
point = local_min(count(hb_01), 0.1, 10, eps);
expect(point.x).toBeCloseTo(1, 6);
expect(point.fx).toBeCloseTo(2, 6);
expect(counter).toBe(14);
});
// 3 (x - 1) * (x - 3) = 3x^2 - 12x + 9
const hb_02 = x => x**3 - 6 * x**2 + 9 * x + 3;
test(hb_02 + ' minimum in [2.3, 3.3]', () => {
const point = local_min(count(hb_02), 2.3, 3.3, eps);
expect(point.x).toBeCloseTo(3, 6);
expect(point.fx).toBeCloseTo(3, 6);
expect(counter).toBe(9);
});
test(hb_02 + ' maximum in [0.25, 1.25]', () => {
const point = local_min(count(x => -hb_02(x)), 0.25, 1.25, eps);
expect(point.x).toBeCloseTo(1, 6);
expect(point.fx).toBeCloseTo(-7, 6);
expect(counter).toBe(9);
});