@graphty/webgpu-graph-algorithms 0.4.1 → 0.5.1

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 (93) hide show
  1. package/README.md +27 -21
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{context-CRbw2Wyo.js → context-BR7fx3vR.js} +47 -5
  4. package/dist/chunks/context-BR7fx3vR.js.map +1 -0
  5. package/dist/node.js +1 -1
  6. package/dist/src/accelerator.d.ts +15 -12
  7. package/dist/src/accelerator.d.ts.map +1 -1
  8. package/dist/src/accelerator.js +35 -12
  9. package/dist/src/accelerator.js.map +1 -1
  10. package/dist/src/constants.d.ts +47 -0
  11. package/dist/src/constants.d.ts.map +1 -1
  12. package/dist/src/constants.js +47 -0
  13. package/dist/src/constants.js.map +1 -1
  14. package/dist/src/index.d.ts +8 -5
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +9 -5
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/kernel/prelude.d.ts.map +1 -1
  19. package/dist/src/kernel/prelude.js +4 -1
  20. package/dist/src/kernel/prelude.js.map +1 -1
  21. package/dist/src/kernels.d.ts +3 -3
  22. package/dist/src/kernels.d.ts.map +1 -1
  23. package/dist/src/kernels.js +27 -11
  24. package/dist/src/kernels.js.map +1 -1
  25. package/dist/src/layouts/force-simulation.d.ts +3 -1
  26. package/dist/src/layouts/force-simulation.d.ts.map +1 -1
  27. package/dist/src/layouts/force-simulation.js +13 -3
  28. package/dist/src/layouts/force-simulation.js.map +1 -1
  29. package/dist/src/layouts/forceatlas2.d.ts +1 -3
  30. package/dist/src/layouts/forceatlas2.d.ts.map +1 -1
  31. package/dist/src/layouts/forceatlas2.js +2 -191
  32. package/dist/src/layouts/forceatlas2.js.map +1 -1
  33. package/dist/src/layouts/fruchterman-reingold.d.ts +195 -0
  34. package/dist/src/layouts/fruchterman-reingold.d.ts.map +1 -0
  35. package/dist/src/layouts/fruchterman-reingold.js +579 -0
  36. package/dist/src/layouts/fruchterman-reingold.js.map +1 -0
  37. package/dist/src/layouts/model-common.d.ts +102 -0
  38. package/dist/src/layouts/model-common.d.ts.map +1 -0
  39. package/dist/src/layouts/model-common.js +198 -0
  40. package/dist/src/layouts/model-common.js.map +1 -0
  41. package/dist/src/layouts/spring-electrical.d.ts +179 -0
  42. package/dist/src/layouts/spring-electrical.d.ts.map +1 -0
  43. package/dist/src/layouts/spring-electrical.js +508 -0
  44. package/dist/src/layouts/spring-electrical.js.map +1 -0
  45. package/dist/src/types/accelerator.d.ts +14 -157
  46. package/dist/src/types/accelerator.d.ts.map +1 -1
  47. package/dist/src/types/accelerator.js +4 -5
  48. package/dist/src/types/accelerator.js.map +1 -1
  49. package/dist/src/types/algorithms.d.ts +1 -1
  50. package/dist/src/types/algorithms.js +1 -1
  51. package/dist/src/types/layout.d.ts +32 -0
  52. package/dist/src/types/layout.d.ts.map +1 -1
  53. package/dist/src/types/options.d.ts +43 -1
  54. package/dist/src/types/options.d.ts.map +1 -1
  55. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +5 -2
  56. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -1
  57. package/dist/src/wgsl/fa2-attraction.wgsl.js +6 -1
  58. package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -1
  59. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +7 -2
  60. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -1
  61. package/dist/src/wgsl/fa2-integrate.wgsl.js +28 -2
  62. package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -1
  63. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +4 -2
  64. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -1
  65. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +14 -5
  66. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -1
  67. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +8 -1
  68. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -1
  69. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +33 -0
  70. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -1
  71. package/dist/tsconfig.build.tsbuildinfo +1 -1
  72. package/dist/webgpu-graph-algorithms.js +1358 -284
  73. package/dist/webgpu-graph-algorithms.js.map +1 -1
  74. package/package.json +6 -3
  75. package/src/accelerator.ts +49 -14
  76. package/src/constants.ts +70 -0
  77. package/src/index.ts +19 -8
  78. package/src/kernel/prelude.ts +6 -0
  79. package/src/kernels.ts +27 -11
  80. package/src/layouts/force-simulation.ts +20 -3
  81. package/src/layouts/forceatlas2.ts +17 -220
  82. package/src/layouts/fruchterman-reingold.ts +737 -0
  83. package/src/layouts/model-common.ts +228 -0
  84. package/src/layouts/spring-electrical.ts +666 -0
  85. package/src/types/accelerator.ts +58 -174
  86. package/src/types/algorithms.ts +1 -1
  87. package/src/types/layout.ts +36 -0
  88. package/src/types/options.ts +45 -1
  89. package/src/wgsl/fa2-attraction.wgsl.ts +6 -1
  90. package/src/wgsl/fa2-integrate.wgsl.ts +28 -2
  91. package/src/wgsl/fa2-repulsion-exact.wgsl.ts +14 -5
  92. package/src/wgsl/fa2-stats-finalize.wgsl.ts +33 -0
  93. package/dist/chunks/context-CRbw2Wyo.js.map +0 -1
@@ -1,165 +1,18 @@
1
1
  /**
2
- * The layout half of spec 9.3 and the @graphty/algorithms AlgorithmAccelerator mirror (spec 9.2), plus the
3
- * package's own accelerator surface (spec 3.3). D27's two halves are now on different footings: at W1b the LAYOUT
4
- * mirrors became `import type` of the real `@graphty/layout` interfaces, re-exported here so this package's public
5
- * surface is unchanged; the ALGORITHMS mirrors stay structural until A2/M8a gives them something real to point at.
6
- * test/types/conformance.test-d.ts is the cross-compile that holds the layout half honest. Types only.
2
+ * The layout half of spec 9.3 and the algorithms half of spec 9.2, plus the package's own accelerator surface
3
+ * (spec 3.3). D27's mirrors are gone: both halves are now `import type` of the real packages, re-exported here so
4
+ * this package's public surface is unchanged; `test/types/conformance.test-d.ts` is the cross-compile that holds
5
+ * them honest. Types only.
7
6
  */
8
- import type { F32, F64, GraphSnapshot, NumericVector, U32 } from "@graphty/graph-format";
7
+ import type { AlgorithmAccelerator, ApspResultLike, BellmanFordResultLike, BetweennessAcceleratorOptions, BfsResultLike, CommunityResultLike, CorenessResultLike, EdgeScoresResultLike, HitsOptionsLike, HitsResultLike, LabelResultLike, MstResultLike, PageRankResultLike, ScoresResultLike, SsspResultLike } from "@graphty/algorithms";
8
+ import type { F32, F64, GraphSnapshot } from "@graphty/graph-format";
9
9
  import type { LayoutAccelerator, LayoutSimulation } from "@graphty/layout";
10
10
  import type { GpuContext } from "../context.js";
11
11
  import type { ComponentsOptions, EigenvectorOptions, GpuHitsResult, GpuLabelResult, GpuPageRankResult, GpuScoresResult, HitsOptions, KatzOptions, PageRankOptions } from "./algorithms.js";
