@interstellar-tools/equations 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,7 +27,12 @@ import type { Radians } from '@interstellar-tools/types';
27
27
  *
28
28
  * **Solving Strategy:**
29
29
  * 1. **Initial Guess:**
30
- * - The solver starts with $E_0 = M$ and refines using:
30
+ * - **Elliptical** ($e < 1$): the equation is $2\pi$-periodic, so $M$ is first reduced to one
31
+ * turn with its sign kept ($M \bmod 2\pi$), then Danby's starting value is used:
32
+ * $$
33
+ * E_0 = M + 0.85\, e \,\operatorname{sign}(\sin M)
34
+ * $$
35
+ * - **Hyperbolic** ($e > 1$):
31
36
  * $$
32
37
  * E_0 = M \pm \frac{e \sin(M)}{1 - e \cos(M)}
33
38
  * $$
@@ -51,7 +56,8 @@ import type { Radians } from '@interstellar-tools/types';
51
56
  * (default tolerance is **1e-9**).
52
57
  *
53
58
  * 3. **Angle Wrapping (Elliptical Only):**
54
- * - The result is wrapped using `wrapAngle()` for consistency.
59
+ * - The result is wrapped using `wrapAngle()`, which keeps the sign: $E \in (-2\pi, 2\pi)$ with
60
+ * the sign of $M$. Use `solveKepler()` for a result normalized to $[0, 2\pi)$.
55
61
  *
56
62
  *
57
63
  * **Performance Considerations:**
@@ -63,7 +69,7 @@ import type { Radians } from '@interstellar-tools/types';
63
69
  * @param {number} e - Orbital eccentricity ($e > 0.9$ for high-eccentricity orbits).
64
70
  * @param {number} [maxIter=Math.max(300, Math.floor(5 + 3 * Math.log(1 + Math.abs(M))))] - Maximum number of **iterations** before failure.
65
71
  * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
66
- * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[-\pi, \pi]$ for elliptical orbits).
72
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (for elliptical orbits in $(-2\pi, 2\pi)$, with the sign of $M$).
67
73
  *
68
74
  *
