@woosh/meep-engine 2.134.4 → 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 (156) 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.d.ts +23 -0
  21. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -0
  22. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +96 -0
  23. package/src/core/graph/layout/box/BoxLayouter.js +7 -7
  24. package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
  25. package/src/core/math/computeWholeDivisorLow.js +33 -33
  26. package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
  27. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
  28. package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
  29. package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
  30. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
  31. package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
  32. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
  33. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
  34. package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
  35. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +17 -0
  36. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
  37. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +107 -0
  38. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
  39. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
  40. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
  41. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
  42. package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
  43. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
  44. package/src/core/math/solveCubic.d.ts +15 -0
  45. package/src/core/math/solveCubic.d.ts.map +1 -0
  46. package/src/core/math/solveCubic.js +82 -0
  47. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
  48. package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
  49. package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
  50. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
  51. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
  52. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
  53. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
  54. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
  55. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
  56. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
  57. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
  58. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
  59. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
  60. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
  61. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
  62. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
  63. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
  64. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
  65. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
  66. package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
  67. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
  68. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
  69. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
  70. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  71. package/src/core/process/delay.js +16 -16
  72. package/src/engine/animation/async/TimeSeries.js +300 -300
  73. package/src/engine/animation/curve/AnimationCurve.d.ts +3 -2
  74. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  75. package/src/engine/animation/curve/AnimationCurve.js +3 -2
  76. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
  77. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
  78. package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
  79. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
  80. package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
  81. package/src/engine/ecs/transform/Transform.d.ts +0 -10
  82. package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
  83. package/src/engine/ecs/transform/Transform.js +0 -12
  84. package/src/engine/graphics/composit/CompositLayer.js +254 -254
  85. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
  86. package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
  87. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
  88. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
  89. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  90. package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
  91. package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
  92. package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
  93. package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
  94. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
  95. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
  96. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  97. package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
  98. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
  99. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
  100. package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
  101. package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
  102. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  103. package/src/generation/grid/GridData.js +220 -220
  104. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
  105. package/src/view/elements/image/SvgImageView.js +1 -1
  106. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  107. package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
  108. package/src/view/util/DomSizeObserver.js +1 -1
  109. package/src/core/binary/clz32.d.ts +0 -6
  110. package/src/core/binary/clz32.d.ts.map +0 -1
  111. package/src/core/binary/clz32.js +0 -5
  112. package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
  113. package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
  114. package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
  115. package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
  116. package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
  117. package/src/core/collection/array/computeHashIntegerArray.js +0 -7
  118. package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
  119. package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
  120. package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
  121. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
  122. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
  123. package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
  124. package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
  125. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
  126. package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
  127. package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
  128. package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
  129. package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
  130. package/src/core/math/spline/cubicCurve.d.ts +0 -6
  131. package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
  132. package/src/core/math/spline/cubicCurve.js +0 -6
  133. package/src/core/math/spline/spline_bezier2.d.ts +0 -6
  134. package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
  135. package/src/core/math/spline/spline_bezier2.js +0 -6
  136. package/src/core/math/spline/spline_bezier3.d.ts +0 -6
  137. package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
  138. package/src/core/math/spline/spline_bezier3.js +0 -6
  139. package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
  140. package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
  141. package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
  142. package/src/core/math/spline/spline_hermite3.d.ts +0 -6
  143. package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
  144. package/src/core/math/spline/spline_hermite3.js +0 -6
  145. package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
  146. package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
  147. package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
  148. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
  149. package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
  150. package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
  151. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
  152. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
  153. package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
  154. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
  155. /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
  156. /package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.d.ts +0 -0
