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