69
75
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler-high-eccentricity.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAKzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AAEH,eAAO,MAAM,2BAA2B,GACtC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,gBAAsE,EACtE,kBAAgB,KACf,OAgEF,CAAC"}
1
+ {"version":3,"file":"solve-kepler-high-eccentricity.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAKzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AAEH,eAAO,MAAM,2BAA2B,GACtC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,gBAAsE,EACtE,kBAAgB,KACf,OAqEF,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { TWO_PI } from '@interstellar-tools/constants';
1
2
  import { wrapAngle } from '../angle/wrap-angle.js';
2
3
  /* node:coverage disable */
3
4
  /**
@@ -28,7 +29,12 @@ import { wrapAngle } from '../angle/wrap-angle.js';
28
29
  *
29
30
  * **Solving Strategy:**
30
31
  * 1. **Initial Guess:**
31
- * - The solver starts with $E_0 = M$ and refines using:
32
+ * - **Elliptical** ($e < 1$): the equation is $2\pi$-periodic, so $M$ is first reduced to one
33
+ * turn with its sign kept ($M \bmod 2\pi$), then Danby's starting value is used:
34
+ * $$
35
+ * E_0 = M + 0.85\, e \,\operatorname{sign}(\sin M)
36
+ * $$
37
+ * - **Hyperbolic** ($e > 1$):
32
38
  * $$
33
39
  * E_0 = M \pm \frac{e \sin(M)}{1 - e \cos(M)}
34
40
  * $$
@@ -52,7 +58,8 @@ import { wrapAngle } from '../angle/wrap-angle.js';
52
58
  * (default tolerance is **1e-9**).
53
59
  *
54
60
  * 3. **Angle Wrapping (Elliptical Only):**
55
- * - The result is wrapped using `wrapAngle()` for consistency.
61
+ * - The result is wrapped using `wrapAngle()`, which keeps the sign: $E \in (-2\pi, 2\pi)$ with
62
+ * the sign of $M$. Use `solveKepler()` for a result normalized to $[0, 2\pi)$.
56
63
  *
57
64
  *
58
65
  * **Performance Considerations:**
@@ -64,7 +71,7 @@ import { wrapAngle } from '../angle/wrap-angle.js';
64
71
  * @param {number} e - Orbital eccentricity ($e > 0.9$ for high-eccentricity orbits).
65
72
  * @param {number} [maxIter=Math.max(300, Math.floor(5 + 3 * Math.log(1 + Math.abs(M))))] - Maximum number of **iterations** before failure.
66
73
  * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
67
- * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[-\pi, \pi]$ for elliptical orbits).
74
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (for elliptical orbits in $(-2\pi, 2\pi)$, with the sign of $M$).
68
75
  *
69
76
  *
70
77
  * @example
@@ -96,8 +103,14 @@ export const solveKeplerHighEccentricity = (M, e, maxIter = Math.max(300, Math.f
96
103
  throw new RangeError(`Invalid eccentricity: ${e}. Must be e ≥ 0.`);
97
104
  }
98
105
  let E;
99
- // Use a more accurate initial guess for highly eccentric orbits
100
- if (M < 0) {
106
+ if (e < 1) {
107
+ // The elliptical equation is 2π-periodic: solve within one turn (sign kept),
108
+ // so large |M| doesn't run into the |E| > 100 divergence guard below
109
+ M = (M % TWO_PI);
110
+ // Danby's starting value, good for all 0 ≤ e < 1
111
+ E = M + 0.85 * e * Math.sign(Math.sin(M));
112
+ }
113
+ else if (M < 0) {
101
114
  E = M - (e * Math.sin(M)) / (1 - e * Math.cos(M));
102
115
  }
103
116
  else {
@@ -137,7 +150,7 @@ export const solveKeplerHighEccentricity = (M, e, maxIter = Math.max(300, Math.f
137
150
  break;
138
151
  }
139
152
  }
140
- // **Wrap angles to the range [-π, π] for elliptical orbits**
153
+ // **Wrap angles to (-2π, 2π), keeping the sign, for elliptical orbits**
141
154
  if (e < 1) {
142
155
  lastValidE = wrapAngle(lastValidE);
143
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler-high-eccentricity.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solve-kepler-high-eccentricity.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"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"}
@@ -18,27 +18,23 @@ import type { Radians } from '@interstellar-tools/types';
18
18
  *
19
19
  * **Solving Strategy:**
20
20
  * 1. **Handle Special Cases:**
21
- * - If the orbit is **circular** ($e = 0$), then $E = M$ directly.
22
- * - If the orbit is **nearly parabolic** ($e \geq 0.97$), a special approximation is used.
23
21
  * - If **eccentricity is out of range** ($e < 0$ or $e \geq 1$), a `RangeError` is thrown.
22
+ * - Kepler's equation is $2\pi$-periodic ($M + 2\pi k \mapsto E + 2\pi k$), so the equation is
23
+ * solved for $M \bmod 2\pi$ and the whole turns are added back. Any finite $M$ works,
24
+ * including negative values and many revolutions.
24
25
  *
25
- * 2. **Initial Approximation:**
26
- * - **For small eccentricities ($e < 0.8$):** $E_0 = M$.
27
- * - **For moderate eccentricities ($0.8 \leq e < 0.97$):** $E_0 = M + e \sin(M) (1 + e \cos(M))$.
28
- * - **For nearly parabolic orbits ($e \geq 0.97$):** $E_0 = \frac{6M}{e}$.
26
+ * 2. **Initial Approximation** (Danby 1987, good for all $0 \leq e < 1$):
27
+ * $$
28
+ * E_0 = M + 0.85\, e \,\operatorname{sign}(\sin M)
29
+ * $$
29
30
  *
30
31
  * 3. **Newton-Raphson Iteration with Householder Acceleration:**
31
- * - The **Newton-Raphson method** iterates using:
32
+ * - With $f(E) = E - e \sin(E) - M$, $f'(E) = 1 - e \cos(E)$, $f''(E) = e \sin(E)$ and
33
+ * $f'''(E) = e \cos(E)$, each step refines the Newton correction to third order:
32
34
  * $$
33
- * E_{n+1} = E_n - \frac{f(E_n)}{f'(E_n)}
34
- * $$
35
- * where:
36
- * - $f(E) = E - e \sin(E) - M$
37
- * - $f'(E) = 1 - e \cos(E)$
38
- *
39
- * - **Householder acceleration** refines the correction:
40
- * $$
41
- * \Delta E = \frac{f(E)}{f'(E)} \left( 1 - \frac{1}{2} \frac{f''(E)}{f'(E)} \Delta E \right)^{-1}
35
+ * \delta_1 = -\frac{f}{f'}, \quad
36
+ * \delta_2 = -\frac{f}{f' + \tfrac{1}{2} \delta_1 f''}, \quad
37
+ * \Delta E = -\frac{f}{f' + \tfrac{1}{2} \delta_2 f'' + \tfrac{1}{6} \delta_2^2 f'''}
42
38
  * $$
43
39
  *
44
40
  * 4. **Convergence Check:**
@@ -54,7 +50,7 @@ import type { Radians } from '@interstellar-tools/types';
54
50
  * ---
55
51
  *
56
52
  * **Performance Considerations:**
57
- * - **Typically converges in 4-5 iterations for most eccentricities.**
53
+ * - **Typically converges in 3-4 iterations, including $e \to 1$.**
58
54
  * - **Time complexity:** $O(1)$ for Newton-Raphson.
59
55
  *
60
56
  * ---
@@ -81,6 +77,7 @@ import type { Radians } from '@interstellar-tools/types';
81
77
  * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
82
78
  * @see [Newton-Raphson Method (Wikipedia)](https://en.wikipedia.org/wiki/Newton%27s_method)
83
79
  * @see [Eccentric Anomaly (Wikipedia)](https://en.wikipedia.org/wiki/Mean_anomaly#Eccentric_anomaly)
80
+ * @see Danby, J. M. A. (1987). The solution of Kepler's equation, III. *Celestial Mechanics*, 40, 303–312.
84
81
  * @group Kepler Solvers
85
82
  */
86
83
  export declare const solveKeplerNewtonRaphson: (M: Radians, e: number, maxIter: number, tolerance: number) => Radians | number;
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler-newton-raphson.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-newton-raphson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,eAAO,MAAM,wBAAwB,GACnC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,SAAS,MAAM,EACf,WAAW,MAAM,KAChB,OAAO,GAAG,MAwCZ,CAAC"}
1
+ {"version":3,"file":"solve-kepler-newton-raphson.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-newton-raphson.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,eAAO,MAAM,wBAAwB,GACnC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,SAAS,MAAM,EACf,WAAW,MAAM,KAChB,OAAO,GAAG,MAkCZ,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { TWO_PI } from '@interstellar-tools/constants';
1
2
  /**
2
3
  * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using the **Newton-Raphson method**
3
4
  * with Householder acceleration for fast convergence.
@@ -17,27 +18,23 @@
17
18
  *
18
19
  * **Solving Strategy:**
19
20
  * 1. **Handle Special Cases:**
20
- * - If the orbit is **circular** ($e = 0$), then $E = M$ directly.
21
- * - If the orbit is **nearly parabolic** ($e \geq 0.97$), a special approximation is used.
22
21
  * - If **eccentricity is out of range** ($e < 0$ or $e \geq 1$), a `RangeError` is thrown.
22
+ * - Kepler's equation is $2\pi$-periodic ($M + 2\pi k \mapsto E + 2\pi k$), so the equation is
23
+ * solved for $M \bmod 2\pi$ and the whole turns are added back. Any finite $M$ works,
24
+ * including negative values and many revolutions.
23
25
  *
24
- * 2. **Initial Approximation:**
25
- * - **For small eccentricities ($e < 0.8$):** $E_0 = M$.
26
- * - **For moderate eccentricities ($0.8 \leq e < 0.97$):** $E_0 = M + e \sin(M) (1 + e \cos(M))$.
27
- * - **For nearly parabolic orbits ($e \geq 0.97$):** $E_0 = \frac{6M}{e}$.
26
+ * 2. **Initial Approximation** (Danby 1987, good for all $0 \leq e < 1$):
27
+ * $$
28
+ * E_0 = M + 0.85\, e \,\operatorname{sign}(\sin M)
29
+ * $$
28
30
  *
29
31
  * 3. **Newton-Raphson Iteration with Householder Acceleration:**
30
- * - The **Newton-Raphson method** iterates using:
32
+ * - With $f(E) = E - e \sin(E) - M$, $f'(E) = 1 - e \cos(E)$, $f''(E) = e \sin(E)$ and
33
+ * $f'''(E) = e \cos(E)$, each step refines the Newton correction to third order:
31
34
  * $$
32
- * E_{n+1} = E_n - \frac{f(E_n)}{f'(E_n)}
33
- * $$
34
- * where:
35
- * - $f(E) = E - e \sin(E) - M$
36
- * - $f'(E) = 1 - e \cos(E)$
37
- *
38
- * - **Householder acceleration** refines the correction:
39
- * $$
40
- * \Delta E = \frac{f(E)}{f'(E)} \left( 1 - \frac{1}{2} \frac{f''(E)}{f'(E)} \Delta E \right)^{-1}
35
+ * \delta_1 = -\frac{f}{f'}, \quad
36
+ * \delta_2 = -\frac{f}{f' + \tfrac{1}{2} \delta_1 f''}, \quad
37
+ * \Delta E = -\frac{f}{f' + \tfrac{1}{2} \delta_2 f'' + \tfrac{1}{6} \delta_2^2 f'''}
41
38
  * $$
42
39
  *
43
40
  * 4. **Convergence Check:**
@@ -53,7 +50,7 @@
53
50
  * ---
54
51
  *
55
52
  * **Performance Considerations:**
56
- * - **Typically converges in 4-5 iterations for most eccentricities.**
53
+ * - **Typically converges in 3-4 iterations, including $e \to 1$.**
57
54
  * - **Time complexity:** $O(1)$ for Newton-Raphson.
58
55
  *
59
56
  * ---
@@ -80,36 +77,31 @@
80
77
  * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
81
78
  * @see [Newton-Raphson Method (Wikipedia)](https://en.wikipedia.org/wiki/Newton%27s_method)
82
79
  * @see [Eccentric Anomaly (Wikipedia)](https://en.wikipedia.org/wiki/Mean_anomaly#Eccentric_anomaly)
80
+ * @see Danby, J. M. A. (1987). The solution of Kepler's equation, III. *Celestial Mechanics*, 40, 303–312.
83
81
  * @group Kepler Solvers
84
82
  */
85
83
  export const solveKeplerNewtonRaphson = (M, e, maxIter, tolerance) => {
86
84
  if (e < 0 || e >= 1) {
87
85
  throw new RangeError(`Invalid eccentricity: ${e}. Must be in range [0,1).`);
88
86
  }
89
- let E;
90
- // Smart initial guess
91
- if (e < 0.8) {
92
- E = M;
93
- }
94
- else if (e < 0.97) {
95
- E = M + e * Math.sin(M) * (1 + e * Math.cos(M));
96
- }
97
- else {
98
- E = (6 * M) / e; // Nearly parabolic case
99
- }
87
+ // Kepler's equation is 2π-periodic: solve within one turn, add the turns back
88
+ const Mr = M % TWO_PI;
89
+ const turns = M - Mr;
90
+ // Danby's starting value, good for all 0 ≤ e < 1
91
+ let E = Mr + 0.85 * e * Math.sign(Math.sin(Mr));
100
92
  let iter = 0;
101
93
  while (iter < maxIter) {
102
- const F = E - e * Math.sin(E) - M;
94
+ const F = E - e * Math.sin(E) - Mr;
103
95
  const dF = 1 - e * Math.cos(E);
104
96
  const d2F = e * Math.sin(E);
105
97
  const d3F = e * Math.cos(E);
106
- const deltaE = -F / dF; // Newton’s step
107
- // Apply Householder's method for faster convergence
108
- let correction = deltaE / (1 - (0.5 * deltaE * d2F) / dF);
109
- correction /= 1 - ((1 / 6) * correction * correction * d3F) / dF;
98
+ // Newton's step, refined to third order (Householder / Danby)
99
+ const delta1 = -F / dF;
100
+ const delta2 = -F / (dF + 0.5 * delta1 * d2F);
101
+ const correction = -F / (dF + 0.5 * delta2 * d2F + (1 / 6) * delta2 * delta2 * d3F);
110
102
  E += correction;
111
103
  if (Math.abs(correction) < tolerance) {
112
- return E; // Converged
104
+ return (E + turns); // Converged
113
105
  }
114
106
  iter++;
115
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler-newton-raphson.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-newton-raphson.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,CAAU,EACV,CAAS,EACT,OAAe,EACf,SAAiB,EACC,EAAE;IACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,yBAAyB,CAAC,2BAA2B,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAS,CAAC;IAEd,sBAAsB;IACtB,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACZ,CAAC,GAAG,CAAC,CAAC;IACR,CAAC;SAAM,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,wBAAwB;IAC3C,CAAC;IAED,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,IAAI,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,gBAAgB;QAExC,oDAAoD;QACpD,IAAI,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAE1D,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,GAAG,UAAU,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAEjE,CAAC,IAAI,UAAU,CAAC;QAEhB,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC;YACrC,OAAO,CAAY,CAAC,CAAC,YAAY;QACnC,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC;IAED,OAAO,GAAG,CAAC,CAAC,mBAAmB;AACjC,CAAC,CAAC"}
1
+ {"version":3,"file":"solve-kepler-newton-raphson.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler-newton-raphson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAGvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,CAAU,EACV,CAAS,EACT,OAAe,EACf,SAAiB,EACC,EAAE;IACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,yBAAyB,CAAC,2BAA2B,CAAC,CAAC;IAC9E,CAAC;IAED,8EAA8E;IAC9E,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IACtB,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC;IAErB,iDAAiD;IACjD,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,IAAI,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5B,8DAA8D;QAC9D,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC;QAC9C,MAAM,UAAU,GACd,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC;QAEnE,CAAC,IAAI,UAAU,CAAC;QAEhB,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC;YACrC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAY,CAAC,CAAC,YAAY;QAC7C,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC;IAED,OAAO,GAAG,CAAC,CAAC,mBAAmB;AACjC,CAAC,CAAC"}
@@ -3,8 +3,8 @@ import type { Radians } from '@interstellar-tools/types';
3
3
  * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using an adaptive approach:
4
4
  *
5
5
  * - **Newton-Raphson method** for fast convergence.
6
- * - **Bisection fallback** if Newton’s method fails.
7
6
  * - **High-eccentricity solver** for extreme orbits ($e > 0.9$).
7
+ * - **Bisection fallback** if the selected solver doesn't return a root.
8
8
  *
9
9
  * ---
10
10
  *
@@ -28,10 +28,15 @@ import type { Radians } from '@interstellar-tools/types';
28
28
  * 2. **Select the Best Solver:**
29
29
  * - **For high eccentricities ($e > 0.9$)** → Uses `solveKeplerHighEccentricity()`.
30
30
  * - **For moderate eccentricities ($e \leq 0.9$)** → Uses `solveKeplerNewtonRaphson()`.
31
- * - **If Newton-Raphson fails**, falls back to `solveKeplerBisection()`.
31
+ * - **The result is verified** against Kepler's equation ($|E - e\sin E - M| \leq$ `tolerance`,
32
+ * modulo $2\pi$). If the solver didn't converge (`NaN`), stopped at `maxIter`, or settled
33
+ * away from the root, it falls back to `solveKeplerBisection()`, which always brackets the root.
32
34
  *
33
- * 3. **Final Wrapping:**
34
- * - Ensures the solution is correctly wrapped using `wrapAngle()`.
35
+ * 3. **Normalization:**
36
+ * - Kepler's equation is $2\pi$-periodic ($M + 2\pi k \mapsto E + 2\pi k$), so $M$ is first
37
+ * reduced to $[0, 2\pi)$ with `norm2pi()`. This keeps the solvers in their stable range
38
+ * for any finite $M$, including negative values and many revolutions.
39
+ * - The solution is normalized to $[0, 2\pi)$ with `norm2pi()`.
35
40
  *
36
41
  * ---
37
42
  *
@@ -46,7 +51,7 @@ import type { Radians } from '@interstellar-tools/types';
46
51
  * @param {number} e - Orbital eccentricity ($0 \leq e < 1$).
47
52
  * @param {number} [maxIter=50] - Maximum number of **iterations** before fallback.
48
53
  * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
49
- * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[0, 2\pi]$).
54
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (normalized to $[0, 2\pi)$).
50
55
  *
51
56
  * @throws {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError | RangeError} If the **eccentricity ($e$) is invalid** ($e < 0$ or $e \geq 1$).
52
57
  *
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAQzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,eAAO,MAAM,WAAW,GACtB,GAAG,OAAO,EACV,GAAG,MAAM,EACT,gBAAY,EACZ,kBAAgB,KACf,OAkBF,CAAC"}
1
+ {"version":3,"file":"solve-kepler.d.ts","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAQzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,eAAO,MAAM,WAAW,GACtB,GAAG,OAAO,EACV,GAAG,MAAM,EACT,gBAAY,EACZ,kBAAgB,KACf,OAuBF,CAAC"}
@@ -1,4 +1,5 @@
1
- import { wrapAngle } from '../angle/wrap-angle.js';
1
+ import { TWO_PI } from '@interstellar-tools/constants';
2
+ import { norm2pi } from '../helpers/misc.js';
2
3
  import { solveKeplerBisection } from './solve-kepler-bisection.js';
3
4
  import { solveKeplerHighEccentricity } from './solve-kepler-high-eccentricity.js';
4
5
  import { solveKeplerNewtonRaphson } from './solve-kepler-newton-raphson.js';
@@ -6,8 +7,8 @@ import { solveKeplerNewtonRaphson } from './solve-kepler-newton-raphson.js';
6
7
  * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using an adaptive approach:
7
8
  *
8
9
  * - **Newton-Raphson method** for fast convergence.
9
- * - **Bisection fallback** if Newton’s method fails.
10
10
  * - **High-eccentricity solver** for extreme orbits ($e > 0.9$).
11
+ * - **Bisection fallback** if the selected solver doesn't return a root.
11
12
  *
12
13
  * ---
13
14
  *
@@ -31,10 +32,15 @@ import { solveKeplerNewtonRaphson } from './solve-kepler-newton-raphson.js';
31
32
  * 2. **Select the Best Solver:**
32
33
  * - **For high eccentricities ($e > 0.9$)** → Uses `solveKeplerHighEccentricity()`.
33
34
  * - **For moderate eccentricities ($e \leq 0.9$)** → Uses `solveKeplerNewtonRaphson()`.
34
- * - **If Newton-Raphson fails**, falls back to `solveKeplerBisection()`.
35
+ * - **The result is verified** against Kepler's equation ($|E - e\sin E - M| \leq$ `tolerance`,
36
+ * modulo $2\pi$). If the solver didn't converge (`NaN`), stopped at `maxIter`, or settled
37
+ * away from the root, it falls back to `solveKeplerBisection()`, which always brackets the root.
35
38
  *
36
- * 3. **Final Wrapping:**
37
- * - Ensures the solution is correctly wrapped using `wrapAngle()`.
39
+ * 3. **Normalization:**
40
+ * - Kepler's equation is $2\pi$-periodic ($M + 2\pi k \mapsto E + 2\pi k$), so $M$ is first
41
+ * reduced to $[0, 2\pi)$ with `norm2pi()`. This keeps the solvers in their stable range
42
+ * for any finite $M$, including negative values and many revolutions.
43
+ * - The solution is normalized to $[0, 2\pi)$ with `norm2pi()`.
38
44
  *
39
45
  * ---
40
46
  *
@@ -49,7 +55,7 @@ import { solveKeplerNewtonRaphson } from './solve-kepler-newton-raphson.js';
49
55
  * @param {number} e - Orbital eccentricity ($0 \leq e < 1$).
50
56
  * @param {number} [maxIter=50] - Maximum number of **iterations** before fallback.
51
57
  * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
52
- * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[0, 2\pi]$).
58
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (normalized to $[0, 2\pi)$).
53
59
  *
