UNPKG

2.71 kBJavaScriptView Raw
1/**
2 * @copyright 2013 Sonia Keys
3 * @copyright 2016 commenthol
4 * @license MIT
5 * @module iterate
6 */
7/**
8 * Iterate: Chapter 5, Iteration.
9 *
10 * This package is best considered illustrative. While the functions are
11 * usable, they are minimal in showing the points of the chapter text. More
12 * robust functions would handle more cases of overflow, loss of precision,
13 * and divergence.
14 */
15
16/**
17 * decimalPlaces iterates to a fixed number of decimal places.
18 *
19 * Inputs are an improvement function, a starting value, the number of
20 * decimal places desired in the result, and an iteration limit.
21 *
22 * @throws Error
23 * @param {Function} better
24 * @param {Number} start - (float)
25 * @param {Number} places - (int)
26 * @param {Number} maxIterations - (int)
27 * @returns {Number}
28 */
29export function decimalPlaces(better, start, places, maxIterations) {
30 var d = Math.pow(10, -places);
31 for (var i = 0; i < maxIterations; i++) {
32 var n = better(start);
33 if (Math.abs(n - start) < d) {
34 return n;
35 }
36 start = n;
37 }
38 throw new Error('Maximum iterations reached');
39}
40
41/**
42 * fullPrecison iterates to (nearly) the full precision of a float64.
43 *
44 * To allow for a little bit of floating point jitter, FullPrecision iterates
45 * to 15 significant figures, which is the maximum number of full significant
46 * figures representable in a float64, but still a couple of bits shy of the
47 * full representable precision.
48 *
49 * @throws Error
50 * @param {Function} better
51 * @param {Number} start - (float)
52 * @param {Number} maxIterations - (int)
53 * @returns {Number}
54 */
55export function fullPrecision(better, start, maxIterations) {
56 for (var i = 0; i < maxIterations; i++) {
57 var n = better(start);
58 if (Math.abs((n - start) / n) < 1e-15) {
59 return n;
60 }
61 start = n;
62 }
63 throw new Error('Maximum iterations reached');
64}
65
66/**
67 * binaryRoot finds a root between given bounds by binary search.
68 *
69 * Inputs are a function on x and the bounds on x. A root must exist between
70 * the given bounds, otherwise the result is not meaningful.
71 *
72 * @param {Function} f - root function
73 * @param {Number} lower - (float)
74 * @param {Number} upper - (float)
75 * @returns {Number}
76 */
77export function binaryRoot(f, lower, upper) {
78 var yLower = f(lower);
79 var mid = 0;
80 for (var j = 0; j < 52; j++) {
81 mid = (lower + upper) / 2;
82 var yMid = f(mid);
83 if (yMid === 0) {
84 break;
85 }
86 if (signbit(yLower) === signbit(yMid)) {
87 lower = mid;
88 yLower = yMid;
89 } else {
90 upper = mid;
91 }
92 }
93 return mid;
94}
95
96function signbit(v) {
97 return v < 0;
98}
99
100export default {
101 decimalPlaces: decimalPlaces,
102 fullPrecision: fullPrecision,
103 binaryRoot: binaryRoot
104};
\No newline at end of file