12
- import type { ForceAtlas2Stats, GpuLayoutSimulation, GpuLayoutTuning } from "./layout.js";
13
- import type { ForceAtlas2Options } from "./options.js";
12
+ import type { ForceAtlas2Stats, FruchtermanReingoldStats, GpuLayoutSimulation, GpuLayoutTuning, SpringElectricalStats } from "./layout.js";
13
+ import type { ForceAtlas2Options, FruchtermanReingoldOptions, SpringElectricalOptions } from "./options.js";
14
14
  export type { LayoutAccelerator, LayoutSimulation };
15
- /**
16
- * Placeholder for the CPU option types the AlgorithmAccelerator methods take before A2 lands (spec 9.2: "the
17
- * accelerator methods reuse the indexed.* option types").
18
- * Exported: published mirror (spec 9.2); re-exported from src/index.ts at P3-T3.
19
- * @public
20
- */
21
- export type CpuAlgorithmOptions = Readonly<Record<string, unknown>>;
22
- /**
23
- * Score-shaped result of the CPU package (spec 9.7).
24
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
25
- * @public
26
- */
27
- export interface ScoresResultLike {
28
- readonly scores: NumericVector;
29
- readonly iterations: number;
30
- readonly converged: boolean;
31
- }
32
- /**
33
- * PageRank result mirror.
34
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
35
- * @public
36
- */
37
- export interface PageRankResultLike extends ScoresResultLike {
38
- readonly danglingMass?: number | undefined;
39
- }
40
- /**
41
- * HITS result mirror.
42
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
43
- * @public
44
- */
45
- export interface HitsResultLike {
46
- readonly hubs: NumericVector;
47
- readonly authorities: NumericVector;
48
- readonly iterations: number;
49
- readonly converged: boolean;
50
- }
51
- /**
52
- * Label result mirror (components, label propagation).
53
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
54
- * @public
55
- */
56
- export interface LabelResultLike {
57
- readonly labels: U32;
58
- readonly count: number;
59
- groups(): U32[];
60
- }
61
- /**
62
- * BFS result mirror.
63
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
64
- * @public
65
- */
66
- export interface BfsResultLike {
67
- readonly depth: U32;
68
- readonly parent: U32;
69
- readonly order: U32;
70
- readonly visitedCount: number;
71
- }
72
- /**
73
- * SSSP result mirror.
74
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
75
- * @public
76
- */
77
- export interface SsspResultLike {
78
- readonly dist: NumericVector;
79
- readonly predArc: U32;
80
- }
81
- /**
82
- * Bellman-Ford result mirror.
83
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
84
- * @public
85
- */
86
- export interface BellmanFordResultLike extends SsspResultLike {
87
- readonly hasNegativeCycle: boolean;
88
- }
89
- /**
90
- * Edge-score result mirror.
91
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
92
- * @public
93
- */
94
- export interface EdgeScoresResultLike {
95
- readonly scores: NumericVector;
96
- }
97
- /**
98
- * APSP result mirror.
99
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
100
- * @public
101
- */
102
- export interface ApspResultLike {
103
- readonly dist: NumericVector;
104
- readonly n: number;
105
- }
106
- /**
107
- * k-core result mirror.
108
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
109
- * @public
110
- */
111
- export interface CorenessResultLike {
112
- readonly coreness: U32;
113
- }
114
- /**
115
- * Minimum-spanning-tree result mirror.
116
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
117
- * @public
118
- */
119
- export interface MstResultLike {
120
- readonly edges: U32;
121
- readonly totalWeight: number;
122
- }
123
- /**
124
- * Community result mirror (Louvain).
125
- * Exported: published mirror; re-exported from src/index.ts at P3-T3.
126
- * @public
127
- */
128
- export interface CommunityResultLike extends LabelResultLike {
129
- readonly modularity: number;
130
- }
131
- /**
132
- * Spec 9.2 AlgorithmAccelerator, verbatim (every member optional; option types are CpuAlgorithmOptions until A2).
133
- * Exported: published mirror (spec 9.2, D27); re-exported from src/index.ts at P3-T3.
134
- * @public
135
- */
136
- export interface AlgorithmAccelerator {
137
- readonly kind: string;
138
- pageRank?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<PageRankResultLike>;
139
- personalizedPageRank?(s: GraphSnapshot, personalization: F32 | F64, options?: CpuAlgorithmOptions): Promise<PageRankResultLike>;
140
- hits?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<HitsResultLike>;
141
- eigenvectorCentrality?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<ScoresResultLike>;
142
- katzCentrality?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<ScoresResultLike>;
143
- connectedComponents?(s: GraphSnapshot): Promise<LabelResultLike>;
144
- weaklyConnectedComponents?(s: GraphSnapshot): Promise<LabelResultLike>;
145
- breadthFirstSearch?(s: GraphSnapshot, source: number, options?: CpuAlgorithmOptions): Promise<BfsResultLike>;
146
- sssp?(s: GraphSnapshot, source: number, options?: CpuAlgorithmOptions): Promise<SsspResultLike>;
147
- bellmanFord?(s: GraphSnapshot, source: number, options?: CpuAlgorithmOptions): Promise<BellmanFordResultLike>;
148
- closenessCentrality?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<ScoresResultLike>;
149
- betweennessCentrality?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<ScoresResultLike>;
150
- edgeBetweennessCentrality?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<EdgeScoresResultLike>;
151
- allPairsShortestPath?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<ApspResultLike>;
152
- kCoreDecomposition?(s: GraphSnapshot): Promise<CorenessResultLike>;
153
- triangleCount?(s: GraphSnapshot): Promise<{
154
- readonly perNode: U32;
155
- readonly total: number;
156
- }>;
157
- labelPropagation?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<LabelResultLike>;
158
- minimumSpanningTree?(s: GraphSnapshot): Promise<MstResultLike>;
159
- louvain?(s: GraphSnapshot, options?: CpuAlgorithmOptions): Promise<CommunityResultLike>;
160
- release?(s: GraphSnapshot): void;
161
- dispose?(): void;
162
- }
15
+ export type { AlgorithmAccelerator, ApspResultLike, BellmanFordResultLike, BetweennessAcceleratorOptions, BfsResultLike, CommunityResultLike, CorenessResultLike, EdgeScoresResultLike, HitsOptionsLike, HitsResultLike, LabelResultLike, MstResultLike, PageRankResultLike, ScoresResultLike, SsspResultLike, };
163
16
  /**
164
17
  * Spec 3.3 AcceleratorOptions, verbatim.
165
18
  * Exported: consumed by src/accelerator.ts (P3-T3); re-exported from src/index.ts at P3-T3.
@@ -175,7 +28,9 @@ export interface AcceleratorOptions {
175
28
  } | undefined;
176
29
  }
177
30
  /**
178
- * The injectable object (spec 3.3): P3's forceAtlas2, release and dispose, plus P7's seven algorithm members
31
+ * The injectable object (spec 3.3): P3's forceAtlas2, release and dispose, P5's fruchtermanReingold and
32
+ * springElectrical (the two other optional members of the real LayoutAccelerator, spec 9.3; the CPU option types in,
33
+ * the GPU simulations out), plus P7's seven algorithm members
179
34
  * (spec 8.2, 8.3; M8b-T8), non-optional here and returning the `Gpu*Result` shapes, which satisfy the `*ResultLike`
180
35
  * mirrors (spec 9.7: `precision` is an extra field, `F32` is a `NumericVector`). `connectedComponents` and
181
36
  * `weaklyConnectedComponents` are the same algorithm (spec 3.3: WCC semantics on directed input) under both names
@@ -189,6 +44,8 @@ export interface GpuAccelerator extends AlgorithmAccelerator, LayoutAccelerator
189
44
  readonly ctx: GpuContext;
190
45
  readonly options: Readonly<AcceleratorOptions>;
191
46
  forceAtlas2(options?: ForceAtlas2Options): GpuLayoutSimulation<ForceAtlas2Options, ForceAtlas2Stats>;
47
+ fruchtermanReingold(options?: FruchtermanReingoldOptions): GpuLayoutSimulation<FruchtermanReingoldOptions, FruchtermanReingoldStats>;
48
+ springElectrical(options?: SpringElectricalOptions): GpuLayoutSimulation<SpringElectricalOptions, SpringElectricalStats>;
192
49
  pageRank(s: GraphSnapshot, options?: PageRankOptions): Promise<GpuPageRankResult>;
193
50
  personalizedPageRank(s: GraphSnapshot, personalization: F32 | F64, options?: PageRankOptions): Promise<GpuPageRankResult>;
194
51
  hits(s: GraphSnapshot, options?: HitsOptions): Promise<GpuHitsResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"accelerator.d.ts","sourceRoot":"","sources":["../../../src/types/accelerator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accelerator.d.ts","sourceRoot":"","sources":["../../../src/types/accelerator.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,8 @@
1
1
  /**
2
- * The layout half of spec 9.3 and the @graphty/algorithms AlgorithmAccelerator mirror (spec 9.2), plus the
3
- * package's own accelerator surface (spec 3.3). D27's two halves are now on different footings: at W1b the LAYOUT
4
- * mirrors became `import type` of the real `@graphty/layout` interfaces, re-exported here so this package's public
5
- * surface is unchanged; the ALGORITHMS mirrors stay structural until A2/M8a gives them something real to point at.
6
- * test/types/conformance.test-d.ts is the cross-compile that holds the layout half honest. Types only.
2
+ * The layout half of spec 9.3 and the algorithms half of spec 9.2, plus the package's own accelerator surface
3
+ * (spec 3.3). D27's mirrors are gone: both halves are now `import type` of the real packages, re-exported here so
4
+ * this package's public surface is unchanged; `test/types/conformance.test-d.ts` is the cross-compile that holds
5
+ * them honest. Types only.
7
6
  */