54
60
  * @throws {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError | RangeError} If the **eccentricity ($e$) is invalid** ($e < 0$ or $e \geq 1$).
55
61
  *
@@ -86,15 +92,18 @@ export const solveKepler = (M, e, maxIter = 50, tolerance = 1e-9) => {
86
92
  if (e < 0 || e >= 1) {
87
93
  throw new RangeError(`Invalid eccentricity: ${e}. Must be in range [0,1).`);
88
94
  }
95
+ // Kepler's equation is 2π-periodic, so solve for M in [0, 2π)
96
+ const Mn = norm2pi(M);
89
97
  // **Use different solvers for high-eccentricity cases**
90
- if (e > 0.9) {
91
- return solveKeplerHighEccentricity(M, e, maxIter, tolerance);
98
+ let E = e > 0.9
99
+ ? solveKeplerHighEccentricity(Mn, e, maxIter, tolerance)
100
+ : solveKeplerNewtonRaphson(Mn, e, maxIter, tolerance);
101
+ // The iterative solvers can stop at maxIter or on a vanishing step away from
102
+ // the root, so verify the result and fall back to bisection if needed
103
+ const residual = norm2pi(E - e * Math.sin(E) - Mn);
104
+ if (!(Math.min(residual, TWO_PI - residual) <= tolerance)) {
105
+ E = solveKeplerBisection(Mn, e, maxIter, tolerance);
92
106
  }
93
- // Use Newton-Raphson first; if it fails, fallback to bisection
94
- let E = solveKeplerNewtonRaphson(M, e, maxIter, tolerance);
95
- if (isNaN(E)) {
96
- E = solveKeplerBisection(M, e, maxIter, tolerance);
97
- }
98
- return wrapAngle(E);
107
+ return norm2pi(E);
99
108
  };
100
109
  //# sourceMappingURL=solve-kepler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solve-kepler.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,CAAU,EACV,CAAS,EACT,OAAO,GAAG,EAAE,EACZ,SAAS,GAAG,IAAI,EACP,EAAE;IACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,yBAAyB,CAAC,2BAA2B,CAAC,CAAC;IAC9E,CAAC;IAED,wDAAwD;IACxD,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACZ,OAAO,2BAA2B,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC,GAAG,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAE3D,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACb,CAAC,GAAG,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,SAAS,CAAC,CAAC,CAAY,CAAC;AACjC,CAAC,CAAC"}
1
+ {"version":3,"file":"solve-kepler.js","sourceRoot":"","sources":["../../../src/categories/kepler/solve-kepler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAGvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,CAAU,EACV,CAAS,EACT,OAAO,GAAG,EAAE,EACZ,SAAS,GAAG,IAAI,EACP,EAAE;IACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,yBAAyB,CAAC,2BAA2B,CAAC,CAAC;IAC9E,CAAC;IAED,8DAA8D;IAC9D,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAY,CAAC;IAEjC,wDAAwD;IACxD,IAAI,CAAC,GACH,CAAC,GAAG,GAAG;QACL,CAAC,CAAC,2BAA2B,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC;QACxD,CAAC,CAAC,wBAAwB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAE1D,6EAA6E;IAC7E,sEAAsE;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAEnD,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC;QAC1D,CAAC,GAAG,oBAAoB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAY,CAAC;AAC/B,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interstellar-tools/equations",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "description": "Curated, well-tested orbital mechanics and dynamics formulas (e.g., Newtonian gravity, vis-viva, Kepler's 3rd law, escape/circular speeds, specific energy, specific angular momentum, peri/apoapsis radii).",
5
5
  "keywords": [
6
6
  "interstellar",
@@ -109,9 +109,9 @@
109
109
  "test:ci": "glob-bin -c \"node --import tsx --test --no-warnings --experimental-test-coverage --test-coverage-exclude='**/__tests__/helpers/**' --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"**/__tests__/**/*.spec.ts\""
110
110
  },
111
111
  "dependencies": {
112
- "@interstellar-tools/constants": "^0.55.0",
113
- "@interstellar-tools/temporal": "^0.55.0",
114
- "@interstellar-tools/types": "^0.55.0"
112
+ "@interstellar-tools/constants": "^0.56.0",
113
+ "@interstellar-tools/temporal": "^0.56.0",
114
+ "@interstellar-tools/types": "^0.56.0"
115
115
  },
116
116
  "devDependencies": {
117
117
  "@types/node": "^25.9.0",