@woosh/meep-engine 2.134.5 → 2.135.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.
Files changed (155) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/tools/v2/TransformControlsGizmo.js +1 -1
  4. package/editor/view/node-graph/NodeGraphEditorView.js +2 -2
  5. package/package.json +1 -1
  6. package/src/core/assert.d.ts +0 -2
  7. package/src/core/assert.d.ts.map +1 -1
  8. package/src/core/assert.js +0 -6
  9. package/src/core/color/Color.d.ts +0 -5
  10. package/src/core/color/Color.d.ts.map +1 -1
  11. package/src/core/color/Color.js +1 -7
  12. package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +386 -386
  13. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +1 -1
  14. package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
  15. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +160 -160
  16. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +96 -96
  17. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
  18. package/src/core/geom/packing/max-rect/findBestContainer.js +4 -4
  19. package/src/core/geom/packing/max-rect/packOneBox.js +2 -2
  20. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +1 -1
  21. package/src/core/graph/layout/box/BoxLayouter.js +7 -7
  22. package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
  23. package/src/core/math/computeWholeDivisorLow.js +33 -33
  24. package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
  25. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
  26. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
  27. package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
  28. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
  29. package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
  30. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
  31. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
  32. package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
  33. package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.d.ts +0 -3
  34. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
  35. package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.js +0 -3
  36. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
  37. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
  38. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
  39. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
  40. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
  41. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
  42. package/src/core/math/solveCubic.d.ts +15 -0
  43. package/src/core/math/solveCubic.d.ts.map +1 -0
  44. package/src/core/math/solveCubic.js +82 -0
  45. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
  46. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
  47. package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
  48. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
  49. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
  50. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
  51. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
  52. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
  53. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
  54. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
  55. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
  56. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
  57. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
  58. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
  59. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
  60. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
  61. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
  62. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
  63. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
  64. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
  65. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
  66. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
  67. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
  68. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  69. package/src/core/process/delay.js +16 -16
  70. package/src/engine/animation/async/TimeSeries.js +300 -300
  71. package/src/engine/animation/curve/AnimationCurve.d.ts +0 -4
  72. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  73. package/src/engine/animation/curve/AnimationCurve.js +1 -6
  74. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
  75. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
  76. package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
  77. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
  78. package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
  79. package/src/engine/ecs/transform/Transform.d.ts +0 -10
  80. package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
  81. package/src/engine/ecs/transform/Transform.js +0 -12
  82. package/src/engine/graphics/composit/CompositLayer.js +254 -254
  83. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
  84. package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
  85. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
  86. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
  87. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  88. package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
  89. package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
  90. package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
  91. package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
  92. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
  93. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
  94. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  95. package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
  96. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
  97. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
  98. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
  99. package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
  100. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  101. package/src/generation/grid/GridData.js +220 -220
  102. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
  103. package/src/view/elements/image/SvgImageView.js +1 -1
  104. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  105. package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
  106. package/src/view/util/DomSizeObserver.js +1 -1
  107. package/src/core/binary/clz32.d.ts +0 -6
  108. package/src/core/binary/clz32.d.ts.map +0 -1
  109. package/src/core/binary/clz32.js +0 -5
  110. package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
  111. package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
  112. package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
  113. package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
  114. package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
  115. package/src/core/collection/array/computeHashIntegerArray.js +0 -7
  116. package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
  117. package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
  118. package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
  119. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
  120. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
  121. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
  122. package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
  123. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
  124. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
  125. package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
  126. package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
  127. package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
  128. package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +0 -1
  129. package/src/core/math/spline/cubicCurve.d.ts +0 -6
  130. package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
  131. package/src/core/math/spline/cubicCurve.js +0 -6
  132. package/src/core/math/spline/spline_bezier2.d.ts +0 -6
  133. package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
  134. package/src/core/math/spline/spline_bezier2.js +0 -6
  135. package/src/core/math/spline/spline_bezier3.d.ts +0 -6
  136. package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
  137. package/src/core/math/spline/spline_bezier3.js +0 -6
  138. package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
  139. package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
  140. package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
  141. package/src/core/math/spline/spline_hermite3.d.ts +0 -6
  142. package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
  143. package/src/core/math/spline/spline_hermite3.js +0 -6
  144. package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
  145. package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
  146. package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
  147. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
  148. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
  149. package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
  150. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
  151. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
  152. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
  153. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
  154. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
  155. /package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.d.ts +0 -0