8
7
  export {};
9
8
  //# sourceMappingURL=accelerator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accelerator.js","sourceRoot":"","sources":["../../../src/types/accelerator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
1
+ {"version":3,"file":"accelerator.js","sourceRoot":"","sources":["../../../src/types/accelerator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -5,7 +5,7 @@
5
5
  * layout options until W1b, when those became `import type` re-exports of `@graphty/layout`'s declarations).
6
6
  * Types only: this file imports nothing at runtime.
7
7
  *
8
- * The CPU counterparts, when phase M8a lands them (plan 2026-09-19-webgpu-m8a-algorithms-seam, Task M8a-T8):
8
+ * The CPU counterparts, in `@graphty/algorithms`' `indexed/accelerator.ts` since the seam landed:
9
9
  * `PageRankOptions` here is `IndexedPageRankOptions` there (`{ dampingFactor?, maxIterations?, tolerance?,
10
10
  * weighted? }`); `HitsOptions`, `EigenvectorOptions` and `KatzOptions` here all correspond to the ONE
11
11
  * `HitsOptionsLike` there (`{ maxIterations?, tolerance?, weighted? }`), which is why every one of them carries
@@ -5,7 +5,7 @@
5
5
  * layout options until W1b, when those became `import type` re-exports of `@graphty/layout`'s declarations).
6
6
  * Types only: this file imports nothing at runtime.
7
7
  *
8
- * The CPU counterparts, when phase M8a lands them (plan 2026-09-19-webgpu-m8a-algorithms-seam, Task M8a-T8):
8
+ * The CPU counterparts, in `@graphty/algorithms`' `indexed/accelerator.ts` since the seam landed:
9
9
  * `PageRankOptions` here is `IndexedPageRankOptions` there (`{ dampingFactor?, maxIterations?, tolerance?,
10
10
  * weighted? }`); `HitsOptions`, `EigenvectorOptions` and `KatzOptions` here all correspond to the ONE
11
11
  * `HitsOptionsLike` there (`{ maxIterations?, tolerance?, weighted? }`), which is why every one of them carries
@@ -37,6 +37,38 @@ export interface ForceAtlas2Stats extends LayoutStatsBase {
37
37
  readonly speedEfficiency: number;
38
38
  readonly trace: ReadonlyArray<ForceAtlas2TraceRecord>;
39
39
  }
40
+ /**
41
+ * One per-iteration trace record of the last completed batch of a Fruchterman-Reingold simulation (spec 3.3
42
+ * FruchtermanReingoldStats.trace element): K1 writes `temperature` from the iteration's uniform slot (spec 7.20).
43
+ * @public
44
+ */
45
+ export interface FruchtermanReingoldTraceRecord {
46
+ readonly temperature: number;
47
+ readonly meanDisplacement: number;
48
+ readonly settledCount: number;
49
+ }
50
+ /** Spec 3.3 FruchtermanReingoldStats, verbatim: the cooling schedule's value replaces the controller fields. */
51
+ export interface FruchtermanReingoldStats extends LayoutStatsBase {
52
+ readonly temperature: number;
53
+ readonly trace: ReadonlyArray<FruchtermanReingoldTraceRecord>;
54
+ }
55
+ /**
56
+ * One per-iteration trace record of the last completed batch of a spring-electrical simulation (spec 3.3
57
+ * SpringElectricalStats.trace element): `kineticEnergy` is `0.5 * sum m |v|^2` over the free nodes after the
58
+ * PREVIOUS iteration's integrate: K5 writes it into partials B and the NEXT iteration's K1 folds it (PD-4), so the
59
+ * first record after load() carries 0 and record i carries the energy of iteration i - 1.
60
+ * @public
61
+ */
62
+ export interface SpringElectricalTraceRecord {
63
+ readonly kineticEnergy: number;
64
+ readonly meanDisplacement: number;
65
+ readonly settledCount: number;
66
+ }
67
+ /** Spec 3.3 SpringElectricalStats, verbatim; `kineticEnergy` is the last folded value, one iteration behind the last integrate (PD-4). */
68
+ export interface SpringElectricalStats extends LayoutStatsBase {
69
+ readonly kineticEnergy: number;
70
+ readonly trace: ReadonlyArray<SpringElectricalTraceRecord>;
71
+ }
40
72
  /** Options of GpuLayoutSimulation.run (spec 3.3). */
41
73
  export interface RunOptions {
42
74
  readonly maxIter?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/types/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,wGAAwG;AACxG,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;CACzD;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC7C;AAED,4GAA4G;AAC5G,MAAM,WAAW,mBAAmB,CAAC,OAAO,EAAE,KAAK,SAAS,eAAe,CAAE,SAAQ,gBAAgB;IACjG,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC;IACpD;;;;;;OAMG;IACH,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,IAAI,IAAI,CAAC;IACf,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,GAAG,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC,CAAC;CAC/D;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;CACtD;AAED,8FAA8F;AAC9F,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;CACzC"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/types/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,wGAAwG;AACxG,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,gHAAgH;AAChH,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC7D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,8BAA8B,CAAC,CAAC;CACjE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,0IAA0I;AAC1I,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC1D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,2BAA2B,CAAC,CAAC;CAC9D;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC7C;AAED,4GAA4G;AAC5G,MAAM,WAAW,mBAAmB,CAAC,OAAO,EAAE,KAAK,SAAS,eAAe,CAAE,SAAQ,gBAAgB;IACjG,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC;IACpD;;;;;;OAMG;IACH,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,IAAI,IAAI,CAAC;IACf,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,GAAG,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC,CAAC;CAC/D;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;CACtD;AAED,8FAA8F;AAC9F,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;CACzC"}
@@ -5,7 +5,7 @@
5
5
  * `ResolvedForceAtlas2Options` below is this package's own and stays local. Types only: nothing here is a runtime
6
6
  * import.
7
7
  */
8
- import type { F32, NodeId } from "@graphty/graph-format";
8
+ import type { F32, NodeId, NodeMask } from "@graphty/graph-format";
9
9
  import type { CommonLayoutOptions, ForceAtlas2Options, FruchtermanReingoldOptions, SimulationOptions, SpringElectricalOptions } from "@graphty/layout";
10
10
  export type { CommonLayoutOptions, ForceAtlas2Options, FruchtermanReingoldOptions, SimulationOptions, SpringElectricalOptions, };
11
11
  /**
@@ -34,4 +34,46 @@ export interface ResolvedForceAtlas2Options {
34
34
  readonly iterationsPerStep: number;
35
35
  readonly maxInFlight: number;
36
36
  }
37
+ /**
38
+ * The resolved (defaults applied) Fruchterman-Reingold option record (spec 7.20, 9.3): `k` null means `1 / sqrt(n)`
39
+ * at load; `fixed` is applied at load through ModelInputs.fixed (PD-6). Exported for src/layouts/fruchterman-reingold.ts
40
+ * and the option tests.
41
+ * @public
42
+ */
43
+ export interface ResolvedFruchtermanReingoldOptions {
44
+ readonly k: number | null;
45
+ readonly iterations: number;
46
+ readonly cooling: "linear" | "adaptive";
47
+ readonly fixed: NodeMask | string | null;
48
+ readonly dim: 2 | 3;
49
+ readonly scale: number;
50
+ readonly center: readonly [number, number, number];
51
+ readonly seed: number | null;
52
+ readonly settleThreshold: number;
53
+ readonly settleWindow: number;
54
+ readonly iterationsPerStep: number;
55
+ readonly maxInFlight: number;
56
+ }
57
+ /**
58
+ * The resolved spring-electrical option record (spec 7.20, 9.3; ngraph's names): `gravity` is the Coulomb constant
59
+ * (negative repels), never FA2's centre gravity. `gravity` and `springCoefficient` are null when left to their
60
+ * defaults: ngraph's constant scaled by min(1, SE_SCALE_REFERENCE_NODES / n) once n is known at load. Exported for
61
+ * src/layouts/spring-electrical.ts and the option tests.
62
+ * @public
63
+ */
64
+ export interface ResolvedSpringElectricalOptions {
65
+ readonly springLength: number;
66
+ readonly springCoefficient: number | null;
67
+ readonly gravity: number | null;
68
+ readonly dragCoefficient: number;
69
+ readonly timeStep: number;
70
+ readonly dim: 2 | 3;
71
+ readonly scale: number;
72
+ readonly center: readonly [number, number, number];
73
+ readonly seed: number | null;
74
+ readonly settleThreshold: number;
75
+ readonly settleWindow: number;
76
+ readonly iterationsPerStep: number;
77
+ readonly maxInFlight: number;
78
+ }
37
79
  //# sourceMappingURL=options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/types/options.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EACR,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,EAC1B,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EACR,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,GAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/types/options.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EACR,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,EAC1B,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EACR,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,GAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kCAAkC;IAC/C,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC"}
@@ -3,10 +3,13 @@
3
3
  * attraction force over the undirected CSR rows (both arcs present, so the sum is symmetric with no atomics), the
4
4
  * linear or linlog law, the optional weights, the distributed-action division by the mass in `pos.w`, written as
5
5
  * the FIRST writer of `force` each iteration. P3 ships the thread-per-row tier over `[tierStart, tierEnd)` = `[0, n)`
6
- * with `USE_PERM = false`; the subgroup / workgroup tiers arrive with P4 (`TIER`).
6
+ * with `USE_PERM = false`; the subgroup / workgroup tiers arrive with P4 (`TIER`). `LAW` (P5, spec 7.20) picks the
7
+ * pair law: 0 = the FA2 text, 1 = Fruchterman-Reingold `d^2 / k` (unfloored), 2 = ngraph's Hooke spring
8
+ * `k_s (d - L)`; under 1 / 2 the models compile `LINLOG = false` and `HAS_WEIGHTS = false`, and the law overwrites
9
+ * `w` so weights are ignored either way.
7
10
  *
8
11
  * Body only (spec 3.5, D9); normative text (contract 4.5); the K2 sabotage mutations (P3-T5) are textual edits of it.
9
12
  */
10
13
  /** The K2 body: entry point `attraction`; an early return is legal here because no barrier follows (spec 3.5 rule 1). */
11
- export declare const fa2AttractionWgsl = "fn store_force(i: u32, f: vec3f) {\n force[3u * i] = f.x;\n force[3u * i + 1u] = f.y;\n force[3u * i + 2u] = f.z;\n}\n\n@compute @workgroup_size(WG)\nfn attraction(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let row = linear_id(wid, lid.x) + P.tierStart;\n if (row >= P.tierEnd) { return; } // no barrier follows in this tier (3.5 rule 1)\n let i = select(row, perm[row], USE_PERM);\n let pi = pos[i]; // xyz + mass in one load (D23)\n var f = vec3f(0.0);\n for (var a = rowPtr[i]; a < rowPtr[i + 1u]; a = a + 1u) {\n let j = colIdx[a];\n if (j == i) { continue; } // a self-loop exerts no force\n var w = 1.0;\n if (HAS_WEIGHTS) { w = weights[a]; }\n let d = pos[j].xyz - pi.xyz; // toward j\n let len = max(length(d), FA2_DIST_FLOOR);\n let mag = select(w, w * log(1.0 + len) / len, LINLOG); // linear: |F| = w len; linlog: |F| = w log(1 + len)\n f = f + d * mag;\n }\n if (DISTRIBUTED) { f = f / pi.w; }\n store_force(i, f); // overwrites: attraction is the first writer of force each iteration\n}";
14
+ export declare const fa2AttractionWgsl = "fn store_force(i: u32, f: vec3f) {\n force[3u * i] = f.x;\n force[3u * i + 1u] = f.y;\n force[3u * i + 2u] = f.z;\n}\n\n@compute @workgroup_size(WG)\nfn attraction(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let row = linear_id(wid, lid.x) + P.tierStart;\n if (row >= P.tierEnd) { return; } // no barrier follows in this tier (3.5 rule 1)\n let i = select(row, perm[row], USE_PERM);\n let pi = pos[i]; // xyz + mass in one load (D23)\n var f = vec3f(0.0);\n for (var a = rowPtr[i]; a < rowPtr[i + 1u]; a = a + 1u) {\n let j = colIdx[a];\n if (j == i) { continue; } // a self-loop exerts no force\n var w = 1.0;\n if (HAS_WEIGHTS) { w = weights[a]; }\n let d = pos[j].xyz - pi.xyz; // toward j\n let len = max(length(d), FA2_DIST_FLOOR);\n if (LAW == 1u) { w = length(d) / P.frK; } // LAW 1 (FR, 7.20): |F| = d^2 / k along d / d, unfloored; the linear select below applies w as is\n if (LAW == 2u) { w = P.springCoefficient * (len - P.springLength) / len; } // LAW 2 (spring, ngraph generateCreateSpringForce.js:33-36): Hooke k_s (d - L) toward j\n let mag = select(w, w * log(1.0 + len) / len, LINLOG); // linear: |F| = w len; linlog: |F| = w log(1 + len)\n f = f + d * mag;\n }\n if (DISTRIBUTED) { f = f / pi.w; }\n store_force(i, f); // overwrites: attraction is the first writer of force each iteration\n}";
12
15
  //# sourceMappingURL=fa2-attraction.wgsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fa2-attraction.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-attraction.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yHAAyH;AACzH,eAAO,MAAM,iBAAiB,wxCAyB5B,CAAC"}
1
+ {"version":3,"file":"fa2-attraction.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-attraction.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yHAAyH;AACzH,eAAO,MAAM,iBAAiB,0mDA2B5B,CAAC"}
@@ -3,7 +3,10 @@
3
3
  * attraction force over the undirected CSR rows (both arcs present, so the sum is symmetric with no atomics), the
4
4
  * linear or linlog law, the optional weights, the distributed-action division by the mass in `pos.w`, written as
5
5
  * the FIRST writer of `force` each iteration. P3 ships the thread-per-row tier over `[tierStart, tierEnd)` = `[0, n)`
6
- * with `USE_PERM = false`; the subgroup / workgroup tiers arrive with P4 (`TIER`).
6
+ * with `USE_PERM = false`; the subgroup / workgroup tiers arrive with P4 (`TIER`). `LAW` (P5, spec 7.20) picks the
7
+ * pair law: 0 = the FA2 text, 1 = Fruchterman-Reingold `d^2 / k` (unfloored), 2 = ngraph's Hooke spring
8
+ * `k_s (d - L)`; under 1 / 2 the models compile `LINLOG = false` and `HAS_WEIGHTS = false`, and the law overwrites
9
+ * `w` so weights are ignored either way.
7
10
  *
8
11
  * Body only (spec 3.5, D9); normative text (contract 4.5); the K2 sabotage mutations (P3-T5) are textual edits of it.
9
12
  */
@@ -28,6 +31,8 @@ fn attraction(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_i
28
31
  if (HAS_WEIGHTS) { w = weights[a]; }
29
32
  let d = pos[j].xyz - pi.xyz; // toward j
30
33
  let len = max(length(d), FA2_DIST_FLOOR);
34
+ if (LAW == 1u) { w = length(d) / P.frK; } // LAW 1 (FR, 7.20): |F| = d^2 / k along d / d, unfloored; the linear select below applies w as is
35
+ if (LAW == 2u) { w = P.springCoefficient * (len - P.springLength) / len; } // LAW 2 (spring, ngraph generateCreateSpringForce.js:33-36): Hooke k_s (d - L) toward j
31
36
  let mag = select(w, w * log(1.0 + len) / len, LINLOG); // linear: |F| = w len; linlog: |F| = w log(1 + len)
32
37
  f = f + d * mag;
33
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fa2-attraction.wgsl.js","sourceRoot":"","sources":["../../../src/wgsl/fa2-attraction.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yHAAyH;AACzH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAyB1C,CAAC"}
1
+ {"version":3,"file":"fa2-attraction.wgsl.js","sourceRoot":"","sources":["../../../src/wgsl/fa2-attraction.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yHAAyH;AACzH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B1C,CAAC"}
@@ -4,10 +4,15 @@
4
4
  * networkx mode `m |F|`, contract 4.6), the position update with no displacement clamp (D25), z never integrated
5
5
  * in 2D (spec 7.13), `oldForce` stored in paper mode for fixed nodes too (spec 7.11), and the partials A
6
6
  * (sum p, sum |p - c|^2, min, max with max |p - c|^2 in `max.w`) and C (sum |dp| over free rows, free count) in
7
- * uniform control flow.
7
+ * uniform control flow. `APPLY` (P5, spec 7.20) picks the integrator: 0 = the FA2 text, 1 = the Fruchterman-Reingold
8
+ * temperature cap `min(|F|, t)` along F, 2 = ngraph's semi-implicit Euler step with drag and the unit speed clamp
9
+ * over the velocity that lives in the `oldForce` slot (PD-2), which also folds the free kinetic energy into
10
+ * `partials.swingTraction.x` (PD-4); mode 1 folds the free force energy `sum |F|^2` into the same slot for K1's
11
+ * adaptive cooling and takes its temperature from the state block when `FA2_FLAG_ADAPTIVE` is set. The energy
12
+ * reduction runs under every mode; only its write is conditional.
8
13
  *
9
14
  * Body only (spec 3.5, D9); normative text (contract 4.5); the K5 sabotage mutations (P3-T5) are textual edits of it.
10
15
  */
11
16
  /** The K5 body: entry point `integrate`; calls the reduction helpers (`needs: ["subgroups"]`, contract 4.3). */
12
- export declare const fa2IntegrateWgsl = "fn load_force(i: u32) -> vec3f { return vec3f(force[3u * i], force[3u * i + 1u], force[3u * i + 2u]); }\nfn load_old(i: u32) -> vec3f { return vec3f(oldForce[3u * i], oldForce[3u * i + 1u], oldForce[3u * i + 2u]); }\nfn store_old(i: u32, f: vec3f) {\n oldForce[3u * i] = f.x;\n oldForce[3u * i + 1u] = f.y;\n oldForce[3u * i + 2u] = f.z;\n}\n\n@compute @workgroup_size(WG)\nfn integrate(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let i = linear_id(wid, lid.x);\n var dp = vec3f(0.0);\n var p = vec4f(0.0);\n var free = false;\n var valid = false;\n if (i < P.n) {\n valid = true;\n let f = load_force(i);\n p = pos[i];\n var swing_i = p.w * length(f); // SWING_MODE 1: NetworkX's local swinging m |F| (layout.py line 1497)\n if (SWING_MODE == 0u) { swing_i = p.w * length(f - load_old(i)); } // paper: m |F(t) - F(t-1)|, recomputed inline (7.2)\n let factor = S.speed / (1.0 + sqrt(S.speed * swing_i));\n let fixed = mask_bit(fixedMask[i >> 5u], i);\n dp = select(f * factor, vec3f(0.0), fixed); // no clamp on dp (D25)\n if (P.dim == 2u) { dp.z = 0.0; } // 2D never integrates z (7.13)\n p = vec4f(p.xyz + dp, p.w);\n pos[i] = p;\n if (SWING_MODE == 0u) { store_old(i, f); } // fixed nodes too, so a later unpin sees no stale swing (7.11)\n free = !fixed;\n }\n // uniform control flow from here (3.5 rule 1): partials A (sum p, sum |p - c|^2, min, max over valid rows) and C (sum |dp|, free count)\n let c = S.centroid.xyz;\n var sumv = vec4f(0.0);\n var lo = vec4f(F32_MAX);\n var hi = vec4f(-F32_MAX);\n var dl = 0.0;\n var fr = 0u;\n if (valid) {\n let q = p.xyz - c;\n sumv = vec4f(p.xyz, dot(q, q));\n lo = vec4f(p.xyz, 0.0);\n hi = vec4f(p.xyz, dot(q, q)); // max.w carries max |p - c|^2 so K1 can write the exact layoutRadius (spec 3.3)\n }\n if (free) { dl = length(dp); fr = 1u; }\n let tSum = wg_reduce_vec4(sumv, lid.x, 0u);\n let tLo = wg_reduce_vec4(lo, lid.x, 1u);\n let tHi = wg_reduce_vec4(hi, lid.x, 2u);\n let tDl = wg_reduce_f32(dl, lid.x, 0u);\n let tFr = wg_reduce_u32(fr, lid.x, 0u);\n if (lid.x == 0u) {\n let g = group_id(wid);\n partials[g].sum = tSum;\n partials[g].min = tLo;\n partials[g].max = tHi;\n partials[g].dispFree = vec2f(tDl, f32(tFr));\n }\n}";
17
+ export declare const fa2IntegrateWgsl = "fn load_force(i: u32) -> vec3f { return vec3f(force[3u * i], force[3u * i + 1u], force[3u * i + 2u]); }\nfn load_old(i: u32) -> vec3f { return vec3f(oldForce[3u * i], oldForce[3u * i + 1u], oldForce[3u * i + 2u]); }\nfn store_old(i: u32, f: vec3f) {\n oldForce[3u * i] = f.x;\n oldForce[3u * i + 1u] = f.y;\n oldForce[3u * i + 2u] = f.z;\n}\n\n@compute @workgroup_size(WG)\nfn integrate(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let i = linear_id(wid, lid.x);\n var dp = vec3f(0.0);\n var p = vec4f(0.0);\n var free = false;\n var valid = false;\n var ke = 0.0;\n if (i < P.n) {\n valid = true;\n let f = load_force(i);\n p = pos[i];\n var swing_i = p.w * length(f); // SWING_MODE 1: NetworkX's local swinging m |F| (layout.py line 1497)\n if (SWING_MODE == 0u) { swing_i = p.w * length(f - load_old(i)); } // paper: m |F(t) - F(t-1)|, recomputed inline (7.2)\n let factor = S.speed / (1.0 + sqrt(S.speed * swing_i));\n let fixed = mask_bit(fixedMask[i >> 5u], i);\n dp = select(f * factor, vec3f(0.0), fixed); // APPLY 0 (FA2): no clamp on dp (D25)\n if (APPLY == 1u) { // APPLY 1 (FR, 7.20): move along F by min(|F|, t); a fixed node stays\n let mag = length(f);\n let t = select(P.temperature, S.temperature, (P.flags & FA2_FLAG_ADAPTIVE) != 0u); // adaptive cooling: K1's state temperature\n dp = vec3f(0.0);\n if (mag > 0.0 && !fixed) { dp = f * (min(mag, t) / mag); }\n ke = select(0.0, dot(f, f), !fixed); // the force energy of Hu's step control, folded like the spring preset's kinetic energy\n }\n if (APPLY == 2u) { // APPLY 2 (spring-electrical): ngraph's Euler step over the velocity in the oldForce slot (PD-2)\n var v = load_old(i);\n let fd = f - P.dragCoefficient * v; // drag (generateCreateDragForce.js:18)\n v = v + (P.timeStep / p.w) * fd; // v += (dt / m) F (generateIntegrator.js:27-29)\n let sp = length(v);\n if (sp > 1.0) { v = v / sp; } // the unit speed clamp (generateIntegrator.js:33-37)\n if (P.dim == 2u) { v.z = 0.0; }\n dp = select(P.timeStep * v, vec3f(0.0), fixed); // dp = dt v; a pinned body is skipped (generateIntegrator.js:21, 39-41)\n if (!fixed) { store_old(i, v); }\n ke = select(0.0, 0.5 * p.w * dot(v, v), !fixed); // partials B under APPLY 2 (PD-4)\n }\n if (P.dim == 2u) { dp.z = 0.0; } // 2D never integrates z (7.13)\n p = vec4f(p.xyz + dp, p.w);\n pos[i] = p;\n if (SWING_MODE == 0u) { store_old(i, f); } // fixed nodes too, so a later unpin sees no stale swing (7.11)\n free = !fixed;\n }\n // uniform control flow from here (3.5 rule 1): partials A (sum p, sum |p - c|^2, min, max over valid rows) and C (sum |dp|, free count)\n let c = S.centroid.xyz;\n var sumv = vec4f(0.0);\n var lo = vec4f(F32_MAX);\n var hi = vec4f(-F32_MAX);\n var dl = 0.0;\n var fr = 0u;\n if (valid) {\n let q = p.xyz - c;\n sumv = vec4f(p.xyz, dot(q, q));\n lo = vec4f(p.xyz, 0.0);\n hi = vec4f(p.xyz, dot(q, q)); // max.w carries max |p - c|^2 so K1 can write the exact layoutRadius (spec 3.3)\n }\n if (free) { dl = length(dp); fr = 1u; }\n let tSum = wg_reduce_vec4(sumv, lid.x, 0u);\n let tLo = wg_reduce_vec4(lo, lid.x, 1u);\n let tHi = wg_reduce_vec4(hi, lid.x, 2u);\n let tDl = wg_reduce_f32(dl, lid.x, 0u);\n let tFr = wg_reduce_u32(fr, lid.x, 0u);\n let tKe = wg_reduce_f32(ke, lid.x, 0u);\n if (lid.x == 0u) {\n let g = group_id(wid);\n partials[g].sum = tSum;\n partials[g].min = tLo;\n partials[g].max = tHi;\n partials[g].dispFree = vec2f(tDl, f32(tFr));\n if (APPLY != 0u) { partials[g].swingTraction = vec2f(tKe, 0.0); } // overwrites K3's epilogue: K4 never runs under FR or the preset (PD-4)\n }\n}";
13
18
  //# sourceMappingURL=fa2-integrate.wgsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fa2-integrate.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-integrate.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gHAAgH;AAChH,eAAO,MAAM,gBAAgB,4jFAwD3B,CAAC"}
1
+ {"version":3,"file":"fa2-integrate.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-integrate.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,gHAAgH;AAChH,eAAO,MAAM,gBAAgB,u1IA6E3B,CAAC"}
@@ -4,7 +4,12 @@
4
4
  * networkx mode `m |F|`, contract 4.6), the position update with no displacement clamp (D25), z never integrated
5
5
  * in 2D (spec 7.13), `oldForce` stored in paper mode for fixed nodes too (spec 7.11), and the partials A
6
6
  * (sum p, sum |p - c|^2, min, max with max |p - c|^2 in `max.w`) and C (sum |dp| over free rows, free count) in
7
- * uniform control flow.
7
+ * uniform control flow. `APPLY` (P5, spec 7.20) picks the integrator: 0 = the FA2 text, 1 = the Fruchterman-Reingold
8
+ * temperature cap `min(|F|, t)` along F, 2 = ngraph's semi-implicit Euler step with drag and the unit speed clamp
9
+ * over the velocity that lives in the `oldForce` slot (PD-2), which also folds the free kinetic energy into
10
+ * `partials.swingTraction.x` (PD-4); mode 1 folds the free force energy `sum |F|^2` into the same slot for K1's
11
+ * adaptive cooling and takes its temperature from the state block when `FA2_FLAG_ADAPTIVE` is set. The energy
12
+ * reduction runs under every mode; only its write is conditional.
8
13
  *
9
14
  * Body only (spec 3.5, D9); normative text (contract 4.5); the K5 sabotage mutations (P3-T5) are textual edits of it.
10
15
  */
@@ -24,6 +29,7 @@ fn integrate(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id
24
29
  var p = vec4f(0.0);
25
30
  var free = false;
26
31
  var valid = false;
32
+ var ke = 0.0;
27
33
  if (i < P.n) {
28
34
  valid = true;
29
35
  let f = load_force(i);
@@ -32,7 +38,25 @@ fn integrate(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id
32
38
  if (SWING_MODE == 0u) { swing_i = p.w * length(f - load_old(i)); } // paper: m |F(t) - F(t-1)|, recomputed inline (7.2)
33
39
  let factor = S.speed / (1.0 + sqrt(S.speed * swing_i));
34
40
  let fixed = mask_bit(fixedMask[i >> 5u], i);
35
- dp = select(f * factor, vec3f(0.0), fixed); // no clamp on dp (D25)
41
+ dp = select(f * factor, vec3f(0.0), fixed); // APPLY 0 (FA2): no clamp on dp (D25)
42
+ if (APPLY == 1u) { // APPLY 1 (FR, 7.20): move along F by min(|F|, t); a fixed node stays
43
+ let mag = length(f);
44
+ let t = select(P.temperature, S.temperature, (P.flags & FA2_FLAG_ADAPTIVE) != 0u); // adaptive cooling: K1's state temperature
45
+ dp = vec3f(0.0);
46
+ if (mag > 0.0 && !fixed) { dp = f * (min(mag, t) / mag); }
47
+ ke = select(0.0, dot(f, f), !fixed); // the force energy of Hu's step control, folded like the spring preset's kinetic energy
48
+ }
49
+ if (APPLY == 2u) { // APPLY 2 (spring-electrical): ngraph's Euler step over the velocity in the oldForce slot (PD-2)
50
+ var v = load_old(i);
51
+ let fd = f - P.dragCoefficient * v; // drag (generateCreateDragForce.js:18)
52
+ v = v + (P.timeStep / p.w) * fd; // v += (dt / m) F (generateIntegrator.js:27-29)
53
+ let sp = length(v);
54
+ if (sp > 1.0) { v = v / sp; } // the unit speed clamp (generateIntegrator.js:33-37)
55
+ if (P.dim == 2u) { v.z = 0.0; }
56
+ dp = select(P.timeStep * v, vec3f(0.0), fixed); // dp = dt v; a pinned body is skipped (generateIntegrator.js:21, 39-41)
57
+ if (!fixed) { store_old(i, v); }
58
+ ke = select(0.0, 0.5 * p.w * dot(v, v), !fixed); // partials B under APPLY 2 (PD-4)
59
+ }
36
60
  if (P.dim == 2u) { dp.z = 0.0; } // 2D never integrates z (7.13)
37
61
  p = vec4f(p.xyz + dp, p.w);
38
62
  pos[i] = p;
@@ -58,12 +82,14 @@ fn integrate(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id
58
82
  let tHi = wg_reduce_vec4(hi, lid.x, 2u);
59
83
  let tDl = wg_reduce_f32(dl, lid.x, 0u);
60
84
  let tFr = wg_reduce_u32(fr, lid.x, 0u);
85
+ let tKe = wg_reduce_f32(ke, lid.x, 0u);
61
86
  if (lid.x == 0u) {
62
87
  let g = group_id(wid);
63
88
  partials[g].sum = tSum;
64
89
  partials[g].min = tLo;
65
90
  partials[g].max = tHi;
66
91
  partials[g].dispFree = vec2f(tDl, f32(tFr));
92
+ if (APPLY != 0u) { partials[g].swingTraction = vec2f(tKe, 0.0); } // overwrites K3's epilogue: K4 never runs under FR or the preset (PD-4)
67
93
  }
68
94
  }`;
69
95
  //# sourceMappingURL=fa2-integrate.wgsl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fa2-integrate.wgsl.js","sourceRoot":"","sources":["../../../src/wgsl/fa2-integrate.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gHAAgH;AAChH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwDzC,CAAC"}
1
+ {"version":3,"file":"fa2-integrate.wgsl.js","sourceRoot":"","sources":["../../../src/wgsl/fa2-integrate.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,gHAAgH;AAChH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EzC,CAAC"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * The `fa2-repulsion-exact` kernel body (K3; contract 4.5; spec 7.6, 7.9, 7.10): the tiled all-pairs repulsion
3
- * `|F| = k m_i m_j / d` with the 0.01 distance floor and the antisymmetric coincident kick, the gravity epilogue
3
+ * `|F| = k m_i m_j / d` with the 0.01 distance floor and the antisymmetric coincident kick (`LAW` 0; P5's `LAW` 1
4
+ * is Fruchterman-Reingold `k^2 / d` and `LAW` 2 ngraph's Coulomb `-g m_i m_j / d^2`, both unfloored, spec 7.20,
5
+ * with the kick's magnitude taken from the law at d = 0.01, PD-10), the gravity epilogue
4
6
  * (GRAVITY_CENTER 0 = centroid, 1 = origin; STRONG_GRAVITY) added under the `valid` guard, `force += f`, and the
5
7
  * swing / traction workgroup reduction in uniform control flow (SWING_MODE 0 = paper: free nodes only against
6
8
  * `oldForce`; 1 = NetworkX: positions and forces mixed, every node) whose lane 0 writes
@@ -8,5 +10,5 @@
8
10
  * `array<f32>` read through the per-body helpers (4.4 rule 6). Normative text, copied verbatim: the P1-T5 sabotage
9
11
  * rows (gravity sign, `k / d2`, the `jj != i` guard, the `.w` mass lane) are textual edits of this string.
10
12
  */
11
- export declare const fa2RepulsionExactWgsl = "\nvar<workgroup> tile: array<vec4f, WG>; // xyz + mass, 4 KiB at WG = 256\n\nfn load_force(i: u32) -> vec3f { return vec3f(force[3u * i], force[3u * i + 1u], force[3u * i + 2u]); }\nfn store_force(i: u32, f: vec3f) {\n force[3u * i] = f.x;\n force[3u * i + 1u] = f.y;\n force[3u * i + 2u] = f.z;\n}\nfn load_old(i: u32) -> vec3f { return vec3f(oldForce[3u * i], oldForce[3u * i + 1u], oldForce[3u * i + 2u]); }\nfn gravity_force(pi: vec4f) -> vec3f { // spec 7.9: centroid (GRAVITY_CENTER 0) or origin (1); regular or strong\n var q = pi.xyz;\n if (GRAVITY_CENTER == 0u) { q = pi.xyz - S.centroid.xyz; }\n if (STRONG_GRAVITY) { return -P.gravity * pi.w * q; }\n let d = length(q);\n if (d > FA2_DIST_FLOOR) { return -P.gravity * pi.w * q / d; }\n return vec3f(0.0);\n}\n\n@compute @workgroup_size(WG)\nfn repulsion(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let i = linear_id(wid, lid.x);\n let valid = i < P.n;\n var pi = vec4f(0.0);\n if (valid) { pi = pos[i]; }\n var f = vec3f(0.0);\n let tiles = (P.n + WG - 1u) / WG;\n for (var t = 0u; t < tiles; t = t + 1u) {\n let j = t * WG + lid.x;\n if (j < P.n) { tile[lid.x] = pos[j]; } else { tile[lid.x] = vec4f(0.0); } // guarded fill; mass 0 marks the pad\n workgroupBarrier(); // uniform: every invocation reaches it\n for (var s = 0u; s < WG; s = s + 1u) {\n let o = tile[s];\n let jj = t * WG + s;\n if (o.w > 0.0 && jj != i) { // mass > 0 for every real node, 0 for the pad\n let d = pi.xyz - o.xyz;\n var d2 = dot(d, d);\n if (d2 < FA2_COINCIDENT_SQ) { // coincident: antisymmetric unit kick of magnitude k m_i m_j / 0.01 (7.2)\n f = f + kick_dir(i, jj, P.dim) * (P.scalingRatio * pi.w * o.w / FA2_DIST_FLOOR);\n continue;\n }\n d2 = max(d2, FA2_DIST_FLOOR_SQ); // d >= 0.01\n let k = P.scalingRatio * pi.w * o.w;\n f = f + d * (k / d2); // |F| = k m_i m_j / d along d / d\n }\n }\n workgroupBarrier();\n }\n // epilogue (7.9, 7.10): gravity and force += under the guard, the swing / traction reduction outside it\n var sw = 0.0;\n var tr = 0.0;\n if (valid) {\n f = f + gravity_force(pi);\n let fnew = load_force(i) + f;\n store_force(i, fnew);\n if (SWING_MODE == 1u) { // NetworkX: positions and forces mixed, every node (7.2)\n sw = pi.w * length(pi.xyz - fnew);\n tr = 0.5 * pi.w * length(pi.xyz + fnew);\n } else if (!mask_bit(fixedMask[i >> 5u], i)) { // paper: free nodes only (Gephi ForceAtlas2.java 283-293)\n let fold = load_old(i);\n sw = pi.w * length(fnew - fold);\n tr = 0.5 * pi.w * length(fnew + fold);\n }\n }\n let t = wg_reduce_vec4(vec4f(sw, tr, 0.0, 0.0), lid.x, 0u); // uniform control flow: 256 -> 1\n if (lid.x == 0u) { partials[group_id(wid)].swingTraction = t.xy; }\n}\n";
13
+ export declare const fa2RepulsionExactWgsl = "\nvar<workgroup> tile: array<vec4f, WG>; // xyz + mass, 4 KiB at WG = 256\n\nfn load_force(i: u32) -> vec3f { return vec3f(force[3u * i], force[3u * i + 1u], force[3u * i + 2u]); }\nfn store_force(i: u32, f: vec3f) {\n force[3u * i] = f.x;\n force[3u * i + 1u] = f.y;\n force[3u * i + 2u] = f.z;\n}\nfn load_old(i: u32) -> vec3f { return vec3f(oldForce[3u * i], oldForce[3u * i + 1u], oldForce[3u * i + 2u]); }\nfn kick_magnitude(mi: f32, mj: f32) -> f32 { // the law's magnitude at d = FA2_DIST_FLOOR (PD-10)\n if (LAW == 1u) { return P.frK * P.frK / FA2_DIST_FLOOR; }\n if (LAW == 2u) { return -P.coulomb * mi * mj / FA2_DIST_FLOOR_SQ; }\n return P.scalingRatio * mi * mj / FA2_DIST_FLOOR;\n}\nfn gravity_force(pi: vec4f) -> vec3f { // spec 7.9: centroid (GRAVITY_CENTER 0) or origin (1); regular or strong\n var q = pi.xyz;\n if (GRAVITY_CENTER == 0u) { q = pi.xyz - S.centroid.xyz; }\n if (STRONG_GRAVITY) { return -P.gravity * pi.w * q; }\n let d = length(q);\n if (d > FA2_DIST_FLOOR) { return -P.gravity * pi.w * q / d; }\n return vec3f(0.0);\n}\n\n@compute @workgroup_size(WG)\nfn repulsion(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {\n let i = linear_id(wid, lid.x);\n let valid = i < P.n;\n var pi = vec4f(0.0);\n if (valid) { pi = pos[i]; }\n var f = vec3f(0.0);\n let tiles = (P.n + WG - 1u) / WG;\n for (var t = 0u; t < tiles; t = t + 1u) {\n let j = t * WG + lid.x;\n if (j < P.n) { tile[lid.x] = pos[j]; } else { tile[lid.x] = vec4f(0.0); } // guarded fill; mass 0 marks the pad\n workgroupBarrier(); // uniform: every invocation reaches it\n for (var s = 0u; s < WG; s = s + 1u) {\n let o = tile[s];\n let jj = t * WG + s;\n if (o.w > 0.0 && jj != i) { // mass > 0 for every real node, 0 for the pad\n let d = pi.xyz - o.xyz;\n var d2 = dot(d, d);\n if (d2 < FA2_COINCIDENT_SQ) { // coincident: antisymmetric unit kick of the law's magnitude at d = 0.01 (7.2; PD-10)\n f = f + kick_dir(i, jj, P.dim) * kick_magnitude(pi.w, o.w);\n continue;\n }\n if (LAW == 0u) { d2 = max(d2, FA2_DIST_FLOOR_SQ); } // FA2 alone floors d >= 0.01 (7.2); FR and coulomb are unfloored (7.20)\n let k = P.scalingRatio * pi.w * o.w;\n if (LAW == 0u) { f = f + d * (k / d2); } // LAW 0 (FA2): |F| = k m_i m_j / d along d / d\n if (LAW == 1u) { f = f + d * (P.frK * P.frK / d2); } // LAW 1 (FR, 7.20): |F| = k^2 / d, mass ignored\n if (LAW == 2u) { f = f + d * (-P.coulomb * pi.w * o.w / (d2 * sqrt(d2))); } // LAW 2 (coulomb, ngraph generateQuadTree.js:131-132): |F| = -g m_i m_j / d^2\n }\n }\n workgroupBarrier();\n }\n // epilogue (7.9, 7.10): gravity and force += under the guard, the swing / traction reduction outside it\n var sw = 0.0;\n var tr = 0.0;\n if (valid) {\n f = f + gravity_force(pi);\n let fnew = load_force(i) + f;\n store_force(i, fnew);\n if (SWING_MODE == 1u) { // NetworkX: positions and forces mixed, every node (7.2)\n sw = pi.w * length(pi.xyz - fnew);\n tr = 0.5 * pi.w * length(pi.xyz + fnew);\n } else if (!mask_bit(fixedMask[i >> 5u], i)) { // paper: free nodes only (Gephi ForceAtlas2.java 283-293)\n let fold = load_old(i);\n sw = pi.w * length(fnew - fold);\n tr = 0.5 * pi.w * length(fnew + fold);\n }\n }\n let t = wg_reduce_vec4(vec4f(sw, tr, 0.0, 0.0), lid.x, 0u); // uniform control flow: 256 -> 1\n if (lid.x == 0u) { partials[group_id(wid)].swingTraction = t.xy; }\n}\n";
12
14
  //# sourceMappingURL=fa2-repulsion-exact.wgsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fa2-repulsion-exact.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-repulsion-exact.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,g4GAmEjC,CAAC"}
1
+ {"version":3,"file":"fa2-repulsion-exact.wgsl.d.ts","sourceRoot":"","sources":["../../../src/wgsl/fa2-repulsion-exact.wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,yiIA0EjC,CAAC"}