@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.
- package/package.json +2 -1
- package/src/core/collection/PairUint32Map.d.ts +100 -0
- package/src/core/collection/PairUint32Map.d.ts.map +1 -0
- package/src/core/collection/PairUint32Map.js +321 -0
- package/src/core/collection/Uint32Map.d.ts +119 -0
- package/src/core/collection/Uint32Map.d.ts.map +1 -0
- package/src/core/collection/Uint32Map.js +345 -0
- package/src/core/collection/array/array_shuffle.d.ts +10 -3
- package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
- package/src/core/collection/array/array_shuffle.js +27 -22
- package/src/core/collection/heap/FibonacciHeap.d.ts +195 -0
- package/src/core/collection/heap/FibonacciHeap.d.ts.map +1 -0
- package/src/core/collection/heap/FibonacciHeap.js +586 -0
- package/src/core/collection/heap/Uint32Heap.js +1 -1
- package/src/core/collection/heap/Uint32Heap4.d.ts +169 -0
- package/src/core/collection/heap/Uint32Heap4.d.ts.map +1 -0
- package/src/core/collection/heap/Uint32Heap4.js +490 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts +27 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts.map +1 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +88 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts +61 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/BoxShape3D.js +158 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +11 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CapsuleShape3D.js +12 -0
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts +37 -9
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -98
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts +10 -0
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitSphereShape3D.js +11 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts +61 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +148 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts +39 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +147 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts +15 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +22 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts +2 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +673 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts +26 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +222 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts +34 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts +36 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts +33 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts +68 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +365 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +31 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +112 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +22 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +55 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts +32 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +49 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +134 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +276 -3
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +17 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +135 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts +14 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +177 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +20 -4
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +5 -3
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +9 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -45
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.js +7 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts +8 -6
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +8 -6
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +73 -0
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +51 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts +10 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts +28 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +227 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts +13 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts +11 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +20 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts +20 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +38 -0
- package/src/core/graph/csr/CSRGraph.d.ts +168 -0
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -0
- package/src/core/graph/csr/CSRGraph.js +319 -0
- package/src/core/graph/metis/cluster_mesh_metis.d.ts +12 -0
- package/src/core/graph/metis/cluster_mesh_metis.d.ts.map +1 -1
- package/src/core/graph/metis/cluster_mesh_metis.js +12 -0
- package/src/core/graph/metis/metis.d.ts +19 -0
- package/src/core/graph/metis/metis.d.ts.map +1 -1
- package/src/core/graph/metis/metis.js +20 -0
- package/src/core/graph/metis/metis_cluster_bs.d.ts +11 -0
- package/src/core/graph/metis/metis_cluster_bs.d.ts.map +1 -1
- package/src/core/graph/metis/metis_cluster_bs.js +11 -0
- package/src/core/graph/metis/metis_options.d.ts +17 -2
- package/src/core/graph/metis/metis_options.d.ts.map +1 -1
- package/src/core/graph/metis/metis_options.js +17 -2
- package/src/core/graph/metis/native/MetisGraph.d.ts +144 -0
- package/src/core/graph/metis/native/MetisGraph.d.ts.map +1 -0
- package/src/core/graph/metis/native/MetisGraph.js +212 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts +72 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.js +101 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.d.ts +37 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts +15 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.js +84 -0
- package/src/core/graph/metis/native/bisection/fm_2way.d.ts +30 -0
- package/src/core/graph/metis/native/bisection/fm_2way.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/fm_2way.js +290 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.d.ts +23 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts +28 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts +20 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts +24 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -0
- package/src/core/graph/metis/native/coarsen/match_shem.d.ts +41 -0
- package/src/core/graph/metis/native/coarsen/match_shem.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/match_shem.js +175 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts +24 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts.map +1 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts +29 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts.map +1 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -0
- package/src/core/graph/metis/native/metis_partition_kway.d.ts +41 -0
- package/src/core/graph/metis/native/metis_partition_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/metis_partition_kway.js +126 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts +62 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.js +261 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts +45 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.d.ts +18 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.js +138 -0
- package/src/core/graph/metis/native/refine/fm_kway.d.ts +63 -0
- package/src/core/graph/metis/native/refine/fm_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/fm_kway.js +462 -0
- package/src/core/graph/metis/native/refine/project_kway.d.ts +22 -0
- package/src/core/graph/metis/native/refine/project_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/project_kway.js +43 -0
- package/src/core/graph/metis/native/refine/refine_kway.d.ts +34 -0
- package/src/core/graph/metis/native/refine/refine_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/refine_kway.js +43 -0
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts +2 -2
- package/src/core/math/linalg/eigen/matrix_householder_in_place.js +2 -2
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +6 -4
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_qr_in_place.js +69 -23
- package/src/engine/EngineHarness.d.ts +3 -1
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +6 -4
- package/src/engine/control/first-person/DESIGN.md +30 -6
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +102 -9
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.js +38 -3
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +533 -4
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +315 -6
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +220 -22
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +858 -241
- package/src/engine/control/first-person/TODO.md +127 -0
- package/src/engine/control/first-person/abilities/Ability.d.ts +101 -0
- package/src/engine/control/first-person/abilities/Ability.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Ability.js +119 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts +86 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/AbilitySet.js +185 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +62 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.js +199 -0
- package/src/engine/control/first-person/abilities/Mantle.d.ts +45 -0
- package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Mantle.js +188 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts +33 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Slide.js +158 -0
- package/src/engine/control/first-person/abilities/WallJump.d.ts +45 -0
- package/src/engine/control/first-person/abilities/WallJump.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/WallJump.js +131 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts +44 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/WallRun.js +180 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts +49 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts.map +1 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.js +60 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts +100 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.js +133 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.d.ts +10 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts +61 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.js +109 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts +40 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.js +45 -0
- package/src/engine/control/first-person/mastery/MasteryScore.d.ts +68 -0
- package/src/engine/control/first-person/mastery/MasteryScore.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasteryScore.js +100 -0
- package/src/engine/control/first-person/mastery/MasterySet.d.ts +60 -0
- package/src/engine/control/first-person/mastery/MasterySet.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasterySet.js +86 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +58 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +83 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +69 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +109 -0
- package/src/engine/control/first-person/math/Spring.d.ts +56 -0
- package/src/engine/control/first-person/math/Spring.d.ts.map +1 -0
- package/src/engine/control/first-person/math/Spring.js +71 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts +26 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts.map +1 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -0
- package/src/engine/control/first-person/math/computeMassRatios.d.ts +35 -0
- package/src/engine/control/first-person/math/computeMassRatios.d.ts.map +1 -0
- package/src/engine/control/first-person/math/computeMassRatios.js +44 -0
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts +31 -1
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts.map +1 -1
- package/src/engine/control/first-person/pose/FirstPersonPose.js +49 -3
- package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts +7 -0
- package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts.map +1 -0
- package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -0
- package/src/engine/control/first-person/prototype_first_person_controller.js +550 -119
- package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +58 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensors.js +77 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +80 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +196 -0
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts +20 -0
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -0
- package/src/engine/control/first-person/test/buildTestPlayer.js +28 -0
- package/src/engine/ecs/EntityManager.d.ts +2 -2
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +13 -8
- package/src/engine/ecs/System.d.ts.map +1 -1
- package/src/engine/ecs/System.js +2 -2
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -2
- package/src/engine/graphics/ecs/light/Light.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/Light.js +27 -0
- package/src/engine/graphics/ecs/light/LightSystem.js +1 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +0 -2
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -2
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -2
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -2
- package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts.map +1 -1
- package/src/engine/navigation/grid/find_path_on_grid_astar.js +11 -2
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -1
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +11 -1
- package/src/engine/physics/PLAN.md +236 -0
- package/src/engine/physics/body/BodyStorage.d.ts +187 -0
- package/src/engine/physics/body/BodyStorage.d.ts.map +1 -0
- package/src/engine/physics/body/BodyStorage.js +427 -0
- package/src/engine/physics/broadphase/PairList.d.ts +62 -0
- package/src/engine/physics/broadphase/PairList.d.ts.map +1 -0
- package/src/engine/physics/broadphase/PairList.js +97 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts +30 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +1 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.js +93 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +16 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +61 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts +38 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -0
- package/src/engine/physics/broadphase/generate_pairs.js +101 -0
- package/src/engine/physics/contact/ManifoldStore.d.ts +226 -0
- package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -0
- package/src/engine/physics/contact/ManifoldStore.js +499 -0
- package/src/engine/physics/ecs/BodyKind.d.ts +23 -0
- package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -0
- package/src/engine/physics/ecs/BodyKind.js +24 -0
- package/src/engine/physics/ecs/Collider.d.ts +98 -0
- package/src/engine/physics/ecs/Collider.d.ts.map +1 -0
- package/src/engine/physics/ecs/Collider.js +136 -0
- package/src/engine/physics/ecs/ColliderFlags.d.ts +14 -0
- package/src/engine/physics/ecs/ColliderFlags.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderFlags.js +15 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +58 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.js +103 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts +25 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -0
- package/src/engine/physics/ecs/PhysicsEvents.d.ts +15 -0
- package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -0
- package/src/engine/physics/ecs/PhysicsEvents.js +16 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +520 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/PhysicsSystem.js +1159 -0
- package/src/engine/physics/ecs/RigidBody.d.ts +197 -0
- package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBody.js +240 -0
- package/src/engine/physics/ecs/RigidBodyFlags.d.ts +21 -0
- package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBodyFlags.js +22 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +28 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +81 -0
- package/src/engine/physics/ecs/SleepState.d.ts +11 -0
- package/src/engine/physics/ecs/SleepState.d.ts.map +1 -0
- package/src/engine/physics/ecs/SleepState.js +12 -0
- package/src/engine/physics/events/ContactEventBuffer.d.ts +46 -0
- package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -0
- package/src/engine/physics/events/ContactEventBuffer.js +83 -0
- package/src/engine/physics/events/diff_manifolds.d.ts +25 -0
- package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -0
- package/src/engine/physics/events/diff_manifolds.js +50 -0
- package/src/engine/physics/fluid/FluidField.d.ts +294 -16
- package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidField.js +510 -66
- package/src/engine/physics/fluid/FluidSimulator.d.ts +188 -5
- package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidSimulator.js +455 -95
- package/src/engine/physics/fluid/SliceVisualiser.d.ts +29 -6
- package/src/engine/physics/fluid/SliceVisualiser.d.ts.map +1 -1
- package/src/engine/physics/fluid/SliceVisualiser.js +190 -165
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +154 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.js +238 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +45 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +107 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.js +278 -0
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +62 -1
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -6
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +17 -4
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +105 -12
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +43 -0
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -0
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +210 -0
- package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +62 -1
- package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/WakeFluidEffector.js +302 -8
- package/src/engine/physics/fluid/prototype.js +102 -91
- package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts +33 -0
- package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/optimal_sor_omega.js +41 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +20 -5
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +60 -38
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +25 -4
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +93 -73
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts +23 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.js +60 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts +23 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.js +68 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +30 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +66 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts +26 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts +30 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +49 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +126 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +93 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +424 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +20 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +83 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +26 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +70 -0
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
- package/src/engine/physics/gjk/expanding_polytope_algorithm.js +8 -10
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +29 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -0
- package/src/engine/physics/inertia/world_inverse_inertia.js +79 -0
- package/src/engine/physics/integration/integrate_position.d.ts +16 -0
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -0
- package/src/engine/physics/integration/integrate_position.js +48 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts +25 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -0
- package/src/engine/physics/integration/integrate_velocity.js +79 -0
- package/src/engine/physics/integration/quat_integrate.d.ts +27 -0
- package/src/engine/physics/integration/quat_integrate.d.ts.map +1 -0
- package/src/engine/physics/integration/quat_integrate.js +62 -0
- package/src/engine/physics/island/IslandBuilder.d.ts +167 -0
- package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -0
- package/src/engine/physics/island/IslandBuilder.js +411 -0
- package/src/engine/physics/island/union_find.d.ts +51 -0
- package/src/engine/physics/island/union_find.d.ts.map +1 -0
- package/src/engine/physics/island/union_find.js +76 -0
- package/src/engine/physics/narrowphase/PosedShape.d.ts +59 -0
- package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/PosedShape.js +110 -0
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts +32 -0
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/box_box_manifold.js +543 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts +122 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/capsule_contacts.js +508 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts +11 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/narrowphase_step.js +382 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts +38 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.js +130 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts +26 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.js +51 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts +83 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts.map +1 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.js +100 -0
- package/src/engine/physics/queries/raycast.d.ts +20 -0
- package/src/engine/physics/queries/raycast.d.ts.map +1 -0
- package/src/engine/physics/queries/raycast.js +249 -0
- package/src/engine/physics/solver/friction_cone.d.ts +16 -0
- package/src/engine/physics/solver/friction_cone.d.ts.map +1 -0
- package/src/engine/physics/solver/friction_cone.js +37 -0
- package/src/engine/physics/solver/solve_contacts.d.ts +36 -0
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -0
- package/src/engine/physics/solver/solve_contacts.js +598 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts +0 -34
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.js +0 -66
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.js +0 -54
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.js +0 -26
- package/src/engine/ecs/components/Motion.d.ts +0 -21
- package/src/engine/ecs/components/Motion.d.ts.map +0 -1
- package/src/engine/ecs/components/Motion.js +0 -27
- package/src/engine/ecs/components/MotionSerializationAdapter.d.ts +0 -20
- package/src/engine/ecs/components/MotionSerializationAdapter.d.ts.map +0 -1
- package/src/engine/ecs/components/MotionSerializationAdapter.js +0 -26
- package/src/engine/ecs/systems/MotionSystem.d.ts +0 -9
- package/src/engine/ecs/systems/MotionSystem.d.ts.map +0 -1
- package/src/engine/ecs/systems/MotionSystem.js +0 -29
- package/src/engine/physics/fluid/Fluid.d.ts +0 -26
- package/src/engine/physics/fluid/Fluid.d.ts.map +0 -1
- package/src/engine/physics/fluid/Fluid.js +0 -221
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts +0 -7
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.js +0 -8
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 2-way Fiduccia–Mattheyses cut refinement (single-constraint, cut objective).
|
|
3
|
+
*
|
|
4
|
+
* Maintains two max-heaps keyed by per-vertex gain (`external_degree − internal_degree`),
|
|
5
|
+
* one per side of the bisection. Each pass:
|
|
6
|
+
* 1. Insert every boundary vertex into the queue for its current side.
|
|
7
|
+
* 2. Repeatedly pop from whichever side is more overweight, move the vertex,
|
|
8
|
+
* and update neighbours. Track running cut and remember the best snapshot.
|
|
9
|
+
* 3. Stop when both queues drain, or when `LIMIT_NONIMPROVING_MOVES` moves
|
|
10
|
+
* pass without finding a better cut.
|
|
11
|
+
* 4. Roll back any moves made after the best-cut snapshot.
|
|
12
|
+
*
|
|
13
|
+
* Each vertex is locked after moving once (it can't move back in the same pass).
|
|
14
|
+
* Locking is reset between passes.
|
|
15
|
+
*
|
|
16
|
+
* Mirrors `FM_2WayCutRefine` from libmetis/fm.c.
|
|
17
|
+
*
|
|
18
|
+
* All scratch state (heaps, moved-index, swap history, insertion order) is
|
|
19
|
+
* shared via the `BisectionScratch` passed in by the caller, sized to the
|
|
20
|
+
* coarsest graph's vertex_count. This eliminates per-trial allocation.
|
|
21
|
+
*
|
|
22
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph
|
|
23
|
+
* @param {number} target_weight_for_partition_0
|
|
24
|
+
* @param {number} pass_count
|
|
25
|
+
* @param {function():number} random seeded RNG used to shuffle boundary
|
|
26
|
+
* insertion order so ties break differently each pass
|
|
27
|
+
* @param {import('./BisectionScratch.js').BisectionScratch} scratch
|
|
28
|
+
*/
|
|
29
|
+
export function fm_2way(graph, target_weight_for_partition_0, pass_count, random, scratch) {
|
|
30
|
+
const vertex_count = graph.vertex_count;
|
|
31
|
+
const edge_addresses = graph.edge_addresses;
|
|
32
|
+
const adjacency = graph.adjacency;
|
|
33
|
+
const edge_weights = graph.edge_weights;
|
|
34
|
+
const vertex_weights = graph.vertex_weights;
|
|
35
|
+
const vertex_partition = graph.vertex_partition;
|
|
36
|
+
const partition_weights = graph.partition_weights;
|
|
37
|
+
const internal_degree = graph.internal_degree;
|
|
38
|
+
const external_degree = graph.external_degree;
|
|
39
|
+
const boundary_vertices = graph.boundary_vertices;
|
|
40
|
+
const boundary_position_of_vertex = graph.boundary_position_of_vertex;
|
|
41
|
+
|
|
42
|
+
if (vertex_count === 0 || graph.boundary_count === 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const target_weight_0 = target_weight_for_partition_0;
|
|
47
|
+
const target_weight_1 = graph.total_vertex_weight - target_weight_for_partition_0;
|
|
48
|
+
|
|
49
|
+
// METIS heuristic: stop a pass after this many moves with no improvement.
|
|
50
|
+
const limit_nonimproving_moves = Math.min(Math.max(Math.floor(0.01 * vertex_count), 15), 100);
|
|
51
|
+
|
|
52
|
+
// METIS uses this for a "close enough to mincut" tolerance when picking
|
|
53
|
+
// the best snapshot — avoids overreacting to small noise in pwgt-balance.
|
|
54
|
+
const avg_vertex_weight = Math.min(
|
|
55
|
+
Math.floor((partition_weights[0] + partition_weights[1]) / 20),
|
|
56
|
+
Math.floor(2 * (partition_weights[0] + partition_weights[1]) / vertex_count)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const queues = scratch.fm_heaps;
|
|
60
|
+
const moved_pass_index = scratch.fm_moved_pass_index;
|
|
61
|
+
const swap_history = scratch.fm_swap_history;
|
|
62
|
+
const insertion_order = scratch.fm_insertion_order;
|
|
63
|
+
|
|
64
|
+
const initial_partition_0_diff = Math.abs(target_weight_0 - partition_weights[0]);
|
|
65
|
+
|
|
66
|
+
for (let pass = 0; pass < pass_count; pass++) {
|
|
67
|
+
queues[0].clear();
|
|
68
|
+
queues[1].clear();
|
|
69
|
+
|
|
70
|
+
let best_cut = graph.current_cut;
|
|
71
|
+
let best_partition_diff = Math.abs(target_weight_0 - partition_weights[0]);
|
|
72
|
+
let best_cut_swap_index = -1;
|
|
73
|
+
let running_cut = best_cut;
|
|
74
|
+
let initial_cut_this_pass = best_cut;
|
|
75
|
+
|
|
76
|
+
let boundary_count = graph.boundary_count;
|
|
77
|
+
|
|
78
|
+
// Insert boundary vertices in random order so ties break differently each pass.
|
|
79
|
+
for (let i = 0; i < boundary_count; i++) {
|
|
80
|
+
insertion_order[i] = i;
|
|
81
|
+
}
|
|
82
|
+
// Fisher–Yates shuffle of insertion_order[0..boundary_count)
|
|
83
|
+
for (let i = boundary_count - 1; i > 0; i--) {
|
|
84
|
+
const j = (random() * (i + 1)) | 0;
|
|
85
|
+
if (j !== i) {
|
|
86
|
+
const tmp = insertion_order[i];
|
|
87
|
+
insertion_order[i] = insertion_order[j];
|
|
88
|
+
insertion_order[j] = tmp;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (let i = 0; i < boundary_count; i++) {
|
|
92
|
+
const vertex = boundary_vertices[insertion_order[i]];
|
|
93
|
+
const gain = external_degree[vertex] - internal_degree[vertex];
|
|
94
|
+
queues[vertex_partition[vertex]].insert(vertex, gain);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let swap_count = 0;
|
|
98
|
+
for (; swap_count < vertex_count; swap_count++) {
|
|
99
|
+
// Pick the side that's more overweight (or equivalently, more under-target).
|
|
100
|
+
const from_side = (target_weight_0 - partition_weights[0]) < (target_weight_1 - partition_weights[1]) ? 0 : 1;
|
|
101
|
+
const to_side = 1 - from_side;
|
|
102
|
+
|
|
103
|
+
const high_gain_vertex = queues[from_side].pop_max();
|
|
104
|
+
if (high_gain_vertex === -1) {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const gain = external_degree[high_gain_vertex] - internal_degree[high_gain_vertex];
|
|
109
|
+
running_cut -= gain;
|
|
110
|
+
|
|
111
|
+
partition_weights[from_side] -= vertex_weights[high_gain_vertex];
|
|
112
|
+
partition_weights[to_side] += vertex_weights[high_gain_vertex];
|
|
113
|
+
|
|
114
|
+
const new_partition_diff = Math.abs(target_weight_0 - partition_weights[0]);
|
|
115
|
+
|
|
116
|
+
const improves_cut_within_balance = (
|
|
117
|
+
running_cut < best_cut &&
|
|
118
|
+
new_partition_diff <= initial_partition_0_diff + avg_vertex_weight
|
|
119
|
+
);
|
|
120
|
+
const matches_cut_but_better_balance = (
|
|
121
|
+
running_cut === best_cut &&
|
|
122
|
+
new_partition_diff < best_partition_diff
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
if (improves_cut_within_balance || matches_cut_but_better_balance) {
|
|
126
|
+
best_cut = running_cut;
|
|
127
|
+
best_partition_diff = new_partition_diff;
|
|
128
|
+
best_cut_swap_index = swap_count;
|
|
129
|
+
} else if (swap_count - best_cut_swap_index > limit_nonimproving_moves) {
|
|
130
|
+
// Pass has gone too long without improvement — undo this last move and stop.
|
|
131
|
+
running_cut += gain;
|
|
132
|
+
partition_weights[from_side] += vertex_weights[high_gain_vertex];
|
|
133
|
+
partition_weights[to_side] -= vertex_weights[high_gain_vertex];
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
vertex_partition[high_gain_vertex] = to_side;
|
|
138
|
+
moved_pass_index[high_gain_vertex] = swap_count;
|
|
139
|
+
swap_history[swap_count] = high_gain_vertex;
|
|
140
|
+
|
|
141
|
+
// After the move, swap id/ed for the moved vertex:
|
|
142
|
+
// edges that used to be external (going to `to_side`) are now internal,
|
|
143
|
+
// and vice versa.
|
|
144
|
+
{
|
|
145
|
+
const tmp = internal_degree[high_gain_vertex];
|
|
146
|
+
internal_degree[high_gain_vertex] = external_degree[high_gain_vertex];
|
|
147
|
+
external_degree[high_gain_vertex] = tmp;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Maybe drop the moved vertex from the boundary.
|
|
151
|
+
if (external_degree[high_gain_vertex] === 0 && edge_addresses[high_gain_vertex] < edge_addresses[high_gain_vertex + 1]) {
|
|
152
|
+
const bp = boundary_position_of_vertex[high_gain_vertex];
|
|
153
|
+
if (bp !== -1) {
|
|
154
|
+
const last = boundary_count - 1;
|
|
155
|
+
if (bp !== last) {
|
|
156
|
+
const moved_to_bp = boundary_vertices[last];
|
|
157
|
+
boundary_vertices[bp] = moved_to_bp;
|
|
158
|
+
boundary_position_of_vertex[moved_to_bp] = bp;
|
|
159
|
+
}
|
|
160
|
+
boundary_position_of_vertex[high_gain_vertex] = -1;
|
|
161
|
+
boundary_count = last;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Update id/ed of neighbours, their boundary membership, and their queue positions.
|
|
166
|
+
const edge_start = edge_addresses[high_gain_vertex];
|
|
167
|
+
const edge_end = edge_addresses[high_gain_vertex + 1];
|
|
168
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
169
|
+
const neighbor = adjacency[edge_offset];
|
|
170
|
+
const ewgt = edge_weights[edge_offset];
|
|
171
|
+
const signed_ewgt = (to_side === vertex_partition[neighbor]) ? ewgt : -ewgt;
|
|
172
|
+
internal_degree[neighbor] += signed_ewgt;
|
|
173
|
+
external_degree[neighbor] -= signed_ewgt;
|
|
174
|
+
|
|
175
|
+
const n_was_on_boundary = boundary_position_of_vertex[neighbor] !== -1;
|
|
176
|
+
|
|
177
|
+
if (n_was_on_boundary) {
|
|
178
|
+
if (external_degree[neighbor] === 0) {
|
|
179
|
+
// Drop from boundary
|
|
180
|
+
const bp = boundary_position_of_vertex[neighbor];
|
|
181
|
+
const last = boundary_count - 1;
|
|
182
|
+
if (bp !== last) {
|
|
183
|
+
const moved_to_bp = boundary_vertices[last];
|
|
184
|
+
boundary_vertices[bp] = moved_to_bp;
|
|
185
|
+
boundary_position_of_vertex[moved_to_bp] = bp;
|
|
186
|
+
}
|
|
187
|
+
boundary_position_of_vertex[neighbor] = -1;
|
|
188
|
+
boundary_count = last;
|
|
189
|
+
if (moved_pass_index[neighbor] === -1) {
|
|
190
|
+
queues[vertex_partition[neighbor]].remove(neighbor);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
// Still on boundary, update queue priority
|
|
194
|
+
if (moved_pass_index[neighbor] === -1) {
|
|
195
|
+
const updated_gain = external_degree[neighbor] - internal_degree[neighbor];
|
|
196
|
+
queues[vertex_partition[neighbor]].update(neighbor, updated_gain);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
if (external_degree[neighbor] > 0) {
|
|
201
|
+
// New boundary vertex
|
|
202
|
+
boundary_vertices[boundary_count] = neighbor;
|
|
203
|
+
boundary_position_of_vertex[neighbor] = boundary_count;
|
|
204
|
+
boundary_count++;
|
|
205
|
+
if (moved_pass_index[neighbor] === -1) {
|
|
206
|
+
const initial_gain = external_degree[neighbor] - internal_degree[neighbor];
|
|
207
|
+
queues[vertex_partition[neighbor]].insert(neighbor, initial_gain);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Reset moved-status for vertices we touched this pass. Preserves the
|
|
215
|
+
// "all -1" invariant for the shared moved_pass_index across calls.
|
|
216
|
+
for (let i = 0; i < swap_count; i++) {
|
|
217
|
+
moved_pass_index[swap_history[i]] = -1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Roll back any moves made after best_cut_swap_index.
|
|
221
|
+
for (let i = swap_count - 1; i > best_cut_swap_index; i--) {
|
|
222
|
+
const vertex = swap_history[i];
|
|
223
|
+
const flipped_from = vertex_partition[vertex];
|
|
224
|
+
const flipped_to = 1 - flipped_from;
|
|
225
|
+
vertex_partition[vertex] = flipped_to;
|
|
226
|
+
|
|
227
|
+
// Swap id/ed back
|
|
228
|
+
{
|
|
229
|
+
const tmp = internal_degree[vertex];
|
|
230
|
+
internal_degree[vertex] = external_degree[vertex];
|
|
231
|
+
external_degree[vertex] = tmp;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Maybe re-add or remove from boundary based on new ed
|
|
235
|
+
if (external_degree[vertex] === 0 && boundary_position_of_vertex[vertex] !== -1 && edge_addresses[vertex] < edge_addresses[vertex + 1]) {
|
|
236
|
+
const bp = boundary_position_of_vertex[vertex];
|
|
237
|
+
const last = boundary_count - 1;
|
|
238
|
+
if (bp !== last) {
|
|
239
|
+
const moved_to_bp = boundary_vertices[last];
|
|
240
|
+
boundary_vertices[bp] = moved_to_bp;
|
|
241
|
+
boundary_position_of_vertex[moved_to_bp] = bp;
|
|
242
|
+
}
|
|
243
|
+
boundary_position_of_vertex[vertex] = -1;
|
|
244
|
+
boundary_count = last;
|
|
245
|
+
} else if (external_degree[vertex] > 0 && boundary_position_of_vertex[vertex] === -1) {
|
|
246
|
+
boundary_vertices[boundary_count] = vertex;
|
|
247
|
+
boundary_position_of_vertex[vertex] = boundary_count;
|
|
248
|
+
boundary_count++;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
partition_weights[flipped_from] -= vertex_weights[vertex];
|
|
252
|
+
partition_weights[flipped_to] += vertex_weights[vertex];
|
|
253
|
+
|
|
254
|
+
// Update neighbours
|
|
255
|
+
const edge_start = edge_addresses[vertex];
|
|
256
|
+
const edge_end = edge_addresses[vertex + 1];
|
|
257
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
258
|
+
const neighbor = adjacency[edge_offset];
|
|
259
|
+
const ewgt = edge_weights[edge_offset];
|
|
260
|
+
const signed_ewgt = (flipped_to === vertex_partition[neighbor]) ? ewgt : -ewgt;
|
|
261
|
+
internal_degree[neighbor] += signed_ewgt;
|
|
262
|
+
external_degree[neighbor] -= signed_ewgt;
|
|
263
|
+
|
|
264
|
+
if (boundary_position_of_vertex[neighbor] !== -1 && external_degree[neighbor] === 0) {
|
|
265
|
+
const bp = boundary_position_of_vertex[neighbor];
|
|
266
|
+
const last = boundary_count - 1;
|
|
267
|
+
if (bp !== last) {
|
|
268
|
+
const moved_to_bp = boundary_vertices[last];
|
|
269
|
+
boundary_vertices[bp] = moved_to_bp;
|
|
270
|
+
boundary_position_of_vertex[moved_to_bp] = bp;
|
|
271
|
+
}
|
|
272
|
+
boundary_position_of_vertex[neighbor] = -1;
|
|
273
|
+
boundary_count = last;
|
|
274
|
+
}
|
|
275
|
+
if (boundary_position_of_vertex[neighbor] === -1 && external_degree[neighbor] > 0) {
|
|
276
|
+
boundary_vertices[boundary_count] = neighbor;
|
|
277
|
+
boundary_position_of_vertex[neighbor] = boundary_count;
|
|
278
|
+
boundary_count++;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
graph.current_cut = best_cut;
|
|
284
|
+
graph.boundary_count = boundary_count;
|
|
285
|
+
|
|
286
|
+
if (best_cut_swap_index <= 0 || best_cut === initial_cut_this_pass) {
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initial bisection by BFS growth from a single random seed.
|
|
3
|
+
*
|
|
4
|
+
* All vertices start in partition 1. A random seed is picked, then BFS
|
|
5
|
+
* expansion moves vertices into partition 0 one at a time until partition 0
|
|
6
|
+
* reaches the target weight. Includes METIS's "drain" handling: if popping a
|
|
7
|
+
* vertex would underflow partition 1's minimum weight, skip it and wait for
|
|
8
|
+
* lighter candidates further down the queue.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors `GrowBisection` from libmetis/initpart.c.
|
|
11
|
+
*
|
|
12
|
+
* Writes to `graph.vertex_partition[]`. Caller is responsible for sizing
|
|
13
|
+
* `graph.partition_weights` to 2 entries (which is allocated by the standard
|
|
14
|
+
* `allocate_partition_state(2)` path).
|
|
15
|
+
*
|
|
16
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph
|
|
17
|
+
* @param {number} target_weight_for_partition_0 the bisection target — partition
|
|
18
|
+
* 0 should end up at roughly this weight
|
|
19
|
+
* @param {number} ub_factor load-imbalance factor (e.g. 1.03)
|
|
20
|
+
* @param {function():number} random
|
|
21
|
+
*/
|
|
22
|
+
export function grow_bisection(graph: import('../MetisGraph.js').MetisGraph, target_weight_for_partition_0: number, ub_factor: number, random: () => number): void;
|
|
23
|
+
//# sourceMappingURL=grow_bisection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grow_bisection.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/graph/metis/native/bisection/grow_bisection.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,sCANW,OAAO,kBAAkB,EAAE,UAAU,iCACrC,MAAM,aAEN,MAAM,gBACK,MAAM,QAmH3B"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { randomIntegerBetween } from "../../../../math/random/randomIntegerBetween.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Initial bisection by BFS growth from a single random seed.
|
|
5
|
+
*
|
|
6
|
+
* All vertices start in partition 1. A random seed is picked, then BFS
|
|
7
|
+
* expansion moves vertices into partition 0 one at a time until partition 0
|
|
8
|
+
* reaches the target weight. Includes METIS's "drain" handling: if popping a
|
|
9
|
+
* vertex would underflow partition 1's minimum weight, skip it and wait for
|
|
10
|
+
* lighter candidates further down the queue.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors `GrowBisection` from libmetis/initpart.c.
|
|
13
|
+
*
|
|
14
|
+
* Writes to `graph.vertex_partition[]`. Caller is responsible for sizing
|
|
15
|
+
* `graph.partition_weights` to 2 entries (which is allocated by the standard
|
|
16
|
+
* `allocate_partition_state(2)` path).
|
|
17
|
+
*
|
|
18
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph
|
|
19
|
+
* @param {number} target_weight_for_partition_0 the bisection target — partition
|
|
20
|
+
* 0 should end up at roughly this weight
|
|
21
|
+
* @param {number} ub_factor load-imbalance factor (e.g. 1.03)
|
|
22
|
+
* @param {function():number} random
|
|
23
|
+
*/
|
|
24
|
+
export function grow_bisection(graph, target_weight_for_partition_0, ub_factor, random) {
|
|
25
|
+
const vertex_count = graph.vertex_count;
|
|
26
|
+
const edge_addresses = graph.edge_addresses;
|
|
27
|
+
const adjacency = graph.adjacency;
|
|
28
|
+
const vertex_weights = graph.vertex_weights;
|
|
29
|
+
const total_vertex_weight = graph.total_vertex_weight;
|
|
30
|
+
const vertex_partition = graph.vertex_partition;
|
|
31
|
+
const partition_weights = graph.partition_weights;
|
|
32
|
+
|
|
33
|
+
const partition_1_minimum_weight = Math.floor(
|
|
34
|
+
(total_vertex_weight - target_weight_for_partition_0) / ub_factor
|
|
35
|
+
);
|
|
36
|
+
const partition_1_maximum_weight = Math.ceil(
|
|
37
|
+
(total_vertex_weight - target_weight_for_partition_0) * ub_factor
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Start with everything in partition 1.
|
|
41
|
+
vertex_partition.fill(1);
|
|
42
|
+
partition_weights[0] = 0;
|
|
43
|
+
partition_weights[1] = total_vertex_weight;
|
|
44
|
+
|
|
45
|
+
if (vertex_count === 0) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const bfs_queue = new Uint32Array(vertex_count);
|
|
50
|
+
const touched = new Uint8Array(vertex_count);
|
|
51
|
+
|
|
52
|
+
const seed_vertex = randomIntegerBetween(random, 0, vertex_count - 1);
|
|
53
|
+
bfs_queue[0] = seed_vertex;
|
|
54
|
+
touched[seed_vertex] = 1;
|
|
55
|
+
let queue_head = 0;
|
|
56
|
+
let queue_tail = 1;
|
|
57
|
+
let unclaimed_count = vertex_count - 1;
|
|
58
|
+
let in_drain_mode = false;
|
|
59
|
+
|
|
60
|
+
for (;;) {
|
|
61
|
+
if (queue_head === queue_tail) {
|
|
62
|
+
// BFS frontier exhausted before reaching the target — the graph
|
|
63
|
+
// (or this component of it) is smaller than expected. Either the
|
|
64
|
+
// graph is disconnected, or partition 0 already overflowed its
|
|
65
|
+
// target and entered drain mode permanently.
|
|
66
|
+
if (unclaimed_count === 0 || in_drain_mode) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
// Pick a random unclaimed vertex to seed a new BFS branch.
|
|
70
|
+
let skip = randomIntegerBetween(random, 0, unclaimed_count - 1);
|
|
71
|
+
let chosen = -1;
|
|
72
|
+
for (let candidate = 0; candidate < vertex_count; candidate++) {
|
|
73
|
+
if (touched[candidate] !== 0) continue;
|
|
74
|
+
if (skip === 0) {
|
|
75
|
+
chosen = candidate;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
skip--;
|
|
79
|
+
}
|
|
80
|
+
if (chosen === -1) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
bfs_queue[queue_tail++] = chosen;
|
|
84
|
+
touched[chosen] = 1;
|
|
85
|
+
unclaimed_count--;
|
|
86
|
+
queue_head = queue_tail - 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const vertex = bfs_queue[queue_head++];
|
|
90
|
+
|
|
91
|
+
// Moving this vertex would underflow partition 1's lower bound.
|
|
92
|
+
// METIS calls this "drain mode": skip the vertex and try the next.
|
|
93
|
+
if (partition_weights[0] > 0 && partition_weights[1] - vertex_weights[vertex] < partition_1_minimum_weight) {
|
|
94
|
+
in_drain_mode = true;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
vertex_partition[vertex] = 0;
|
|
99
|
+
partition_weights[0] += vertex_weights[vertex];
|
|
100
|
+
partition_weights[1] -= vertex_weights[vertex];
|
|
101
|
+
|
|
102
|
+
if (partition_weights[1] <= partition_1_maximum_weight) {
|
|
103
|
+
// Partition 1 is at or below the upper bound — partition 0 is full enough.
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
in_drain_mode = false;
|
|
108
|
+
|
|
109
|
+
const edge_start = edge_addresses[vertex];
|
|
110
|
+
const edge_end = edge_addresses[vertex + 1];
|
|
111
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
112
|
+
const neighbor = adjacency[edge_offset];
|
|
113
|
+
if (touched[neighbor] === 0) {
|
|
114
|
+
bfs_queue[queue_tail++] = neighbor;
|
|
115
|
+
touched[neighbor] = 1;
|
|
116
|
+
unclaimed_count--;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Pathological edge cases — make sure both partitions are non-empty so
|
|
122
|
+
// downstream code doesn't choke on a degenerate bisection.
|
|
123
|
+
if (partition_weights[0] === 0) {
|
|
124
|
+
const forced_seed = randomIntegerBetween(random, 0, vertex_count - 1);
|
|
125
|
+
partition_weights[0] += vertex_weights[forced_seed];
|
|
126
|
+
partition_weights[1] -= vertex_weights[forced_seed];
|
|
127
|
+
vertex_partition[forced_seed] = 0;
|
|
128
|
+
}
|
|
129
|
+
if (partition_weights[1] === 0) {
|
|
130
|
+
const forced_seed = randomIntegerBetween(random, 0, vertex_count - 1);
|
|
131
|
+
if (vertex_partition[forced_seed] === 0) {
|
|
132
|
+
partition_weights[0] -= vertex_weights[forced_seed];
|
|
133
|
+
partition_weights[1] += vertex_weights[forced_seed];
|
|
134
|
+
vertex_partition[forced_seed] = 1;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a graph and a `vertex_partition[]` containing only 0 and 1, build the
|
|
3
|
+
* two induced subgraphs (one per side) and return them along with vertex-id
|
|
4
|
+
* mappings back to the parent.
|
|
5
|
+
*
|
|
6
|
+
* Each subgraph's CSR contains only the edges with both endpoints on the same
|
|
7
|
+
* side. Cross-edges are dropped — they represent the bisection cut and don't
|
|
8
|
+
* play a role in further recursion.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors `SplitGraphPart` from libmetis/pmetis.c, simplified.
|
|
11
|
+
*
|
|
12
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph fine graph with a 0/1
|
|
13
|
+
* `vertex_partition[]` populated by `grow_bisection` + `fm_2way`
|
|
14
|
+
* @returns {{
|
|
15
|
+
* side_0_subgraph: MetisGraph,
|
|
16
|
+
* side_1_subgraph: MetisGraph,
|
|
17
|
+
* side_0_subgraph_to_parent: Uint32Array,
|
|
18
|
+
* side_1_subgraph_to_parent: Uint32Array,
|
|
19
|
+
* }}
|
|
20
|
+
*/
|
|
21
|
+
export function split_graph_two_way(graph: import('../MetisGraph.js').MetisGraph): {
|
|
22
|
+
side_0_subgraph: MetisGraph;
|
|
23
|
+
side_1_subgraph: MetisGraph;
|
|
24
|
+
side_0_subgraph_to_parent: Uint32Array;
|
|
25
|
+
side_1_subgraph_to_parent: Uint32Array;
|
|
26
|
+
};
|
|
27
|
+
import { MetisGraph } from "../MetisGraph.js";
|
|
28
|
+
//# sourceMappingURL=split_graph_two_way.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split_graph_two_way.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/graph/metis/native/bisection/split_graph_two_way.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,2CATW,OAAO,kBAAkB,EAAE,UAAU;qBAG1B,UAAU;qBACV,UAAU;+BACA,WAAW;+BACX,WAAW;EAmG1C;2BAtH0B,kBAAkB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { MetisGraph } from "../MetisGraph.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Given a graph and a `vertex_partition[]` containing only 0 and 1, build the
|
|
5
|
+
* two induced subgraphs (one per side) and return them along with vertex-id
|
|
6
|
+
* mappings back to the parent.
|
|
7
|
+
*
|
|
8
|
+
* Each subgraph's CSR contains only the edges with both endpoints on the same
|
|
9
|
+
* side. Cross-edges are dropped — they represent the bisection cut and don't
|
|
10
|
+
* play a role in further recursion.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors `SplitGraphPart` from libmetis/pmetis.c, simplified.
|
|
13
|
+
*
|
|
14
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph fine graph with a 0/1
|
|
15
|
+
* `vertex_partition[]` populated by `grow_bisection` + `fm_2way`
|
|
16
|
+
* @returns {{
|
|
17
|
+
* side_0_subgraph: MetisGraph,
|
|
18
|
+
* side_1_subgraph: MetisGraph,
|
|
19
|
+
* side_0_subgraph_to_parent: Uint32Array,
|
|
20
|
+
* side_1_subgraph_to_parent: Uint32Array,
|
|
21
|
+
* }}
|
|
22
|
+
*/
|
|
23
|
+
export function split_graph_two_way(graph) {
|
|
24
|
+
const vertex_count = graph.vertex_count;
|
|
25
|
+
const parent_edge_addresses = graph.edge_addresses;
|
|
26
|
+
const parent_adjacency = graph.adjacency;
|
|
27
|
+
const parent_edge_weights = graph.edge_weights;
|
|
28
|
+
const parent_vertex_weights = graph.vertex_weights;
|
|
29
|
+
const parent_vertex_partition = graph.vertex_partition;
|
|
30
|
+
|
|
31
|
+
// --- Count per-side vertices and assign subgraph-local ids ---
|
|
32
|
+
const parent_to_subgraph = new Uint32Array(vertex_count);
|
|
33
|
+
let side_0_vertex_count = 0;
|
|
34
|
+
let side_1_vertex_count = 0;
|
|
35
|
+
for (let vertex = 0; vertex < vertex_count; vertex++) {
|
|
36
|
+
if (parent_vertex_partition[vertex] === 0) {
|
|
37
|
+
parent_to_subgraph[vertex] = side_0_vertex_count;
|
|
38
|
+
side_0_vertex_count++;
|
|
39
|
+
} else {
|
|
40
|
+
parent_to_subgraph[vertex] = side_1_vertex_count;
|
|
41
|
+
side_1_vertex_count++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// --- Count per-side edges (only edges with both endpoints same side) ---
|
|
46
|
+
let side_0_edge_count = 0;
|
|
47
|
+
let side_1_edge_count = 0;
|
|
48
|
+
for (let vertex = 0; vertex < vertex_count; vertex++) {
|
|
49
|
+
const my_side = parent_vertex_partition[vertex];
|
|
50
|
+
const edge_start = parent_edge_addresses[vertex];
|
|
51
|
+
const edge_end = parent_edge_addresses[vertex + 1];
|
|
52
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
53
|
+
if (parent_vertex_partition[parent_adjacency[edge_offset]] === my_side) {
|
|
54
|
+
if (my_side === 0) {
|
|
55
|
+
side_0_edge_count++;
|
|
56
|
+
} else {
|
|
57
|
+
side_1_edge_count++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// --- Allocate subgraphs and inverse-id maps ---
|
|
64
|
+
const side_0_subgraph = new MetisGraph(side_0_vertex_count, side_0_edge_count);
|
|
65
|
+
const side_1_subgraph = new MetisGraph(side_1_vertex_count, side_1_edge_count);
|
|
66
|
+
|
|
67
|
+
const side_0_subgraph_to_parent = new Uint32Array(side_0_vertex_count);
|
|
68
|
+
const side_1_subgraph_to_parent = new Uint32Array(side_1_vertex_count);
|
|
69
|
+
|
|
70
|
+
// --- Fill the subgraphs ---
|
|
71
|
+
side_0_subgraph.edge_addresses[0] = 0;
|
|
72
|
+
side_1_subgraph.edge_addresses[0] = 0;
|
|
73
|
+
let side_0_cursor = 0;
|
|
74
|
+
let side_1_cursor = 0;
|
|
75
|
+
|
|
76
|
+
for (let vertex = 0; vertex < vertex_count; vertex++) {
|
|
77
|
+
const my_side = parent_vertex_partition[vertex];
|
|
78
|
+
const subgraph_vertex = parent_to_subgraph[vertex];
|
|
79
|
+
|
|
80
|
+
const edge_start = parent_edge_addresses[vertex];
|
|
81
|
+
const edge_end = parent_edge_addresses[vertex + 1];
|
|
82
|
+
|
|
83
|
+
if (my_side === 0) {
|
|
84
|
+
side_0_subgraph_to_parent[subgraph_vertex] = vertex;
|
|
85
|
+
side_0_subgraph.vertex_weights[subgraph_vertex] = parent_vertex_weights[vertex];
|
|
86
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
87
|
+
const neighbor = parent_adjacency[edge_offset];
|
|
88
|
+
if (parent_vertex_partition[neighbor] === 0) {
|
|
89
|
+
side_0_subgraph.adjacency[side_0_cursor] = parent_to_subgraph[neighbor];
|
|
90
|
+
side_0_subgraph.edge_weights[side_0_cursor] = parent_edge_weights[edge_offset];
|
|
91
|
+
side_0_cursor++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
side_0_subgraph.edge_addresses[subgraph_vertex + 1] = side_0_cursor;
|
|
95
|
+
} else {
|
|
96
|
+
side_1_subgraph_to_parent[subgraph_vertex] = vertex;
|
|
97
|
+
side_1_subgraph.vertex_weights[subgraph_vertex] = parent_vertex_weights[vertex];
|
|
98
|
+
for (let edge_offset = edge_start; edge_offset < edge_end; edge_offset++) {
|
|
99
|
+
const neighbor = parent_adjacency[edge_offset];
|
|
100
|
+
if (parent_vertex_partition[neighbor] === 1) {
|
|
101
|
+
side_1_subgraph.adjacency[side_1_cursor] = parent_to_subgraph[neighbor];
|
|
102
|
+
side_1_subgraph.edge_weights[side_1_cursor] = parent_edge_weights[edge_offset];
|
|
103
|
+
side_1_cursor++;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
side_1_subgraph.edge_addresses[subgraph_vertex + 1] = side_1_cursor;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
side_0_subgraph.refresh_total_vertex_weight();
|
|
111
|
+
side_1_subgraph.refresh_total_vertex_weight();
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
side_0_subgraph,
|
|
115
|
+
side_1_subgraph,
|
|
116
|
+
side_0_subgraph_to_parent,
|
|
117
|
+
side_1_subgraph_to_parent
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive the coarsening phase: repeatedly match + contract until the coarsest
|
|
3
|
+
* graph is small enough, or the contraction ratio drops below the threshold.
|
|
4
|
+
*
|
|
5
|
+
* On entry, `graph` is the original finest graph. On return, the result is the
|
|
6
|
+
* coarsest graph; walking `.finer_graph` repeatedly reaches the original.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors `CoarsenGraph` from libmetis/coarsen.c.
|
|
9
|
+
*
|
|
10
|
+
* @param {import('../MetisGraph.js').MetisGraph} graph
|
|
11
|
+
* @param {{random: function():number, coarsen_until_vertex_count: number}} opts
|
|
12
|
+
* `coarsen_until_vertex_count`: stop coarsening once vertex_count drops at or
|
|
13
|
+
* below this. METIS uses `max(vertex_count / (20·log2(nparts)), 30·nparts)`.
|
|
14
|
+
* @returns {import('../MetisGraph.js').MetisGraph} the coarsest graph
|
|
15
|
+
*/
|
|
16
|
+
export function coarsen_graph(graph: import('../MetisGraph.js').MetisGraph, opts: {
|
|
17
|
+
random: () => number;
|
|
18
|
+
coarsen_until_vertex_count: number;
|
|
19
|
+
}): import('../MetisGraph.js').MetisGraph;
|
|
20
|
+
//# sourceMappingURL=coarsen_graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coarsen_graph.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/graph/metis/native/coarsen/coarsen_graph.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;GAcG;AACH,qCANW,OAAO,kBAAkB,EAAE,UAAU;kBACjB,MAAM;gCAA8B,MAAM;IAG5D,OAAO,kBAAkB,EAAE,UAAU,CAgEjD"}
|