@@ -1,33 +1,33 @@
1
- import { assert } from "../assert.js";
2
-
3
- /**
4
- * Compute the largest positive integer divisor of a given "product" value
5
- * @param {number} product
6
- * @param {number} limit
7
- * @returns {number}
8
- */
9
- export function computeWholeDivisorLow(product, limit) {
10
-
11
- assert.isNumber(product, 'product');
12
- assert.isInteger(product, 'product');
13
-
14
- assert.isNumber(limit, 'limit');
15
- assert.isInteger(limit, 'limit');
16
-
17
- assert.isFiniteNumber(limit,'limit');
18
- assert.isFiniteNumber(product,'product');
19
-
20
- let i = limit;
21
-
22
- while (i > 1) {
23
-
24
- if (product % i === 0) {
25
- break;
26
- }
27
-
28
- i--;
29
-
30
- }
31
-
32
- return i;
33
- }
1
+ import { assert } from "../assert.js";
2
+
3
+ /**
4
+ * Compute the largest positive integer divisor of a given "product" value
5
+ * @param {number} product
6
+ * @param {number} limit
7
+ * @returns {number}
8
+ */
9
+ export function computeWholeDivisorLow(product, limit) {
10
+
11
+ assert.isNumber(product, 'product');
12
+ assert.isInteger(product, 'product');
13
+
14
+ assert.isNumber(limit, 'limit');
15
+ assert.isInteger(limit, 'limit');
16
+
17
+ assert.isFinite(limit,'limit');
18
+ assert.isFinite(product,'product');
19
+
20
+ let i = limit;
21
+
22
+ while (i > 1) {
23
+
24
+ if (product % i === 0) {
25
+ break;
26
+ }
27
+
28
+ i--;
29
+
30
+ }
31
+
32
+ return i;
33
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eigen_values_find_spectral_gap.d.ts","sourceRoot":"","sources":["../../../../../../src/core/math/linalg/eigen/eigen_values_find_spectral_gap.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,uDAHW,MAAM,EAAE,GACN,MAAM,CAoBlB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * list of eigen values square matrix (allow non-symmetric)
3
+ * NOTE: Modifies input matrix
4
+ * @template T extends ArrayLike<number>
5
+ * @param {T} out
6
+ * @param {SquareMatrix} mat
7
+ * @return {T}
8
+ */
9
+ export function matrix_eigenvalues_in_place<T>(out: T, mat: SquareMatrix): T;
10
+ //# sourceMappingURL=matrix_eigenvalues_in_place.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix_eigenvalues_in_place.d.ts","sourceRoot":"","sources":["../../../../../../src/core/math/linalg/eigen/matrix_eigenvalues_in_place.js"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,6EASC"}
@@ -3,19 +3,20 @@ import { matrix_qr_in_place } from "./matrix_qr_in_place.js";
3
3
 
4
4
 
5
5
  /**
6
- * list of eigen values square matrix (allow non symmetric)
6
+ * list of eigen values square matrix (allow non-symmetric)
7
7
  * NOTE: Modifies input matrix
8
+ * @template T extends ArrayLike<number>
9
+ * @param {T} out
8
10
  * @param {SquareMatrix} mat
9
- * @return {number[]}
11
+ * @return {T}
10
12
  */
11
- export function matrix_eigenvalues_in_place(mat) {
13
+ export function matrix_eigenvalues_in_place(out, mat) {
12
14
  const n = mat.size;
15
+
13
16
  matrix_householder_in_place(mat.data, n);
14
17
  matrix_qr_in_place(mat.data, n);
15
18
 
16
- const result = new Float32Array(n);
17
-
18
- mat.readDiagonal(result);
19
+ mat.readDiagonal(out);
19
20
 
20
- return result;
21
+ return out;
21
22
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix_householder_in_place.d.ts","sourceRoot":"","sources":["../../../../../../src/core/math/linalg/eigen/matrix_householder_in_place.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,+CAHW,MAAM,EAAE,KACR,MAAM,QA0FhB"}
@@ -32,14 +32,20 @@ export function matrix_householder_in_place(a, n) {
32
32
  sum = sum + u[i] * u[i];
33
33
  }
34
34
 
35
- const u_k_1 = u[k + 1];
36
-
37
- const u_k_1_abs = Math.abs(u_k_1);
38
- if (u_k_1_abs < EPSILON) {
35
+ if (sum < EPSILON * EPSILON) {
36
+ // sub-column already zero — nothing to reduce at this k
39
37
  continue;
40
38
  }
41
39
 
42
- const sigma = Math.sqrt(sum) * u_k_1 / u_k_1_abs;
40
+ const u_k_1 = u[k + 1];
41
+ const u_k_1_abs = Math.abs(u_k_1);
42
+
43
+ // sigma = sign(u[k+1]) · ‖u‖. When u[k+1] = 0 the sign is arbitrary
44
+ // (entries below are still nonzero by the `sum` check above), so pick
45
+ // +‖u‖.
46
+ const sigma = u_k_1_abs < EPSILON
47
+ ? Math.sqrt(sum)
48
+ : Math.sqrt(sum) * u_k_1 / u_k_1_abs;
43
49
 
44
50
  u[k + 1] += sigma;
45
51
 
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Perform QR factorization in-place.
3
+ * Subfunction that analyzes eigenvalues by QR decomposition.
4
+ *
5
+ * Single-shift Wilkinson iteration: deflates the trailing subdiagonal one row
6
+ * at a time as it converges. A complex eigenvalue pair leaves a 2×2 trailing
7
+ * block whose inner subdiagonal does not vanish, and this routine will spin
8
+ * on it indefinitely — only safe today for matrices with all-real eigenvalues.
9
+ *
10
+ * @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
11
+ * @param {number[]} a Square matrix
12
+ * @param {number} n size of the matrix in single dimension
13
+ */
14
+ export function matrix_qr_in_place(a: number[], n: number): void;
15
+ //# sourceMappingURL=matrix_qr_in_place.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix_qr_in_place.d.ts","sourceRoot":"","sources":["../../../../../../src/core/math/linalg/eigen/matrix_qr_in_place.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,sCAHW,MAAM,EAAE,KACR,MAAM,QA8GhB"}
@@ -1,8 +1,14 @@
1
1
  const EPSILON = 1e-10;
2
2
 
3
3
  /**
4
- * Perform QR factorization in-place
5
- * Subfunction that analyzes eigenvalues by QR decomposition
4
+ * Perform QR factorization in-place.
5
+ * Subfunction that analyzes eigenvalues by QR decomposition.
6
+ *
7
+ * Single-shift Wilkinson iteration: deflates the trailing subdiagonal one row
8
+ * at a time as it converges. A complex eigenvalue pair leaves a 2×2 trailing
9
+ * block whose inner subdiagonal does not vanish, and this routine will spin
10
+ * on it indefinitely — only safe today for matrices with all-real eigenvalues.
11
+ *
6
12
  * @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
7
13
  * @param {number[]} a Square matrix
8
14
  * @param {number} n size of the matrix in single dimension
@@ -7,9 +7,6 @@
7
7
  * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
8
8
  * equal magnitude — convergence stalls in that regime.
9
9
  *
10
- * NOTE: intended to live in @woosh/meep-engine under core/graph/eigen/. Kept
11
- * local for now.
12
- *
13
10
  * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
14
11
  * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
15
12
  * @param {number} [max_iterations=64]
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix_top_eigenvector_power_iteration.d.ts","sourceRoot":"","sources":["../../../../../../src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,kFALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,mBAClC,MAAM,cACN,MAAM,GACJ,MAAM,CAoFlB"}
@@ -16,9 +16,6 @@ function ensure_scratch(n) {
16
16
  * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
17
17
  * equal magnitude — convergence stalls in that regime.
18
18
  *
19
- * NOTE: intended to live in @woosh/meep-engine under core/graph/eigen/. Kept
20
- * local for now.
21
- *
22
19
  * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
23
20
  * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
24
21
  * @param {number} [max_iterations=64]
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Find all complex roots of a univariate polynomial via Aberth–Ehrlich.
3
+ *
4
+ * The polynomial is given in ascending-power coefficient form:
5
+ * p(x) = coeffs[0] + coeffs[1]·x + … + coeffs[degree]·x^degree
6
+ * The leading coefficient `coeffs[degree]` must be nonzero.
7
+ *
8
+ * Exactly `degree` complex numbers are written into `roots_re`/`roots_im` at
9
+ * index `offset`, `offset + 1`, …, `offset + degree - 1`. The order they
10
+ * appear in is not specified.
11
+ *
12
+ * @param {Float64Array|number[]} coeffs ascending-power, length ≥ degree + 1
13
+ * @param {number} degree polynomial degree, ≥ 1, ≤ 64
14
+ * @param {Float64Array|number[]} roots_re real parts, length ≥ offset + degree
15
+ * @param {Float64Array|number[]} roots_im imaginary parts, length ≥ offset + degree
16
+ * @param {number} offset
17
+ */
18
+ export function polynomial_complex_roots_aberth_ehrlich(coeffs: Float64Array | number[], degree: number, roots_re: Float64Array | number[], roots_im: Float64Array | number[], offset: number): void;
19
+ //# sourceMappingURL=polynomial_complex_roots_aberth_ehrlich.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polynomial_complex_roots_aberth_ehrlich.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js"],"names":[],"mappings":"AA6DA;;;;;;;;;;;;;;;;GAgBG;AACH,gEANW,YAAY,GAAC,MAAM,EAAE,UACrB,MAAM,YACN,YAAY,GAAC,MAAM,EAAE,YACrB,YAAY,GAAC,MAAM,EAAE,UACrB,MAAM,QAoFhB"}
@@ -0,0 +1,161 @@
1
+ import { assert } from "../../assert.js";
2
+
3
+ /*
4
+ Find all roots of a univariate polynomial in the complex plane via
5
+ Aberth–Ehrlich simultaneous iteration. Real and complex roots are isolated
6
+ together; the caller separates real ones by inspecting the imaginary parts.
7
+
8
+ Reference: Aberth (1973), "Iteration methods for finding all zeros of a
9
+ polynomial simultaneously", Math. Comp. 27.
10
+
11
+ The iteration is
12
+
13
+ z_k ← z_k − w_k / (1 − w_k · Σ_{j≠k} 1/(z_k − z_j))
14
+
15
+ with w_k = p(z_k) / p'(z_k). Initial points are placed on a circle of radius
16
+ = Cauchy bound, with a fixed phase offset so an initial guess never lands
17
+ exactly on a real root (which would make the pairwise sum singular at step
18
+ zero). Convergence is quadratic once close.
19
+ */
20
+
21
+ const MAX_SUPPORTED_DEGREE = 64;
22
+
23
+ const ABERTH_MAX_ITERATIONS = 80;
24
+ const ABERTH_CONVERGENCE_TOLERANCE = 1e-14;
25
+
26
+ const _DERIV = new Float64Array(MAX_SUPPORTED_DEGREE);
27
+ const _P_EVAL = new Float64Array(2);
28
+ const _DP_EVAL = new Float64Array(2);
29
+
30
+ /**
31
+ * Horner evaluation of polynomial p(z) at a complex z = (zr, zi).
32
+ * Writes [p(z).re, p(z).im] into `out`.
33
+ */
34
+ function poly_eval_complex(coeffs, degree, zr, zi, out) {
35
+ let pr = coeffs[degree];
36
+ let pi = 0;
37
+
38
+ for (let i = degree - 1; i >= 0; i--) {
39
+ const new_pr = pr * zr - pi * zi + coeffs[i];
40
+ const new_pi = pr * zi + pi * zr;
41
+ pr = new_pr;
42
+ pi = new_pi;
43
+ }
44
+
45
+ out[0] = pr;
46
+ out[1] = pi;
47
+ }
48
+
49
+ /**
50
+ * Cauchy bound: every root z of `coeffs` satisfies |z| ≤ this value.
51
+ */
52
+ function cauchy_root_magnitude_bound(coeffs, degree) {
53
+ const lead = Math.abs(coeffs[degree]);
54
+ let m = 0;
55
+ for (let i = 0; i < degree; i++) {
56
+ const a = Math.abs(coeffs[i]);
57
+ if (a > m) m = a;
58
+ }
59
+ return 1 + m / lead;
60
+ }
61
+
62
+ /**
63
+ * Find all complex roots of a univariate polynomial via Aberth–Ehrlich.
64
+ *
65
+ * The polynomial is given in ascending-power coefficient form:
66
+ * p(x) = coeffs[0] + coeffs[1]·x + … + coeffs[degree]·x^degree
67
+ * The leading coefficient `coeffs[degree]` must be nonzero.
68
+ *
69
+ * Exactly `degree` complex numbers are written into `roots_re`/`roots_im` at
70
+ * index `offset`, `offset + 1`, …, `offset + degree - 1`. The order they
71
+ * appear in is not specified.
72
+ *
73
+ * @param {Float64Array|number[]} coeffs ascending-power, length ≥ degree + 1
74
+ * @param {number} degree polynomial degree, ≥ 1, ≤ 64
75
+ * @param {Float64Array|number[]} roots_re real parts, length ≥ offset + degree
76
+ * @param {Float64Array|number[]} roots_im imaginary parts, length ≥ offset + degree
77
+ * @param {number} offset
78
+ */
79
+ export function polynomial_complex_roots_aberth_ehrlich(
80
+ coeffs, degree,
81
+ roots_re, roots_im, offset
82
+ ) {
83
+ assert.greaterThanOrEqual(degree, 1, 'degree');
84
+ assert.greaterThanOrEqual(MAX_SUPPORTED_DEGREE, degree, 'degree exceeds MAX_SUPPORTED_DEGREE');
85
+ assert.isNonNegativeInteger(offset, 'offset');
86
+
87
+ // derivative: _DERIV[i] = (i + 1) * coeffs[i + 1], i = 0 .. degree - 1
88
+ for (let i = 0; i < degree; i++) {
89
+ _DERIV[i] = (i + 1) * coeffs[i + 1];
90
+ }
91
+
92
+ const radius = cauchy_root_magnitude_bound(coeffs, degree);
93
+
94
+ // Initial points around a circle, with a small phase offset to avoid
95
+ // landing exactly on a real root at iteration zero.
96
+ const phase_offset = 0.5;
97
+ const two_pi_over_n = (2 * Math.PI) / degree;
98
+ for (let k = 0; k < degree; k++) {
99
+ const angle = k * two_pi_over_n + phase_offset;
100
+ roots_re[offset + k] = radius * Math.cos(angle);
101
+ roots_im[offset + k] = radius * Math.sin(angle);
102
+ }
103
+
104
+ for (let iter = 0; iter < ABERTH_MAX_ITERATIONS; iter++) {
105
+ let max_correction_sq = 0;
106
+
107
+ for (let k = 0; k < degree; k++) {
108
+ const zr = roots_re[offset + k];
109
+ const zi = roots_im[offset + k];
110
+
111
+ poly_eval_complex(coeffs, degree, zr, zi, _P_EVAL);
112
+ const pr = _P_EVAL[0];
113
+ const pi = _P_EVAL[1];
114
+
115
+ poly_eval_complex(_DERIV, degree - 1, zr, zi, _DP_EVAL);
116
+ const dpr = _DP_EVAL[0];
117
+ const dpi = _DP_EVAL[1];
118
+
119
+ // w = p / p'
120
+ const dp_norm_sq = dpr * dpr + dpi * dpi;
121
+ if (dp_norm_sq === 0) continue;
122
+ const inv_dp_sq = 1 / dp_norm_sq;
123
+ const wr = (pr * dpr + pi * dpi) * inv_dp_sq;
124
+ const wi = (pi * dpr - pr * dpi) * inv_dp_sq;
125
+
126
+ // S = Σ_{j≠k} 1/(z_k − z_j) in complex
127
+ let sr = 0, si = 0;
128
+ for (let j = 0; j < degree; j++) {
129
+ if (j === k) continue;
130
+ const dr = zr - roots_re[offset + j];
131
+ const di = zi - roots_im[offset + j];
132
+ const denom_sq = dr * dr + di * di;
133
+ if (denom_sq === 0) continue;
134
+ const inv_d_sq = 1 / denom_sq;
135
+ sr += dr * inv_d_sq;
136
+ si += -di * inv_d_sq;
137
+ }
138
+
139
+ // correction = w / (1 − w·S)
140
+ const ws_r = wr * sr - wi * si;
141
+ const ws_i = wr * si + wi * sr;
142
+ const denom_r = 1 - ws_r;
143
+ const denom_i = -ws_i;
144
+ const denom_sq2 = denom_r * denom_r + denom_i * denom_i;
145
+ if (denom_sq2 === 0) continue;
146
+ const inv_denom_sq2 = 1 / denom_sq2;
147
+ const corr_r = (wr * denom_r + wi * denom_i) * inv_denom_sq2;
148
+ const corr_i = (wi * denom_r - wr * denom_i) * inv_denom_sq2;
149
+
150
+ roots_re[offset + k] = zr - corr_r;
151
+ roots_im[offset + k] = zi - corr_i;
152
+
153
+ const corr_sq = corr_r * corr_r + corr_i * corr_i;
154
+ if (corr_sq > max_correction_sq) max_correction_sq = corr_sq;
155
+ }
156
+
157
+ if (max_correction_sq < ABERTH_CONVERGENCE_TOLERANCE * ABERTH_CONVERGENCE_TOLERANCE) {
158
+ break;
159
+ }
160
+ }
161
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Find all real roots of a univariate polynomial that lie inside the closed
3
+ * interval [lo, hi]. Roots are written to `out[out_offset ..]` in ascending
4
+ * order; the count of roots written is returned.
5
+ *
6
+ * @param {Float64Array|number[]} coeffs ascending power order: coeffs[i] is the coefficient of x^i
7
+ * @param {number} degree polynomial degree (coeffs must have at least `degree + 1` entries)
8
+ * @param {number} lo
9
+ * @param {number} hi
10
+ * @param {Float64Array|number[]} out
11
+ * @param {number} out_offset
12
+ * @returns {number} number of roots written
13
+ */
14
+ export function polynomial_real_roots_in_interval(coeffs: Float64Array | number[], degree: number, lo: number, hi: number, out: Float64Array | number[], out_offset: number): number;
15
+ //# sourceMappingURL=polynomial_real_roots_in_interval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polynomial_real_roots_in_interval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_real_roots_in_interval.js"],"names":[],"mappings":"AAsGA;;;;;;;;;;;;GAYG;AACH,0DARW,YAAY,GAAC,MAAM,EAAE,UACrB,MAAM,MACN,MAAM,MACN,MAAM,OACN,YAAY,GAAC,MAAM,EAAE,cACrB,MAAM,GACJ,MAAM,CAsFlB"}
@@ -0,0 +1,200 @@
1
+ import { assert } from "../../assert.js";
2
+ import { solveQuadratic } from "../solveQuadratic.js";
3
+ import { polynomial_complex_roots_aberth_ehrlich } from "./polynomial_complex_roots_aberth_ehrlich.js";
4
+
5
+ /*
6
+ Find all real roots of a univariate polynomial that lie inside a closed interval [lo, hi].
7
+ Coefficient layout: coeffs[i] is the coefficient of x^i, so
8
+
9
+ p(x) = coeffs[0] + coeffs[1]*x + coeffs[2]*x^2 + ... + coeffs[degree]*x^degree
10
+
11
+ Approach:
12
+ 1. Trim leading zeros (treat the polynomial at its effective degree).
13
+ 2. Closed-form for degrees 1 and 2.
14
+ 3. For degree ≥ 3, isolate all complex roots via
15
+ polynomial_complex_roots_aberth_ehrlich, then keep the ones whose
16
+ imaginary part is below a scale-relative threshold and whose real part
17
+ lies in [lo, hi]. Each survivor is Newton-polished against the real
18
+ polynomial as a sanity / precision pass.
19
+ */
20
+
21
+ const MAX_SUPPORTED_DEGREE = 64;
22
+
23
+ const SCRATCH_COEFF = new Float64Array(MAX_SUPPORTED_DEGREE + 1);
24
+ const SCRATCH_ROOTS_RE = new Float64Array(MAX_SUPPORTED_DEGREE);
25
+ const SCRATCH_ROOTS_IM = new Float64Array(MAX_SUPPORTED_DEGREE);
26
+ const SCRATCH_OUT_REAL = new Float64Array(MAX_SUPPORTED_DEGREE);
27
+ const SCRATCH_QUADRATIC = new Float64Array(2);
28
+ const SCRATCH_EVAL = new Float64Array(2);
29
+
30
+ const NEWTON_MAX_ITERATIONS = 32;
31
+
32
+ // Imaginary part below this fraction of root scale is treated as real.
33
+ const IMAG_PART_REAL_THRESHOLD = 1e-8;
34
+
35
+ const NEWTON_RELATIVE_RESIDUAL_TOLERANCE = 1e-10;
36
+
37
+ const DEDUPE_RELATIVE_TOLERANCE = 1e-7;
38
+
39
+ function poly_eval_with_derivative(coeffs, degree, x, out) {
40
+ let p = coeffs[degree];
41
+ let dp = 0;
42
+
43
+ for (let i = degree - 1; i >= 0; i--) {
44
+ dp = dp * x + p;
45
+ p = p * x + coeffs[i];
46
+ }
47
+
48
+ out[0] = p;
49
+ out[1] = dp;
50
+ }
51
+
52
+ function max_abs_coefficient(coeffs, degree) {
53
+ let m = 0;
54
+ for (let i = 0; i <= degree; i++) {
55
+ const a = Math.abs(coeffs[i]);
56
+ if (a > m) m = a;
57
+ }
58
+ return m;
59
+ }
60
+
61
+ function root_scale_estimate(coeffs, degree) {
62
+ const lead = Math.abs(coeffs[degree]);
63
+ let m = 0;
64
+ for (let i = 0; i < degree; i++) {
65
+ const a = Math.abs(coeffs[i]);
66
+ if (a > m) m = a;
67
+ }
68
+ return 1 + m / lead;
69
+ }
70
+
71
+ function newton_polish_real(coeffs, degree, x_init) {
72
+ let x = x_init;
73
+
74
+ for (let i = 0; i < NEWTON_MAX_ITERATIONS; i++) {
75
+ poly_eval_with_derivative(coeffs, degree, x, SCRATCH_EVAL);
76
+
77
+ const p = SCRATCH_EVAL[0];
78
+ const dp = SCRATCH_EVAL[1];
79
+
80
+ if (dp === 0) break;
81
+
82
+ const step = p / dp;
83
+ x -= step;
84
+
85
+ if (Math.abs(step) <= Math.abs(x) * 1e-15) break;
86
+ }
87
+
88
+ return x;
89
+ }
90
+
91
+ function insert_sorted_unique(roots, count, value, dedupe_tolerance) {
92
+ let i = 0;
93
+ while (i < count && roots[i] < value) i++;
94
+
95
+ if (i > 0 && Math.abs(roots[i - 1] - value) <= dedupe_tolerance) return count;
96
+ if (i < count && Math.abs(roots[i] - value) <= dedupe_tolerance) return count;
97
+
98
+ for (let j = count; j > i; j--) roots[j] = roots[j - 1];
99
+ roots[i] = value;
100
+ return count + 1;
101
+ }
102
+
103
+ /**
104
+ * Find all real roots of a univariate polynomial that lie inside the closed
105
+ * interval [lo, hi]. Roots are written to `out[out_offset ..]` in ascending
106
+ * order; the count of roots written is returned.
107
+ *
108
+ * @param {Float64Array|number[]} coeffs ascending power order: coeffs[i] is the coefficient of x^i
109
+ * @param {number} degree polynomial degree (coeffs must have at least `degree + 1` entries)
110
+ * @param {number} lo
111
+ * @param {number} hi
112
+ * @param {Float64Array|number[]} out
113
+ * @param {number} out_offset
114
+ * @returns {number} number of roots written
115
+ */
116
+ export function polynomial_real_roots_in_interval(
117
+ coeffs,
118
+ degree,
119
+ lo, hi,
120
+ out, out_offset
121
+ ) {
122
+ assert.isNonNegativeInteger(degree, 'degree');
123
+ assert.isNonNegativeInteger(out_offset, 'out_offset');
124
+ assert.greaterThanOrEqual(MAX_SUPPORTED_DEGREE, degree, 'degree exceeds MAX_SUPPORTED_DEGREE');
125
+
126
+ if (degree === 0) return 0;
127
+
128
+ const coeff_norm = max_abs_coefficient(coeffs, degree);
129
+ if (coeff_norm === 0) return 0;
130
+
131
+ let effective_degree = degree;
132
+ const leading_zero_threshold = coeff_norm * 1e-14;
133
+ while (effective_degree > 0 && Math.abs(coeffs[effective_degree]) <= leading_zero_threshold) {
134
+ effective_degree--;
135
+ }
136
+ if (effective_degree === 0) return 0;
137
+
138
+ if (effective_degree === 1) {
139
+ const root = -coeffs[0] / coeffs[1];
140
+ if (root >= lo && root <= hi) {
141
+ out[out_offset] = root;
142
+ return 1;
143
+ }
144
+ return 0;
145
+ }
146
+
147
+ if (effective_degree === 2) {
148
+ const root_count = solveQuadratic(SCRATCH_QUADRATIC, 0, coeffs[2], coeffs[1], coeffs[0]);
149
+ let written = 0;
150
+ for (let i = 0; i < root_count; i++) {
151
+ const r = SCRATCH_QUADRATIC[i];
152
+ if (r >= lo && r <= hi) {
153
+ if (written === 0 || Math.abs(out[out_offset + written - 1] - r) > 0) {
154
+ out[out_offset + written] = r;
155
+ written++;
156
+ }
157
+ }
158
+ }
159
+ return written;
160
+ }
161
+
162
+ for (let i = 0; i <= effective_degree; i++) SCRATCH_COEFF[i] = coeffs[i];
163
+
164
+ polynomial_complex_roots_aberth_ehrlich(
165
+ SCRATCH_COEFF, effective_degree,
166
+ SCRATCH_ROOTS_RE, SCRATCH_ROOTS_IM, 0
167
+ );
168
+
169
+ const root_scale = root_scale_estimate(SCRATCH_COEFF, effective_degree);
170
+ const imag_threshold = IMAG_PART_REAL_THRESHOLD * Math.max(1, root_scale);
171
+ const residual_tolerance = NEWTON_RELATIVE_RESIDUAL_TOLERANCE * coeff_norm;
172
+ const dedupe_tolerance = DEDUPE_RELATIVE_TOLERANCE * Math.max(1, Math.max(Math.abs(lo), Math.abs(hi)));
173
+
174
+ let unique_count = 0;
175
+
176
+ for (let i = 0; i < effective_degree; i++) {
177
+ const re = SCRATCH_ROOTS_RE[i];
178
+ const im = SCRATCH_ROOTS_IM[i];
179
+
180
+ if (!Number.isFinite(re) || !Number.isFinite(im)) continue;
181
+
182
+ if (Math.abs(im) > imag_threshold) continue;
183
+
184
+ const polished = newton_polish_real(SCRATCH_COEFF, effective_degree, re);
185
+ if (!Number.isFinite(polished)) continue;
186
+
187
+ poly_eval_with_derivative(SCRATCH_COEFF, effective_degree, polished, SCRATCH_EVAL);
188
+ if (Math.abs(SCRATCH_EVAL[0]) > residual_tolerance) continue;
189
+
190
+ if (polished < lo || polished > hi) continue;
191
+
192
+ unique_count = insert_sorted_unique(SCRATCH_OUT_REAL, unique_count, polished, dedupe_tolerance);
193
+ }
194
+
195
+ for (let i = 0; i < unique_count; i++) {
196
+ out[out_offset + i] = SCRATCH_OUT_REAL[i];
197
+ }
198
+
199
+ return unique_count;
200
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Return real solutions for a cubic polynomial: ax³ + bx² + cx + d
3
+ * Repeated roots are written once each — multiplicity is not duplicated in the output.
4
+ * Imaginary roots are not provided.
5
+ *
6
+ * @param {number[]|Float32Array|Float64Array} result solutions are written here
7
+ * @param {number} result_offset offset into result array where solutions are written to
8
+ * @param {number} a
9
+ * @param {number} b
10
+ * @param {number} c
11
+ * @param {number} d
12
+ * @returns {number} number of real roots found (0, 1, 2, or 3)
13
+ */
14
+ export function solveCubic(result: number[] | Float32Array | Float64Array, result_offset: number, a: number, b: number, c: number, d: number): number;
15
+ //# sourceMappingURL=solveCubic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solveCubic.d.ts","sourceRoot":"","sources":["../../../../src/core/math/solveCubic.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;GAYG;AACH,mCARW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,MAAM,CA+DlB"}