@@ -0,0 +1,96 @@
1
+ import { BinaryDataType } from "../../binary/type/BinaryDataType.js";
2
+ import { matrix_top_eigenvector_power_iteration } from "../../math/linalg/eigen/matrix_top_eigenvector_power_iteration.js";
3
+ import { SquareMatrix } from "../../math/matrix/SquareMatrix.js"
4
+
5
+ const scratch_horn_n = new SquareMatrix(4, BinaryDataType.Float64);
6
+
7
+ /**
8
+ * Closed-form solution for the rotation that best aligns two sets of unit
9
+ * vectors, via Horn (1987) "Closed-form solution of absolute orientation using
10
+ * unit quaternions".
11
+ *
12
+ * Given paired unit vectors {a_i} and {b_i}, finds the unit quaternion q such
13
+ * that rotating each b_i by q minimizes Σ |a_i − R(q)·b_i|².
14
+ *
15
+ * The matrix N is built so that the eigenvector of its largest eigenvalue
16
+ * IS the optimal rotation quaternion (in scalar-last form, matching meep's
17
+ * `Quaternion`).
18
+ *
19
+ * Inputs are unit vectors so no centroid subtraction is needed — the rotation
20
+ * is recovered from the cross-correlations alone.
21
+ *
22
+ * @param {Float32Array|number[]} a_xyz Source vectors — Length: count*3, unit length per triple
23
+ * @param {Float32Array|number[]} b_xyz Target vectors — Length: count*3, unit length per triple
24
+ * @param {number} count
25
+ * @param {Float32Array|number[]} out_quaternion Length 4 (x, y, z, w)
26
+ * @returns {number} The maximum eigenvalue ≈ Σ a_i · R·b_i. For a perfect alignment this equals `count`.
27
+ */
28
+ export function v3_rigid_align_paired_unit_vectors(a_xyz, b_xyz, count, out_quaternion) {
29
+
30
+ // Cross-correlation matrix S_ij = Σ b_i_component * a_j_component
31
+ // Note: S is built as Σ b ⊗ aᵀ (Horn 1987 convention) — the rotation
32
+ // recovered will take b onto a.
33
+ let Sxx = 0, Sxy = 0, Sxz = 0;
34
+ let Syx = 0, Syy = 0, Syz = 0;
35
+ let Szx = 0, Szy = 0, Szz = 0;
36
+
37
+ for (let i = 0; i < count; i++) {
38
+ const i3 = i * 3;
39
+ const ax = a_xyz[i3], ay = a_xyz[i3 + 1], az = a_xyz[i3 + 2];
40
+ const bx = b_xyz[i3], by = b_xyz[i3 + 1], bz = b_xyz[i3 + 2];
41
+
42
+ Sxx += bx * ax;
43
+ Sxy += bx * ay;
44
+ Sxz += bx * az;
45
+ Syx += by * ax;
46
+ Syy += by * ay;
47
+ Syz += by * az;
48
+ Szx += bz * ax;
49
+ Szy += bz * ay;
50
+ Szz += bz * az;
51
+ }
52
+
53
+ // Horn's 4x4 symmetric matrix N (scalar-last quaternion ordering: x, y, z, w).
54
+ //
55
+ // From the paper, ordered for scalar-FIRST quaternion (w, x, y, z):
56
+ // N00 = Sxx + Syy + Szz N01 = Syz - Szy N02 = Szx - Sxz N03 = Sxy - Syx
57
+ // N11 = Sxx - Syy - Szz N12 = Sxy + Syx N13 = Szx + Sxz
58
+ // N22 = -Sxx + Syy - Szz N23 = Syz + Szy
59
+ // N33 = -Sxx - Syy + Szz
60
+ //
61
+ // We rebind to (x, y, z, w):
62
+ // row/col 0 = x, 1 = y, 2 = z, 3 = w
63
+ // i.e. swap original index 0 with 3 and shift others down.
64
+ const Nxx = Sxx - Syy - Szz;
65
+ const Nyy = -Sxx + Syy - Szz;
66
+ const Nzz = -Sxx - Syy + Szz;
67
+ const Nww = Sxx + Syy + Szz;
68
+ const Nxy = Sxy + Syx;
69
+ const Nxz = Szx + Sxz;
70
+ const Nxw = Syz - Szy;
71
+ const Nyz = Syz + Szy;
72
+ const Nyw = Szx - Sxz;
73
+ const Nzw = Sxy - Syx;
74
+
75
+ const N = scratch_horn_n;
76
+ const d = N.data;
77
+ // SquareMatrix is column-major: d[col * 4 + row]
78
+ d[0] = Nxx;
79
+ d[5] = Nyy;
80
+ d[10] = Nzz;
81
+ d[15] = Nww;
82
+ d[1] = Nxy;
83
+ d[4] = Nxy;
84
+ d[2] = Nxz;
85
+ d[8] = Nxz;
86
+ d[3] = Nxw;
87
+ d[12] = Nxw;
88
+ d[6] = Nyz;
89
+ d[9] = Nyz;
90
+ d[7] = Nyw;
91
+ d[13] = Nyw;
92
+ d[11] = Nzw;
93
+ d[14] = Nzw;
94
+
95
+ return matrix_top_eigenvector_power_iteration(N, out_quaternion);
96
+ }
@@ -22,11 +22,11 @@ function evaluateEdgeCost(edge) {
22
22
  const second = edge.target;
23
23
 
24
24
  //compute center points
25
- const x0 = first.midX();
26
- const y0 = first.midY();
25
+ const x0 = first.centerX;
26
+ const y0 = first.centerY;
27
27
 
28
- const x1 = second.midX();
29
- const y1 = second.midY();
28
+ const x1 = second.centerX;
29
+ const y1 = second.centerY;
30
30
 
31
31
  return Vector2._distance(x0, y0, x1, y1);
32
32
  }
