@woosh/meep-engine 2.138.19 → 2.139.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 (496) hide show
  1. package/package.json +2 -1
  2. package/src/core/collection/PairUint32Map.d.ts +100 -0
  3. package/src/core/collection/PairUint32Map.d.ts.map +1 -0
  4. package/src/core/collection/PairUint32Map.js +321 -0
  5. package/src/core/collection/Uint32Map.d.ts +119 -0
  6. package/src/core/collection/Uint32Map.d.ts.map +1 -0
  7. package/src/core/collection/Uint32Map.js +345 -0
  8. package/src/core/collection/array/array_shuffle.d.ts +10 -3
  9. package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
  10. package/src/core/collection/array/array_shuffle.js +27 -22
  11. package/src/core/collection/heap/FibonacciHeap.d.ts +195 -0
  12. package/src/core/collection/heap/FibonacciHeap.d.ts.map +1 -0
  13. package/src/core/collection/heap/FibonacciHeap.js +586 -0
  14. package/src/core/collection/heap/Uint32Heap.js +1 -1
  15. package/src/core/collection/heap/Uint32Heap4.d.ts +169 -0
  16. package/src/core/collection/heap/Uint32Heap4.d.ts.map +1 -0
  17. package/src/core/collection/heap/Uint32Heap4.js +490 -0
  18. package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts +27 -0
  19. package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts.map +1 -0
  20. package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +88 -0
  21. package/src/core/geom/3d/shape/BoxShape3D.d.ts +61 -0
  22. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -0
  23. package/src/core/geom/3d/shape/BoxShape3D.js +158 -0
  24. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +11 -0
  25. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  26. package/src/core/geom/3d/shape/CapsuleShape3D.js +12 -0
  27. package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts +37 -9
  28. package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts.map +1 -1
  29. package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -98
  30. package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts +10 -0
  31. package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts.map +1 -1
  32. package/src/core/geom/3d/shape/UnitSphereShape3D.js +11 -0
  33. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts +61 -0
  34. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -0
  35. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +148 -0
  36. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts +39 -0
  37. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts.map +1 -0
  38. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +147 -0
  39. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts +15 -0
  40. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts.map +1 -0
  41. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +22 -0
  42. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts +2 -0
  43. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts.map +1 -0
  44. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +673 -0
  45. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts +26 -0
  46. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -0
  47. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +222 -0
  48. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts +34 -0
  49. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts.map +1 -0
  50. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -0
  51. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts +36 -0
  52. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts.map +1 -0
  53. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -0
  54. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts +33 -0
  55. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts.map +1 -0
  56. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -0
  57. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts +68 -0
  58. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -0
  59. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +365 -0
  60. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +31 -0
  61. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -0
  62. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +112 -0
  63. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +22 -0
  64. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -0
  65. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +55 -0
  66. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts +32 -0
  67. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts.map +1 -0
  68. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -0
  69. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +22 -0
  70. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
  71. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +49 -0
  72. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +134 -0
  73. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
  74. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +276 -3
  75. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +17 -0
  76. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -0
  77. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +135 -0
  78. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts +14 -0
  79. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts.map +1 -0
  80. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +177 -0
  81. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts.map +1 -1
  82. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +20 -4
  83. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  84. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +5 -3
  85. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
  86. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +9 -0
  87. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.d.ts.map +1 -1
  88. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -45
  89. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.d.ts.map +1 -1
  90. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.js +7 -1
  91. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts +8 -6
  92. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts.map +1 -1
  93. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +8 -6
  94. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts +22 -0
  95. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts.map +1 -0
  96. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +73 -0
  97. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
  98. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +51 -1
  99. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts +10 -0
  100. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts.map +1 -0
  101. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -0
  102. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts +28 -0
  103. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -0
  104. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +227 -0
  105. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts +13 -0
  106. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts.map +1 -0
  107. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -0
  108. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts +11 -0
  109. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts.map +1 -0
  110. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +20 -0
  111. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts +20 -0
  112. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts.map +1 -0
  113. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +38 -0
  114. package/src/core/graph/csr/CSRGraph.d.ts +168 -0
  115. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -0
  116. package/src/core/graph/csr/CSRGraph.js +319 -0
  117. package/src/core/graph/metis/cluster_mesh_metis.d.ts +12 -0
  118. package/src/core/graph/metis/cluster_mesh_metis.d.ts.map +1 -1
  119. package/src/core/graph/metis/cluster_mesh_metis.js +12 -0
  120. package/src/core/graph/metis/metis.d.ts +19 -0
  121. package/src/core/graph/metis/metis.d.ts.map +1 -1
  122. package/src/core/graph/metis/metis.js +20 -0
  123. package/src/core/graph/metis/metis_cluster_bs.d.ts +11 -0
  124. package/src/core/graph/metis/metis_cluster_bs.d.ts.map +1 -1
  125. package/src/core/graph/metis/metis_cluster_bs.js +11 -0
  126. package/src/core/graph/metis/metis_options.d.ts +17 -2
  127. package/src/core/graph/metis/metis_options.d.ts.map +1 -1
  128. package/src/core/graph/metis/metis_options.js +17 -2
  129. package/src/core/graph/metis/native/MetisGraph.d.ts +144 -0
  130. package/src/core/graph/metis/native/MetisGraph.d.ts.map +1 -0
  131. package/src/core/graph/metis/native/MetisGraph.js +212 -0
  132. package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts +72 -0
  133. package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts.map +1 -0
  134. package/src/core/graph/metis/native/bisection/BisectionScratch.js +101 -0
  135. package/src/core/graph/metis/native/bisection/bisect_graph.d.ts +37 -0
  136. package/src/core/graph/metis/native/bisection/bisect_graph.d.ts.map +1 -0
  137. package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -0
  138. package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts +15 -0
  139. package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts.map +1 -0
  140. package/src/core/graph/metis/native/bisection/compute_2way_params.js +84 -0
  141. package/src/core/graph/metis/native/bisection/fm_2way.d.ts +30 -0
  142. package/src/core/graph/metis/native/bisection/fm_2way.d.ts.map +1 -0
  143. package/src/core/graph/metis/native/bisection/fm_2way.js +290 -0
  144. package/src/core/graph/metis/native/bisection/grow_bisection.d.ts +23 -0
  145. package/src/core/graph/metis/native/bisection/grow_bisection.d.ts.map +1 -0
  146. package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -0
  147. package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts +28 -0
  148. package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts.map +1 -0
  149. package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -0
  150. package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts +20 -0
  151. package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts.map +1 -0
  152. package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -0
  153. package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts +24 -0
  154. package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts.map +1 -0
  155. package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -0
  156. package/src/core/graph/metis/native/coarsen/match_shem.d.ts +41 -0
  157. package/src/core/graph/metis/native/coarsen/match_shem.d.ts.map +1 -0
  158. package/src/core/graph/metis/native/coarsen/match_shem.js +175 -0
  159. package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts +24 -0
  160. package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts.map +1 -0
  161. package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -0
  162. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts +29 -0
  163. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts.map +1 -0
  164. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -0
  165. package/src/core/graph/metis/native/metis_partition_kway.d.ts +41 -0
  166. package/src/core/graph/metis/native/metis_partition_kway.d.ts.map +1 -0
  167. package/src/core/graph/metis/native/metis_partition_kway.js +126 -0
  168. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts +62 -0
  169. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts.map +1 -0
  170. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.js +261 -0
  171. package/src/core/graph/metis/native/refine/RefinementScratch.d.ts +45 -0
  172. package/src/core/graph/metis/native/refine/RefinementScratch.d.ts.map +1 -0
  173. package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -0
  174. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts +18 -0
  175. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -0
  176. package/src/core/graph/metis/native/refine/compute_kway_params.js +138 -0
  177. package/src/core/graph/metis/native/refine/fm_kway.d.ts +63 -0
  178. package/src/core/graph/metis/native/refine/fm_kway.d.ts.map +1 -0
  179. package/src/core/graph/metis/native/refine/fm_kway.js +462 -0
  180. package/src/core/graph/metis/native/refine/project_kway.d.ts +22 -0
  181. package/src/core/graph/metis/native/refine/project_kway.d.ts.map +1 -0
  182. package/src/core/graph/metis/native/refine/project_kway.js +43 -0
  183. package/src/core/graph/metis/native/refine/refine_kway.d.ts +34 -0
  184. package/src/core/graph/metis/native/refine/refine_kway.d.ts.map +1 -0
  185. package/src/core/graph/metis/native/refine/refine_kway.js +43 -0
  186. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts +2 -2
  187. package/src/core/math/linalg/eigen/matrix_householder_in_place.js +2 -2
  188. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +6 -4
  189. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -1
  190. package/src/core/math/linalg/eigen/matrix_qr_in_place.js +69 -23
  191. package/src/engine/EngineHarness.d.ts +3 -1
  192. package/src/engine/EngineHarness.d.ts.map +1 -1
  193. package/src/engine/EngineHarness.js +6 -4
  194. package/src/engine/control/first-person/DESIGN.md +30 -6
  195. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -0
  196. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +102 -9
  197. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  198. package/src/engine/control/first-person/FirstPersonPlayerController.js +38 -3
  199. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +533 -4
  200. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  201. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +315 -6
  202. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +220 -22
  203. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  204. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +858 -241
  205. package/src/engine/control/first-person/TODO.md +127 -0
  206. package/src/engine/control/first-person/abilities/Ability.d.ts +101 -0
  207. package/src/engine/control/first-person/abilities/Ability.d.ts.map +1 -0
  208. package/src/engine/control/first-person/abilities/Ability.js +119 -0
  209. package/src/engine/control/first-person/abilities/AbilitySet.d.ts +86 -0
  210. package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -0
  211. package/src/engine/control/first-person/abilities/AbilitySet.js +185 -0
  212. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +62 -0
  213. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -0
  214. package/src/engine/control/first-person/abilities/LedgeGrab.js +199 -0
  215. package/src/engine/control/first-person/abilities/Mantle.d.ts +45 -0
  216. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -0
  217. package/src/engine/control/first-person/abilities/Mantle.js +188 -0
  218. package/src/engine/control/first-person/abilities/Slide.d.ts +33 -0
  219. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -0
  220. package/src/engine/control/first-person/abilities/Slide.js +158 -0
  221. package/src/engine/control/first-person/abilities/WallJump.d.ts +45 -0
  222. package/src/engine/control/first-person/abilities/WallJump.d.ts.map +1 -0
  223. package/src/engine/control/first-person/abilities/WallJump.js +131 -0
  224. package/src/engine/control/first-person/abilities/WallRun.d.ts +44 -0
  225. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -0
  226. package/src/engine/control/first-person/abilities/WallRun.js +180 -0
  227. package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts +49 -0
  228. package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts.map +1 -0
  229. package/src/engine/control/first-person/composer/EyeOffsetStack.js +60 -0
  230. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts +100 -0
  231. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts.map +1 -0
  232. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.js +133 -0
  233. package/src/engine/control/first-person/mastery/DecisionPoint.d.ts +10 -0
  234. package/src/engine/control/first-person/mastery/DecisionPoint.d.ts.map +1 -0
  235. package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -0
  236. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts +61 -0
  237. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts.map +1 -0
  238. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.js +109 -0
  239. package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts +40 -0
  240. package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts.map +1 -0
  241. package/src/engine/control/first-person/mastery/MasteryEvaluator.js +45 -0
  242. package/src/engine/control/first-person/mastery/MasteryScore.d.ts +68 -0
  243. package/src/engine/control/first-person/mastery/MasteryScore.d.ts.map +1 -0
  244. package/src/engine/control/first-person/mastery/MasteryScore.js +100 -0
  245. package/src/engine/control/first-person/mastery/MasterySet.d.ts +60 -0
  246. package/src/engine/control/first-person/mastery/MasterySet.d.ts.map +1 -0
  247. package/src/engine/control/first-person/mastery/MasterySet.js +86 -0
  248. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +58 -0
  249. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -0
  250. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +83 -0
  251. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +69 -0
  252. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -0
  253. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +109 -0
  254. package/src/engine/control/first-person/math/Spring.d.ts +56 -0
  255. package/src/engine/control/first-person/math/Spring.d.ts.map +1 -0
  256. package/src/engine/control/first-person/math/Spring.js +71 -0
  257. package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts +26 -0
  258. package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts.map +1 -0
  259. package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -0
  260. package/src/engine/control/first-person/math/computeMassRatios.d.ts +35 -0
  261. package/src/engine/control/first-person/math/computeMassRatios.d.ts.map +1 -0
  262. package/src/engine/control/first-person/math/computeMassRatios.js +44 -0
  263. package/src/engine/control/first-person/pose/FirstPersonPose.d.ts +31 -1
  264. package/src/engine/control/first-person/pose/FirstPersonPose.d.ts.map +1 -1
  265. package/src/engine/control/first-person/pose/FirstPersonPose.js +49 -3
  266. package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts +7 -0
  267. package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts.map +1 -0
  268. package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -0
  269. package/src/engine/control/first-person/prototype_first_person_controller.js +550 -119
  270. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +58 -0
  271. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -0
  272. package/src/engine/control/first-person/sensors/FirstPersonSensors.js +77 -0
  273. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +80 -0
  274. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -0
  275. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +196 -0
  276. package/src/engine/control/first-person/test/buildTestPlayer.d.ts +20 -0
  277. package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -0
  278. package/src/engine/control/first-person/test/buildTestPlayer.js +28 -0
  279. package/src/engine/ecs/EntityManager.d.ts +2 -2
  280. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  281. package/src/engine/ecs/EntityManager.js +13 -8
  282. package/src/engine/ecs/System.d.ts.map +1 -1
  283. package/src/engine/ecs/System.js +2 -2
  284. package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -2
  285. package/src/engine/graphics/ecs/light/Light.d.ts.map +1 -1
  286. package/src/engine/graphics/ecs/light/Light.js +27 -0
  287. package/src/engine/graphics/ecs/light/LightSystem.js +1 -1
  288. package/src/engine/graphics/ecs/path/PathDisplaySystem.d.ts.map +1 -1
  289. package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
  290. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +0 -2
  291. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -2
  292. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -2
  293. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -2
  294. package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts.map +1 -1
  295. package/src/engine/navigation/grid/find_path_on_grid_astar.js +11 -2
  296. package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -1
  297. package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +11 -1
  298. package/src/engine/physics/PLAN.md +236 -0
  299. package/src/engine/physics/body/BodyStorage.d.ts +187 -0
  300. package/src/engine/physics/body/BodyStorage.d.ts.map +1 -0
  301. package/src/engine/physics/body/BodyStorage.js +427 -0
  302. package/src/engine/physics/broadphase/PairList.d.ts +62 -0
  303. package/src/engine/physics/broadphase/PairList.d.ts.map +1 -0
  304. package/src/engine/physics/broadphase/PairList.js +97 -0
  305. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts +30 -0
  306. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +1 -0
  307. package/src/engine/physics/broadphase/aabb_transform_oriented.js +93 -0
  308. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +16 -0
  309. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -0
  310. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +61 -0
  311. package/src/engine/physics/broadphase/generate_pairs.d.ts +38 -0
  312. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -0
  313. package/src/engine/physics/broadphase/generate_pairs.js +101 -0
  314. package/src/engine/physics/contact/ManifoldStore.d.ts +226 -0
  315. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -0
  316. package/src/engine/physics/contact/ManifoldStore.js +499 -0
  317. package/src/engine/physics/ecs/BodyKind.d.ts +23 -0
  318. package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -0
  319. package/src/engine/physics/ecs/BodyKind.js +24 -0
  320. package/src/engine/physics/ecs/Collider.d.ts +98 -0
  321. package/src/engine/physics/ecs/Collider.d.ts.map +1 -0
  322. package/src/engine/physics/ecs/Collider.js +136 -0
  323. package/src/engine/physics/ecs/ColliderFlags.d.ts +14 -0
  324. package/src/engine/physics/ecs/ColliderFlags.d.ts.map +1 -0
  325. package/src/engine/physics/ecs/ColliderFlags.js +15 -0
  326. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +58 -0
  327. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -0
  328. package/src/engine/physics/ecs/ColliderObserverSystem.js +103 -0
  329. package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts +25 -0
  330. package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts.map +1 -0
  331. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -0
  332. package/src/engine/physics/ecs/PhysicsEvents.d.ts +15 -0
  333. package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -0
  334. package/src/engine/physics/ecs/PhysicsEvents.js +16 -0
  335. package/src/engine/physics/ecs/PhysicsSystem.d.ts +520 -0
  336. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -0
  337. package/src/engine/physics/ecs/PhysicsSystem.js +1159 -0
  338. package/src/engine/physics/ecs/RigidBody.d.ts +197 -0
  339. package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -0
  340. package/src/engine/physics/ecs/RigidBody.js +240 -0
  341. package/src/engine/physics/ecs/RigidBodyFlags.d.ts +21 -0
  342. package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -0
  343. package/src/engine/physics/ecs/RigidBodyFlags.js +22 -0
  344. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +28 -0
  345. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -0
  346. package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +81 -0
  347. package/src/engine/physics/ecs/SleepState.d.ts +11 -0
  348. package/src/engine/physics/ecs/SleepState.d.ts.map +1 -0
  349. package/src/engine/physics/ecs/SleepState.js +12 -0
  350. package/src/engine/physics/events/ContactEventBuffer.d.ts +46 -0
  351. package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -0
  352. package/src/engine/physics/events/ContactEventBuffer.js +83 -0
  353. package/src/engine/physics/events/diff_manifolds.d.ts +25 -0
  354. package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -0
  355. package/src/engine/physics/events/diff_manifolds.js +50 -0
  356. package/src/engine/physics/fluid/FluidField.d.ts +294 -16
  357. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  358. package/src/engine/physics/fluid/FluidField.js +510 -66
  359. package/src/engine/physics/fluid/FluidSimulator.d.ts +188 -5
  360. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  361. package/src/engine/physics/fluid/FluidSimulator.js +455 -95
  362. package/src/engine/physics/fluid/SliceVisualiser.d.ts +29 -6
  363. package/src/engine/physics/fluid/SliceVisualiser.d.ts.map +1 -1
  364. package/src/engine/physics/fluid/SliceVisualiser.js +190 -165
  365. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +154 -0
  366. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -0
  367. package/src/engine/physics/fluid/ecs/FluidComponent.js +238 -0
  368. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +45 -0
  369. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -0
  370. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -0
  371. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +107 -0
  372. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -0
  373. package/src/engine/physics/fluid/ecs/FluidSystem.js +278 -0
  374. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +62 -1
  375. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
  376. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -6
  377. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +17 -4
  378. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  379. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +105 -12
  380. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +43 -0
  381. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -0
  382. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +210 -0
  383. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +62 -1
  384. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  385. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +302 -8
  386. package/src/engine/physics/fluid/prototype.js +102 -91
  387. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts +33 -0
  388. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +1 -0
  389. package/src/engine/physics/fluid/solver/optimal_sor_omega.js +41 -0
  390. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +20 -5
  391. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
  392. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +60 -38
  393. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +25 -4
  394. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
  395. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +93 -73
  396. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts +23 -0
  397. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts.map +1 -0
  398. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.js +60 -0
  399. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts +23 -0
  400. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts.map +1 -0
  401. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.js +68 -0
  402. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +30 -0
  403. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -0
  404. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +66 -0
  405. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts +26 -0
  406. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts.map +1 -0
  407. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -0
  408. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts +30 -0
  409. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts.map +1 -0
  410. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -0
  411. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +49 -0
  412. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -0
  413. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +126 -0
  414. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +93 -0
  415. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -0
  416. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +424 -0
  417. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +20 -0
  418. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +1 -0
  419. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +83 -0
  420. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +26 -0
  421. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -0
  422. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +70 -0
  423. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
  424. package/src/engine/physics/gjk/expanding_polytope_algorithm.js +8 -10
  425. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +29 -0
  426. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -0
  427. package/src/engine/physics/inertia/world_inverse_inertia.js +79 -0
  428. package/src/engine/physics/integration/integrate_position.d.ts +16 -0
  429. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -0
  430. package/src/engine/physics/integration/integrate_position.js +48 -0
  431. package/src/engine/physics/integration/integrate_velocity.d.ts +25 -0
  432. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -0
  433. package/src/engine/physics/integration/integrate_velocity.js +79 -0
  434. package/src/engine/physics/integration/quat_integrate.d.ts +27 -0
  435. package/src/engine/physics/integration/quat_integrate.d.ts.map +1 -0
  436. package/src/engine/physics/integration/quat_integrate.js +62 -0
  437. package/src/engine/physics/island/IslandBuilder.d.ts +167 -0
  438. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -0
  439. package/src/engine/physics/island/IslandBuilder.js +411 -0
  440. package/src/engine/physics/island/union_find.d.ts +51 -0
  441. package/src/engine/physics/island/union_find.d.ts.map +1 -0
  442. package/src/engine/physics/island/union_find.js +76 -0
  443. package/src/engine/physics/narrowphase/PosedShape.d.ts +59 -0
  444. package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -0
  445. package/src/engine/physics/narrowphase/PosedShape.js +110 -0
  446. package/src/engine/physics/narrowphase/box_box_manifold.d.ts +32 -0
  447. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -0
  448. package/src/engine/physics/narrowphase/box_box_manifold.js +543 -0
  449. package/src/engine/physics/narrowphase/capsule_contacts.d.ts +122 -0
  450. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -0
  451. package/src/engine/physics/narrowphase/capsule_contacts.js +508 -0
  452. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +11 -0
  453. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -0
  454. package/src/engine/physics/narrowphase/narrowphase_step.js +382 -0
  455. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts +38 -0
  456. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -0
  457. package/src/engine/physics/narrowphase/sphere_box_contact.js +130 -0
  458. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts +26 -0
  459. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts.map +1 -0
  460. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +51 -0
  461. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts +83 -0
  462. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts.map +1 -0
  463. package/src/engine/physics/queries/PhysicsSurfacePoint.js +100 -0
  464. package/src/engine/physics/queries/raycast.d.ts +20 -0
  465. package/src/engine/physics/queries/raycast.d.ts.map +1 -0
  466. package/src/engine/physics/queries/raycast.js +249 -0
  467. package/src/engine/physics/solver/friction_cone.d.ts +16 -0
  468. package/src/engine/physics/solver/friction_cone.d.ts.map +1 -0
  469. package/src/engine/physics/solver/friction_cone.js +37 -0
  470. package/src/engine/physics/solver/solve_contacts.d.ts +36 -0
  471. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -0
  472. package/src/engine/physics/solver/solve_contacts.js +598 -0
  473. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts +0 -34
  474. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts.map +0 -1
  475. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.js +0 -66
  476. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts +0 -2
  477. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts.map +0 -1
  478. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.js +0 -54
  479. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts +0 -2
  480. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts.map +0 -1
  481. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.js +0 -26
  482. package/src/engine/ecs/components/Motion.d.ts +0 -21
  483. package/src/engine/ecs/components/Motion.d.ts.map +0 -1
  484. package/src/engine/ecs/components/Motion.js +0 -27
  485. package/src/engine/ecs/components/MotionSerializationAdapter.d.ts +0 -20
  486. package/src/engine/ecs/components/MotionSerializationAdapter.d.ts.map +0 -1
  487. package/src/engine/ecs/components/MotionSerializationAdapter.js +0 -26
  488. package/src/engine/ecs/systems/MotionSystem.d.ts +0 -9
  489. package/src/engine/ecs/systems/MotionSystem.d.ts.map +0 -1
  490. package/src/engine/ecs/systems/MotionSystem.js +0 -29
  491. package/src/engine/physics/fluid/Fluid.d.ts +0 -26
  492. package/src/engine/physics/fluid/Fluid.d.ts.map +0 -1
  493. package/src/engine/physics/fluid/Fluid.js +0 -221
  494. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts +0 -7
  495. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts.map +0 -1
  496. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.js +0 -8