@@ -63,7 +63,7 @@ function evaluateLayout(boxes, edges) {
63
63
  const footprint = computeBoundingBox(boxes);
64
64
 
65
65
  //overall size of the layout plays a role
66
- const totalArea = footprint.getHeight() * footprint.getWidth();
66
+ const totalArea = footprint.height * footprint.width;
67
67
 
68
68
  const totalConnectionLength = edges.reduce(function (sum, edge) {
69
69
  return sum + evaluateEdgeCost(edge);
@@ -177,8 +177,8 @@ function applyPull(edges, strength) {
177
177
  const first = edge.source;
178
178
  const second = edge.target;
179
179
 
180
- d.set(second.midX(), second.midY());
181
- d._sub(first.midX(), first.midY());
180
+ d.set(second.centerX, second.centerY);
181
+ d._sub(first.centerX, first.centerY);
182
182
 
183
183
  d.multiplyScalar(strength);
184
184
 
@@ -31,13 +31,13 @@ function compute_initial_placement(
31
31
 
32
32
  const targetCenter = target.getCenter();
33
33
 
34
- const targetH = target.getHeight();
35
- const targetW = target.getWidth();
34
+ const targetH = target.height;
35
+ const targetW = target.width;
36
36
 
37
37
  const targetDiagonal = Math.sqrt(targetH * targetH + targetW * targetW);
38
38
 
39
- const boxWidth = box.getWidth();
40
- const boxHeight = box.getHeight();
39
+ const boxWidth = box.width;
40
+ const boxHeight = box.height;
41
41
 
42
42
  const boxWidth_2 = boxWidth / 2;
43
43
  const boxHeight_2 = boxHeight / 2;
@@ -120,8 +120,8 @@ function compute_initial_placement(
120
120
 
121
121
  let score = 0;
122
122
 
123
- const availableWidth = availableSpace.getWidth();
124
- const availableHeight = availableSpace.getHeight();
123
+ const availableWidth = availableSpace.width;
124
+ const availableHeight = availableSpace.height;
125
125
 
126
126
  const spareWidth = availableWidth - boxWidth;
127
127
  const spareHeight = availableHeight - boxHeight;
@@ -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
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Find the eigenvector corresponding to the largest-magnitude eigenvalue of a
3
+ * symmetric square matrix using power iteration.
4
+ *
5
+ * Designed for small symmetric matrices where the dominant eigenvalue is
6
+ * well-separated from the rest (Horn's quaternion method on a 4x4, PCA on a
7
+ * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
8
+ * equal magnitude — convergence stalls in that regime.
9
+ *
10
+ * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
11
+ * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
12
+ * @param {number} [max_iterations=64]
13
+ * @param {number} [tolerance=1e-8] Convergence stops when ||v_next - v|| < tolerance
14
+ * @returns {number} The Rayleigh quotient (estimated eigenvalue)
15
+ */
16
+ export function matrix_top_eigenvector_power_iteration(matrix: SquareMatrix, out: number[] | Float32Array | Float64Array, max_iterations?: number, tolerance?: number): number;
17
+ //# sourceMappingURL=matrix_top_eigenvector_power_iteration.d.ts.map
@@ -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"}
@@ -0,0 +1,107 @@
1
+ import { assert } from "@woosh/meep-engine/src/core/assert.js";
2
+
3
+ let scratch_next = new Float64Array(16);
4
+
5
+ function ensure_scratch(n) {
6
+ if (scratch_next.length < n) scratch_next = new Float64Array(n);
7
+ return scratch_next;
8
+ }
9
+
10
+ /**
11
+ * Find the eigenvector corresponding to the largest-magnitude eigenvalue of a
12
+ * symmetric square matrix using power iteration.
13
+ *
14
+ * Designed for small symmetric matrices where the dominant eigenvalue is
15
+ * well-separated from the rest (Horn's quaternion method on a 4x4, PCA on a
16
+ * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
17
+ * equal magnitude — convergence stalls in that regime.
18
+ *
19
+ * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
20
+ * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
21
+ * @param {number} [max_iterations=64]
22
+ * @param {number} [tolerance=1e-8] Convergence stops when ||v_next - v|| < tolerance
23
+ * @returns {number} The Rayleigh quotient (estimated eigenvalue)
24
+ */
25
+ export function matrix_top_eigenvector_power_iteration(
26
+ matrix,
27
+ out,
28
+ max_iterations = 64,
29
+ tolerance = 1e-8
30
+ ) {
31
+ assert.defined(matrix, "matrix");
32
+ assert.defined(out, "out");
33
+
34
+ const n = matrix.size;
35
+ const data = matrix.data;
36
+
37
+ // Deterministic asymmetric initial vector. A uniform init (e.g. 1/√n in
38
+ // every slot) can be orthogonal to the dominant eigenvector when the matrix
39
+ // has block structure, stalling iteration on a sub-dominant eigenvalue.
40
+ // Irrational-component cosines avoid this for any reasonable n.
41
+ let init_norm_sq = 0;
42
+ for (let i = 0; i < n; i++) {
43
+ const v = Math.cos(i * 1.7 + 0.3);
44
+ out[i] = v;
45
+ init_norm_sq += v * v;
46
+ }
47
+ const init_inv = 1 / Math.sqrt(init_norm_sq);
48
+ for (let i = 0; i < n; i++) out[i] *= init_inv;
49
+
50
+ const next = ensure_scratch(n);
51
+ let eigenvalue = 0;
52
+
53
+ for (let iter = 0; iter < max_iterations; iter++) {
54
+ // next = matrix * out
55
+ // Column-major: data[col * n + row] is element at (row, col)
56
+ for (let row = 0; row < n; row++) {
57
+ let sum = 0;
58
+ for (let col = 0; col < n; col++) {
59
+ sum += data[col * n + row] * out[col];
60
+ }
61
+ next[row] = sum;
62
+ }
63
+
64
+ // Rayleigh quotient = out . next (since out is unit length and matrix is symmetric)
65
+ let rayleigh = 0;
66
+ for (let i = 0; i < n; i++) {
67
+ rayleigh += out[i] * next[i];
68
+ }
69
+
70
+ // Normalize next
71
+ let length_sqr = 0;
72
+ for (let i = 0; i < n; i++) {
73
+ length_sqr += next[i] * next[i];
74
+ }
75
+
76
+ if (length_sqr === 0) {
77
+ // Degenerate input — bail out, leave `out` as-is
78
+ return 0;
79
+ }
80
+
81
+ const inv_length = 1 / Math.sqrt(length_sqr);
82
+
83
+ // Sign-align next with out so we can measure convergence by raw difference.
84
+ // (Power iteration has a sign ambiguity per step when eigenvalue is negative.)
85
+ let dot = 0;
86
+ for (let i = 0; i < n; i++) {
87
+ dot += next[i] * out[i];
88
+ }
89
+ const sign = dot < 0 ? -inv_length : inv_length;
90
+
91
+ let delta_sqr = 0;
92
+ for (let i = 0; i < n; i++) {
93
+ const v = next[i] * sign;
94
+ const d = v - out[i];
95
+ delta_sqr += d * d;
96
+ out[i] = v;
97
+ }
98
+
99
+ eigenvalue = rayleigh;
100
+
101
+ if (delta_sqr < tolerance * tolerance) {
102
+ break;
103
+ }
104
+ }
105
+
106
+ return eigenvalue;
107
+ }
@@ -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
+ }