@@ -0,0 +1,462 @@
1
+ // Per-vertex membership state for the priority queue. Each pass starts with
2
+ // every vertex NOT_PRESENT, boundary vertices get inserted (PRESENT), and once
3
+ // processed they become EXTRACTED so they don't get re-inserted within the pass.
4
+ const QUEUE_STATUS_NOT_PRESENT = 0;
5
+ const QUEUE_STATUS_PRESENT = 1;
6
+ const QUEUE_STATUS_EXTRACTED = 2;
7
+
8
+ /**
9
+ * K-way Fiduccia–Mattheyses cut refinement (single-constraint, cut objective).
10
+ *
11
+ * For each pass:
12
+ * 1. Insert all boundary vertices into a max-heap keyed by
13
+ * `gain = external_degree / sqrt(neighbor_partition_count) - internal_degree`.
14
+ * 2. Repeatedly pop the highest-gain vertex. Find the best target partition
15
+ * satisfying either the standard balance bounds OR a balance-improvement
16
+ * exception. Commit the move.
17
+ * 3. Each move incrementally updates id/ed/nbrs for the moved vertex and all
18
+ * its neighbours, including queue priorities and boundary membership.
19
+ *
20
+ * The pass terminates when the heap drains or no further moves help. Multiple
21
+ * passes are run (default 10) until cut stops improving.
22
+ *
23
+ * Mirrors `Greedy_KWayCutOptimize` from libmetis/kwayfm.c master (post-5.1.0),
24
+ * OMODE_REFINE branch. Three master-era refinements over the 5.1.0 baseline:
25
+ *
26
+ * - **Adaptive ub_factor**: at start, expand `ub_factor` to match the current
27
+ * load imbalance if the graph is already worse than the configured bound.
28
+ * Without this, refinement starting from an imbalanced state can't legally
29
+ * act on it and gets stuck.
30
+ * - **No `fudge_factor` slack** on the max-weight check (master forces this to
31
+ * 0 internally). The looser balance comes from the adaptive ub_factor instead.
32
+ * - **Balance-improvement exception**: a move that violates the strict balance
33
+ * bound is still allowed if it improves the proportional balance ratio
34
+ * between `from` and `to`. Lets refinement pull weight back toward the
35
+ * target over time.
36
+ *
37
+ * Skipped:
38
+ * - minconn (sub-domain connectivity minimisation)
39
+ * - contig (contiguous-partition articulation-point checks)
40
+ * - ncon > 1 (multi-constraint balance)
41
+ * - OMODE_BALANCE (we run REFINE only; the adaptive ub_factor recovers most
42
+ * of what an explicit BALANCE pass would have done)
43
+ *
44
+ * Assumes `compute_kway_params` (or `project_kway`) has populated the refinement
45
+ * state on the graph.
46
+ *
47
+ * @param {import('../MetisGraph.js').MetisGraph} graph
48
+ * @param {number} partition_count
49
+ * @param {{
50
+ * random: function():number,
51
+ * pass_count?: number,
52
+ * ub_factor?: number,
53
+ * fudge_factor?: number,
54
+ * }} opts
55
+ * `ub_factor` (default 1.03) caps `partition_weight` at `target × ub_factor`.
56
+ * Will be expanded automatically if the input is already more imbalanced.
57
+ * `fudge_factor` (default 0; master sets this to 0). Set non-zero to allow
58
+ * positive-gain moves to overshoot the max bound by `fudge_factor × gain`.
59
+ * @param {import('./RefinementScratch.js').RefinementScratch} scratch shared
60
+ * scratch sized to the original (finest) graph's vertex_count and the same
61
+ * partition_count used here
62
+ * @returns {number} total moves committed across all passes
63
+ */
64
+ export function fm_kway(graph, partition_count, opts, scratch) {
65
+ const random = opts.random;
66
+ const pass_count = opts.pass_count !== undefined ? opts.pass_count : 10;
67
+ const configured_ub_factor = opts.ub_factor !== undefined ? opts.ub_factor : 1.03;
68
+ const fudge_factor = opts.fudge_factor !== undefined ? opts.fudge_factor : 0.0;
69
+
70
+ const vertex_count = graph.vertex_count;
71
+ const edge_addresses = graph.edge_addresses;
72
+ const adjacency = graph.adjacency;
73
+ const edge_weights = graph.edge_weights;
74
+ const vertex_weights = graph.vertex_weights;
75
+ const vertex_partition = graph.vertex_partition;
76
+ const partition_weights = graph.partition_weights;
77
+ const boundary_vertices = graph.boundary_vertices;
78
+ const boundary_position_of_vertex = graph.boundary_position_of_vertex;
79
+ const internal_degree = graph.internal_degree;
80
+ const external_degree = graph.external_degree;
81
+ const neighbor_partition_count = graph.neighbor_partition_count;
82
+ const neighbor_partition_offset = graph.neighbor_partition_offset;
83
+ const neighbor_partition_pool = graph.neighbor_partition_pool;
84
+
85
+ // Adaptive ub_factor: if the input is already more imbalanced than the
86
+ // configured target, expand the bound so refinement can act on the
87
+ // imbalanced state instead of being stuck refusing every move. Mirrors
88
+ // master's `gk_max(ctrl->ubfactors[0], ComputeLoadImbalance(...))`.
89
+ const target_partition_weight = graph.total_vertex_weight / partition_count;
90
+ let current_max_imbalance_ratio = 1.0;
91
+ for (let p = 0; p < partition_count; p++) {
92
+ const ratio = partition_weights[p] / target_partition_weight;
93
+ if (ratio > current_max_imbalance_ratio) {
94
+ current_max_imbalance_ratio = ratio;
95
+ }
96
+ }
97
+ const effective_ub_factor = Math.max(configured_ub_factor, current_max_imbalance_ratio);
98
+
99
+ const partition_weight_min = scratch.partition_weight_min;
100
+ const partition_weight_max = scratch.partition_weight_max;
101
+ for (let p = 0; p < partition_count; p++) {
102
+ partition_weight_max[p] = Math.ceil(target_partition_weight * effective_ub_factor);
103
+ partition_weight_min[p] = Math.max(1, Math.floor(target_partition_weight / effective_ub_factor));
104
+ }
105
+
106
+ // All from shared scratch — no per-call allocation.
107
+ // queue_status and touched_position_of_vertex preserve their clean state
108
+ // (all-0 and all-(-1) respectively) across calls via the per-pass cleanup
109
+ // at the end of the main loop.
110
+ const move_queue = scratch.move_queue;
111
+ const queue_status = scratch.queue_status;
112
+ const touched_vertices = scratch.touched_vertices;
113
+ const touched_position_of_vertex = scratch.touched_position_of_vertex;
114
+
115
+ let total_moves = 0;
116
+
117
+ for (let pass = 0; pass < pass_count; pass++) {
118
+ const cut_at_pass_start = graph.current_cut;
119
+ let boundary_count = graph.boundary_count;
120
+ let touched_count = 0;
121
+ let moves_this_pass = 0;
122
+
123
+ move_queue.clear();
124
+
125
+ // Shuffle the boundary order before insertion. Heap ordering means
126
+ // visitation order doesn't change which vertex pops next, but it
127
+ // breaks ties differently each pass, which helps escape local minima.
128
+ // `touched_vertices` is reused as scratch for the shuffle.
129
+ for (let i = 0; i < boundary_count; i++) {
130
+ touched_vertices[i] = i;
131
+ }
132
+ for (let i = boundary_count - 1; i > 0; i--) {
133
+ const j = (random() * (i + 1)) | 0;
134
+ if (j !== i) {
135
+ const tmp = touched_vertices[i];
136
+ touched_vertices[i] = touched_vertices[j];
137
+ touched_vertices[j] = tmp;
138
+ }
139
+ }
140
+ for (let i = 0; i < boundary_count; i++) {
141
+ const vertex = boundary_vertices[touched_vertices[i]];
142
+ const v_external_degree = external_degree[vertex];
143
+ const v_internal_degree = internal_degree[vertex];
144
+ const v_nbr_partition_count = neighbor_partition_count[vertex];
145
+ const gain = v_nbr_partition_count > 0
146
+ ? v_external_degree / Math.sqrt(v_nbr_partition_count) - v_internal_degree
147
+ : -v_internal_degree;
148
+ move_queue.insert(vertex, gain);
149
+ queue_status[vertex] = QUEUE_STATUS_PRESENT;
150
+ }
151
+
152
+ // Build the touched-list properly (the scratch values above are now
153
+ // wrong since they were boundary indices, not vertex ids).
154
+ touched_count = boundary_count;
155
+ for (let i = 0; i < boundary_count; i++) {
156
+ const vertex = boundary_vertices[i];
157
+ touched_vertices[i] = vertex;
158
+ touched_position_of_vertex[vertex] = i;
159
+ }
160
+
161
+ // ===== Main move loop ============================================
162
+ for (;;) {
163
+ const vertex = move_queue.pop_max();
164
+ if (vertex === -1) {
165
+ break;
166
+ }
167
+ queue_status[vertex] = QUEUE_STATUS_EXTRACTED;
168
+
169
+ const from_partition = vertex_partition[vertex];
170
+ const vertex_weight = vertex_weights[vertex];
171
+ const v_internal_degree = internal_degree[vertex];
172
+ const v_external_degree = external_degree[vertex];
173
+ const v_nbr_partition_count = neighbor_partition_count[vertex];
174
+ const v_pool_offset = neighbor_partition_offset[vertex];
175
+
176
+ if (v_pool_offset === -1) {
177
+ // Vertex turned interior during this pass; nothing to do.
178
+ continue;
179
+ }
180
+
181
+ // ----- Select the best target partition --------------------------
182
+ // Walk v's neighbour-partition entries from the end. Take the first
183
+ // one that's acceptable under master's REFINE criterion: strictly
184
+ // positive cut gain AND (either both balance bounds respected, or
185
+ // the move improves the proportional balance ratio between `from`
186
+ // and `to`). Tie-break: zero-gain moves only if they're balance-
187
+ // improving. Then re-scan for a strictly better candidate.
188
+ //
189
+ // The balance-improvement test `pwgts[from] - vwgt > pwgts[to]`
190
+ // is master's `tpwgts[from]*pwgts[to] < tpwgts[to]*(pwgts[from]-vwgt)`
191
+ // simplified for uniform tpwgts (which is all we support).
192
+ const pool_data = neighbor_partition_pool.data_uint32;
193
+ const v_pool_word_base = neighbor_partition_pool.element_word(v_pool_offset);
194
+
195
+ const partition_weight_from_after = partition_weights[from_partition] - vertex_weight;
196
+
197
+ let best_nbr_index = -1;
198
+ for (let nbr_index = v_nbr_partition_count - 1; nbr_index >= 0; nbr_index--) {
199
+ const candidate_partition = pool_data[v_pool_word_base + nbr_index * 2];
200
+ const candidate_edge_weight = pool_data[v_pool_word_base + nbr_index * 2 + 1];
201
+ const candidate_weight_after = partition_weights[candidate_partition] + vertex_weight;
202
+
203
+ // "Move improves proportional balance" (uniform-tpwgts form).
204
+ const balance_improves = candidate_weight_after - vertex_weight < partition_weight_from_after;
205
+
206
+ const from_ok = partition_weight_from_after >= partition_weight_min[from_partition] || balance_improves;
207
+ const to_ok = candidate_weight_after <= partition_weight_max[candidate_partition] + fudge_factor * (candidate_edge_weight - v_internal_degree) || balance_improves;
208
+
209
+ if (candidate_edge_weight > v_internal_degree && from_ok && to_ok) {
210
+ best_nbr_index = nbr_index;
211
+ break;
212
+ }
213
+ if (candidate_edge_weight === v_internal_degree && balance_improves) {
214
+ best_nbr_index = nbr_index;
215
+ break;
216
+ }
217
+ }
218
+ if (best_nbr_index === -1) {
219
+ continue;
220
+ }
221
+
222
+ {
223
+ let best_edge_weight = pool_data[v_pool_word_base + best_nbr_index * 2 + 1];
224
+ let best_target_partition = pool_data[v_pool_word_base + best_nbr_index * 2];
225
+ for (let nbr_index = best_nbr_index - 1; nbr_index >= 0; nbr_index--) {
226
+ const candidate_partition = pool_data[v_pool_word_base + nbr_index * 2];
227
+ const candidate_edge_weight = pool_data[v_pool_word_base + nbr_index * 2 + 1];
228
+ const candidate_weight_after = partition_weights[candidate_partition] + vertex_weight;
229
+ const balance_improves = candidate_weight_after - vertex_weight < partition_weight_from_after;
230
+
231
+ const from_ok = partition_weight_from_after >= partition_weight_min[from_partition] || balance_improves;
232
+ const to_ok = candidate_weight_after <= partition_weight_max[candidate_partition] + fudge_factor * (candidate_edge_weight - v_internal_degree) || balance_improves;
233
+
234
+ if (candidate_edge_weight > best_edge_weight && from_ok && to_ok) {
235
+ best_nbr_index = nbr_index;
236
+ best_edge_weight = candidate_edge_weight;
237
+ best_target_partition = candidate_partition;
238
+ } else if (
239
+ candidate_edge_weight === best_edge_weight &&
240
+ partition_weights[candidate_partition] < partition_weights[best_target_partition]
241
+ ) {
242
+ best_nbr_index = nbr_index;
243
+ best_target_partition = candidate_partition;
244
+ }
245
+ }
246
+ }
247
+
248
+ const to_partition = pool_data[v_pool_word_base + best_nbr_index * 2];
249
+ const to_edge_weight = pool_data[v_pool_word_base + best_nbr_index * 2 + 1];
250
+ const gain = to_edge_weight - v_internal_degree;
251
+
252
+ // ===== Commit the move =========================================
253
+ graph.current_cut -= gain;
254
+ moves_this_pass++;
255
+ total_moves++;
256
+
257
+ partition_weights[from_partition] -= vertex_weight;
258
+ partition_weights[to_partition] += vertex_weight;
259
+ vertex_partition[vertex] = to_partition;
260
+
261
+ // Update v's own id/ed and the neighbour-partition entry at best_nbr_index.
262
+ // After the move:
263
+ // new internal_degree = old edge-weight to `to_partition` (those edges are now internal)
264
+ // new external_degree = old external_degree - old edge-weight to to + old internal_degree
265
+ // (old internal edges to `from_partition` become external)
266
+ const new_internal_degree = to_edge_weight;
267
+ const new_external_degree = v_external_degree - to_edge_weight + v_internal_degree;
268
+ internal_degree[vertex] = new_internal_degree;
269
+ external_degree[vertex] = new_external_degree;
270
+
271
+ if (v_internal_degree === 0) {
272
+ // No back-edges to `from_partition`. Drop the entry by swap-with-last.
273
+ const last_index = v_nbr_partition_count - 1;
274
+ if (best_nbr_index !== last_index) {
275
+ pool_data[v_pool_word_base + best_nbr_index * 2] = pool_data[v_pool_word_base + last_index * 2];
276
+ pool_data[v_pool_word_base + best_nbr_index * 2 + 1] = pool_data[v_pool_word_base + last_index * 2 + 1];
277
+ }
278
+ neighbor_partition_count[vertex] = last_index;
279
+ } else {
280
+ // The slot that used to represent `to_partition` now represents
281
+ // `from_partition` with the old internal_degree as its edge weight.
282
+ pool_data[v_pool_word_base + best_nbr_index * 2] = from_partition;
283
+ pool_data[v_pool_word_base + best_nbr_index * 2 + 1] = v_internal_degree;
284
+ }
285
+
286
+ // Update v's boundary membership.
287
+ {
288
+ const v_boundary_position = boundary_position_of_vertex[vertex];
289
+ if (v_boundary_position !== -1 && new_external_degree - new_internal_degree < 0) {
290
+ const last_boundary_index = boundary_count - 1;
291
+ if (v_boundary_position !== last_boundary_index) {
292
+ const moved_vertex = boundary_vertices[last_boundary_index];
293
+ boundary_vertices[v_boundary_position] = moved_vertex;
294
+ boundary_position_of_vertex[moved_vertex] = v_boundary_position;
295
+ }
296
+ boundary_position_of_vertex[vertex] = -1;
297
+ boundary_count = last_boundary_index;
298
+ } else if (v_boundary_position === -1 && new_external_degree - new_internal_degree >= 0) {
299
+ boundary_vertices[boundary_count] = vertex;
300
+ boundary_position_of_vertex[vertex] = boundary_count;
301
+ boundary_count++;
302
+ }
303
+ }
304
+
305
+ // ----- Update each neighbour of v -------------------------------
306
+ for (let edge_offset = edge_addresses[vertex]; edge_offset < edge_addresses[vertex + 1]; edge_offset++) {
307
+ const neighbor = adjacency[edge_offset];
308
+ const neighbor_owning_partition = vertex_partition[neighbor];
309
+ const edge_weight_to_neighbor = edge_weights[edge_offset];
310
+
311
+ const neighbor_old_nbr_partition_count = neighbor_partition_count[neighbor];
312
+ let neighbor_pool_offset = neighbor_partition_offset[neighbor];
313
+
314
+ if (neighbor_pool_offset === -1) {
315
+ // Neighbour was interior; allocate now, sized to its degree
316
+ // so subsequent additions will fit.
317
+ const neighbor_degree = edge_addresses[neighbor + 1] - edge_addresses[neighbor];
318
+ neighbor_pool_offset = neighbor_partition_pool.allocate_continuous(neighbor_degree);
319
+ neighbor_partition_offset[neighbor] = neighbor_pool_offset;
320
+ }
321
+ // Re-fetch the data view in case the pool grew during allocate.
322
+ const pool_data_for_neighbor = neighbor_partition_pool.data_uint32;
323
+ const neighbor_pool_word_base = neighbor_partition_pool.element_word(neighbor_pool_offset);
324
+
325
+ let n_internal_degree = internal_degree[neighbor];
326
+ let n_external_degree = external_degree[neighbor];
327
+ let n_nbr_partition_count = neighbor_partition_count[neighbor];
328
+
329
+ if (neighbor_owning_partition === from_partition) {
330
+ // The edge v–neighbor used to be internal for the neighbour
331
+ // (both in `from`); after v's move it becomes external.
332
+ n_internal_degree -= edge_weight_to_neighbor;
333
+ n_external_degree += edge_weight_to_neighbor;
334
+ } else if (neighbor_owning_partition === to_partition) {
335
+ // The reverse — was external, now internal.
336
+ n_internal_degree += edge_weight_to_neighbor;
337
+ n_external_degree -= edge_weight_to_neighbor;
338
+ }
339
+
340
+ // Remove the neighbour's record of `from_partition` (or
341
+ // decrement it). Only do this if the neighbour is not itself
342
+ // in `from_partition`; if it is, `from` isn't in its neighbour
343
+ // list at all.
344
+ if (neighbor_owning_partition !== from_partition) {
345
+ for (let nbr_index = 0; nbr_index < n_nbr_partition_count; nbr_index++) {
346
+ if (pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2] === from_partition) {
347
+ const current_edge_weight = pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2 + 1];
348
+ if (current_edge_weight === edge_weight_to_neighbor) {
349
+ // Last edge to from-partition; remove the entry.
350
+ const last_index = n_nbr_partition_count - 1;
351
+ if (nbr_index !== last_index) {
352
+ pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2] = pool_data_for_neighbor[neighbor_pool_word_base + last_index * 2];
353
+ pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2 + 1] = pool_data_for_neighbor[neighbor_pool_word_base + last_index * 2 + 1];
354
+ }
355
+ n_nbr_partition_count = last_index;
356
+ } else {
357
+ pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2 + 1] = current_edge_weight - edge_weight_to_neighbor;
358
+ }
359
+ break;
360
+ }
361
+ }
362
+ }
363
+
364
+ // Add or increment the neighbour's record of `to_partition`,
365
+ // unless the neighbour is itself in `to_partition`.
366
+ if (neighbor_owning_partition !== to_partition) {
367
+ let found_existing_entry = false;
368
+ for (let nbr_index = 0; nbr_index < n_nbr_partition_count; nbr_index++) {
369
+ if (pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2] === to_partition) {
370
+ pool_data_for_neighbor[neighbor_pool_word_base + nbr_index * 2 + 1] += edge_weight_to_neighbor;
371
+ found_existing_entry = true;
372
+ break;
373
+ }
374
+ }
375
+ if (!found_existing_entry) {
376
+ pool_data_for_neighbor[neighbor_pool_word_base + n_nbr_partition_count * 2] = to_partition;
377
+ pool_data_for_neighbor[neighbor_pool_word_base + n_nbr_partition_count * 2 + 1] = edge_weight_to_neighbor;
378
+ n_nbr_partition_count++;
379
+ }
380
+ }
381
+
382
+ internal_degree[neighbor] = n_internal_degree;
383
+ external_degree[neighbor] = n_external_degree;
384
+ neighbor_partition_count[neighbor] = n_nbr_partition_count;
385
+
386
+ // Update boundary membership for the neighbour.
387
+ const n_boundary_position = boundary_position_of_vertex[neighbor];
388
+ if (neighbor_owning_partition === from_partition && n_external_degree - n_internal_degree >= 0 && n_boundary_position === -1) {
389
+ boundary_vertices[boundary_count] = neighbor;
390
+ boundary_position_of_vertex[neighbor] = boundary_count;
391
+ boundary_count++;
392
+ } else if (neighbor_owning_partition === to_partition && n_external_degree - n_internal_degree < 0 && n_boundary_position !== -1) {
393
+ const last_boundary_index = boundary_count - 1;
394
+ if (n_boundary_position !== last_boundary_index) {
395
+ const moved_vertex = boundary_vertices[last_boundary_index];
396
+ boundary_vertices[n_boundary_position] = moved_vertex;
397
+ boundary_position_of_vertex[moved_vertex] = n_boundary_position;
398
+ }
399
+ boundary_position_of_vertex[neighbor] = -1;
400
+ boundary_count = last_boundary_index;
401
+ }
402
+
403
+ // Update the priority queue. Skip if the neighbour's
404
+ // partition wasn't `from` or `to` AND its nbr-count didn't
405
+ // change — nothing observably moved for it.
406
+ const neighbor_state_changed = (
407
+ neighbor_owning_partition === from_partition ||
408
+ neighbor_owning_partition === to_partition ||
409
+ neighbor_old_nbr_partition_count !== n_nbr_partition_count
410
+ );
411
+ if (neighbor_state_changed) {
412
+ const updated_gain = n_nbr_partition_count > 0
413
+ ? n_external_degree / Math.sqrt(n_nbr_partition_count) - n_internal_degree
414
+ : -n_internal_degree;
415
+ const neighbor_status = queue_status[neighbor];
416
+ if (neighbor_status === QUEUE_STATUS_PRESENT) {
417
+ if (n_external_degree - n_internal_degree >= 0) {
418
+ move_queue.update(neighbor, updated_gain);
419
+ } else {
420
+ // No longer a boundary candidate; drop from queue.
421
+ move_queue.remove(neighbor);
422
+ queue_status[neighbor] = QUEUE_STATUS_NOT_PRESENT;
423
+ const touched_pos = touched_position_of_vertex[neighbor];
424
+ if (touched_pos !== -1) {
425
+ const last_touched_index = touched_count - 1;
426
+ if (touched_pos !== last_touched_index) {
427
+ const moved_touched_vertex = touched_vertices[last_touched_index];
428
+ touched_vertices[touched_pos] = moved_touched_vertex;
429
+ touched_position_of_vertex[moved_touched_vertex] = touched_pos;
430
+ }
431
+ touched_position_of_vertex[neighbor] = -1;
432
+ touched_count = last_touched_index;
433
+ }
434
+ }
435
+ } else if (neighbor_status === QUEUE_STATUS_NOT_PRESENT && n_external_degree - n_internal_degree >= 0) {
436
+ move_queue.insert(neighbor, updated_gain);
437
+ queue_status[neighbor] = QUEUE_STATUS_PRESENT;
438
+ touched_vertices[touched_count] = neighbor;
439
+ touched_position_of_vertex[neighbor] = touched_count;
440
+ touched_count++;
441
+ }
442
+ // EXTRACTED: don't re-insert in the same pass.
443
+ }
444
+ }
445
+ }
446
+
447
+ graph.boundary_count = boundary_count;
448
+
449
+ // Reset per-pass tracking state.
450
+ for (let i = 0; i < touched_count; i++) {
451
+ const vertex = touched_vertices[i];
452
+ queue_status[vertex] = QUEUE_STATUS_NOT_PRESENT;
453
+ touched_position_of_vertex[vertex] = -1;
454
+ }
455
+
456
+ if (moves_this_pass === 0 || graph.current_cut === cut_at_pass_start) {
457
+ break;
458
+ }
459
+ }
460
+
461
+ return total_moves;
462
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Project the partition assignment from `graph.coarser_graph` down to `graph`,
3
+ * then compute the k-way refinement bookkeeping at the fine level.
4
+ *
5
+ * Each fine vertex inherits the partition of its coarse parent
6
+ * (`coarse_vertex_map[v]` maps fine→coarse). After projection,
7
+ * `vertex_partition`, `partition_weights`, the `internal_degree` /
8
+ * `external_degree` / `neighbor_partition_*` arrays, the boundary list, and
9
+ * `current_cut` are all rebuilt from scratch.
10
+ *
11
+ * METIS's `ProjectKWayPartition` folds the projection into the parameter-compute
12
+ * pass and uses the coarse graph's `external_degree[]` as a hint to skip vertices
13
+ * that are guaranteed interior. That's a measurable speedup at scale, but the
14
+ * state coupling isn't worth it in v1 — we just project then call the standard
15
+ * compute routine.
16
+ *
17
+ * @param {import('../MetisGraph.js').MetisGraph} graph the fine graph (must have
18
+ * `.coarser_graph` set and that coarser graph's `vertex_partition` populated)
19
+ * @param {number} partition_count
20
+ */
21
+ export function project_kway(graph: import('../MetisGraph.js').MetisGraph, partition_count: number): void;
22
+ //# sourceMappingURL=project_kway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project_kway.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/graph/metis/native/refine/project_kway.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,oCAJW,OAAO,kBAAkB,EAAE,UAAU,mBAErC,MAAM,QAqBhB"}
@@ -0,0 +1,43 @@
1
+ import { assert } from "../../../../assert.js";
2
+ import { compute_kway_params } from "./compute_kway_params.js";
3
+
4
+ /**
5
+ * Project the partition assignment from `graph.coarser_graph` down to `graph`,
6
+ * then compute the k-way refinement bookkeeping at the fine level.
7
+ *
8
+ * Each fine vertex inherits the partition of its coarse parent
9
+ * (`coarse_vertex_map[v]` maps fine→coarse). After projection,
10
+ * `vertex_partition`, `partition_weights`, the `internal_degree` /
11
+ * `external_degree` / `neighbor_partition_*` arrays, the boundary list, and
12
+ * `current_cut` are all rebuilt from scratch.
13
+ *
14
+ * METIS's `ProjectKWayPartition` folds the projection into the parameter-compute
15
+ * pass and uses the coarse graph's `external_degree[]` as a hint to skip vertices
16
+ * that are guaranteed interior. That's a measurable speedup at scale, but the
17
+ * state coupling isn't worth it in v1 — we just project then call the standard
18
+ * compute routine.
19
+ *
20
+ * @param {import('../MetisGraph.js').MetisGraph} graph the fine graph (must have
21
+ * `.coarser_graph` set and that coarser graph's `vertex_partition` populated)
22
+ * @param {number} partition_count
23
+ */
24
+ export function project_kway(graph, partition_count) {
25
+ const coarser_graph = graph.coarser_graph;
26
+ const coarse_vertex_map = graph.coarse_vertex_map;
27
+
28
+ assert.equal(coarser_graph !== null, true, 'graph.coarser_graph must be set before projection');
29
+ assert.equal(coarse_vertex_map !== null, true, 'graph.coarse_vertex_map must be set before projection');
30
+ assert.equal(coarser_graph.vertex_partition !== null, true, 'coarser_graph.vertex_partition must be populated before projection');
31
+
32
+ graph.allocate_partition_state(partition_count);
33
+
34
+ const fine_partition = graph.vertex_partition;
35
+ const coarse_partition = coarser_graph.vertex_partition;
36
+ const vertex_count = graph.vertex_count;
37
+
38
+ for (let vertex = 0; vertex < vertex_count; vertex++) {
39
+ fine_partition[vertex] = coarse_partition[coarse_vertex_map[vertex]];
40
+ }
41
+
42
+ compute_kway_params(graph, partition_count);
43
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Uncoarsen the multilevel graph hierarchy, running FM refinement at every level.
3
+ *
4
+ * On entry, `coarsest_graph` has a valid initial partition in
5
+ * `coarsest_graph.vertex_partition[]` and its refinement bookkeeping fully
6
+ * populated (via `compute_kway_params`). On exit, `original_graph.vertex_partition[]`
7
+ * holds the refined partition of the original finest graph.
8
+ *
9
+ * Mirrors `RefineKWay` from libmetis/kwayrefine.c, simplified:
10
+ * - no minconn / contig handling
11
+ * - no separate balance passes (we run REFINE-only at each level; the
12
+ * adaptive ub_factor in fm_kway recovers most of what an explicit BALANCE
13
+ * pass would have done)
14
+ * - no separator/volume code
15
+ *
16
+ * @param {import('../MetisGraph.js').MetisGraph} original_graph the finest graph
17
+ * @param {import('../MetisGraph.js').MetisGraph} coarsest_graph the coarsest graph
18
+ * @param {number} partition_count
19
+ * @param {{
20
+ * random: function():number,
21
+ * pass_count?: number,
22
+ * ub_factor?: number,
23
+ * fudge_factor?: number,
24
+ * }} opts forwarded to `fm_kway`
25
+ * @param {import('./RefinementScratch.js').RefinementScratch} scratch shared scratch
26
+ * sized to `original_graph.vertex_count`
27
+ */
28
+ export function refine_kway(original_graph: import('../MetisGraph.js').MetisGraph, coarsest_graph: import('../MetisGraph.js').MetisGraph, partition_count: number, opts: {
29
+ random: () => number;
30
+ pass_count?: number;
31
+ ub_factor?: number;
32
+ fudge_factor?: number;
33
+ }, scratch: import('./RefinementScratch.js').RefinementScratch): void;
34
+ //# sourceMappingURL=refine_kway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refine_kway.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/graph/metis/native/refine/refine_kway.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,4CAZW,OAAO,kBAAkB,EAAE,UAAU,kBACrC,OAAO,kBAAkB,EAAE,UAAU,mBACrC,MAAM,QACN;IACV,MAAU,QAAa,MAAM,CAAC;IAC9B,UAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAgB,CAAC,EAAE,MAAM,CAAC;CACvB,WACO,OAAO,wBAAwB,EAAE,iBAAiB,QAe5D"}
@@ -0,0 +1,43 @@
1
+ import { fm_kway } from "./fm_kway.js";
2
+ import { project_kway } from "./project_kway.js";
3
+
4
+ /**
5
+ * Uncoarsen the multilevel graph hierarchy, running FM refinement at every level.
6
+ *
7
+ * On entry, `coarsest_graph` has a valid initial partition in
8
+ * `coarsest_graph.vertex_partition[]` and its refinement bookkeeping fully
9
+ * populated (via `compute_kway_params`). On exit, `original_graph.vertex_partition[]`
10
+ * holds the refined partition of the original finest graph.
11
+ *
12
+ * Mirrors `RefineKWay` from libmetis/kwayrefine.c, simplified:
13
+ * - no minconn / contig handling
14
+ * - no separate balance passes (we run REFINE-only at each level; the
15
+ * adaptive ub_factor in fm_kway recovers most of what an explicit BALANCE
16
+ * pass would have done)
17
+ * - no separator/volume code
18
+ *
19
+ * @param {import('../MetisGraph.js').MetisGraph} original_graph the finest graph
20
+ * @param {import('../MetisGraph.js').MetisGraph} coarsest_graph the coarsest graph
21
+ * @param {number} partition_count
22
+ * @param {{
23
+ * random: function():number,
24
+ * pass_count?: number,
25
+ * ub_factor?: number,
26
+ * fudge_factor?: number,
27
+ * }} opts forwarded to `fm_kway`
28
+ * @param {import('./RefinementScratch.js').RefinementScratch} scratch shared scratch
29
+ * sized to `original_graph.vertex_count`
30
+ */
31
+ export function refine_kway(original_graph, coarsest_graph, partition_count, opts, scratch) {
32
+ let current_level = coarsest_graph;
33
+
34
+ // First refine the freshly-initialised coarsest partition before projection.
35
+ fm_kway(current_level, partition_count, opts, scratch);
36
+
37
+ while (current_level !== original_graph) {
38
+ const finer_level = current_level.finer_graph;
39
+ project_kway(finer_level, partition_count);
40
+ current_level = finer_level;
41
+ fm_kway(current_level, partition_count, opts, scratch);
42
+ }
43
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * NxN matrix Householder reduction to upper Hessenberg form via similarity
3
3
  * transformations. After this routine, `a[c*n + r] == 0` for every `r > c+1`
4
- * — i.e. only the main diagonal and the first sub-diagonal carry nonzeros
4
+ * — i.e. only the main diagonal and the first sub-diagonal carry non-zeros
5
5
  * below the diagonal.
6
6
  *
7
7
  * Inner loops are arranged so the hot accesses stream one column at a time
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
11
11
  * @param {number[]|Float64Array} a Square matrix, column-major flat layout (a[j*n + i] = row i, col j); modified in place
12
- * @param {number} n
12
+ * @param {number} n matrix size (e.g. 4 for 4x4 matrix)
13
13
  */
14
14
  export function matrix_householder_in_place(a: number[] | Float64Array, n: number): void;
15
15
  //# sourceMappingURL=matrix_householder_in_place.d.ts.map
@@ -3,7 +3,7 @@ const EPSILON = 1e-10;
3
3
  /**
4
4
  * NxN matrix Householder reduction to upper Hessenberg form via similarity
5
5
  * transformations. After this routine, `a[c*n + r] == 0` for every `r > c+1`
6
- * — i.e. only the main diagonal and the first sub-diagonal carry nonzeros
6
+ * — i.e. only the main diagonal and the first sub-diagonal carry non-zeros
7
7
  * below the diagonal.
8
8
  *
9
9
  * Inner loops are arranged so the hot accesses stream one column at a time
@@ -11,7 +11,7 @@ const EPSILON = 1e-10;
11
11
  *
12
12
  * @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
13
13
  * @param {number[]|Float64Array} a Square matrix, column-major flat layout (a[j*n + i] = row i, col j); modified in place
14
- * @param {number} n
14
+ * @param {number} n matrix size (e.g. 4 for 4x4 matrix)
15
15
  */
16
16
  export function matrix_householder_in_place(a, n) {
17
17
  const u = new Float64Array(n);