@tscircuit/hypergraph 0.0.13 → 0.0.15
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/dist/index.d.ts +1 -0
- package/dist/index.js +173 -55
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -389,6 +389,7 @@ declare class JumperGraphSolver extends HyperGraphSolver<JRegion, JPort> {
|
|
|
389
389
|
ripCost: number;
|
|
390
390
|
baseMaxIterations: number;
|
|
391
391
|
additionalMaxIterationsPerConnection: number;
|
|
392
|
+
additionalMaxIterationsPerCrossing: number;
|
|
392
393
|
constructor(input: {
|
|
393
394
|
inputGraph: HyperGraph | SerializedHyperGraph;
|
|
394
395
|
inputConnections: (Connection | SerializedConnection)[];
|
package/dist/index.js
CHANGED
|
@@ -10,19 +10,21 @@ var computeBoundsCenter = (bounds) => {
|
|
|
10
10
|
var dims1206x4 = {
|
|
11
11
|
padWidth: 0.8,
|
|
12
12
|
// X direction (horizontal)
|
|
13
|
-
|
|
14
|
-
// Y direction (vertical)
|
|
15
|
-
|
|
13
|
+
outerPadHeight: 0.5,
|
|
14
|
+
// Y direction (vertical) for rows 1 and 4
|
|
15
|
+
innerPadHeight: 0.4,
|
|
16
|
+
// Y direction (vertical) for rows 2 and 3
|
|
17
|
+
leftPadCenterX: -0.9,
|
|
16
18
|
// X position of left pads (P1, P2, P3, P4)
|
|
17
|
-
rightPadCenterX:
|
|
19
|
+
rightPadCenterX: 0.9,
|
|
18
20
|
// X position of right pads (P5, P6, P7, P8)
|
|
19
|
-
row1CenterY: 1.
|
|
21
|
+
row1CenterY: -1.2,
|
|
20
22
|
// Y position of row 1 (P1, P8)
|
|
21
|
-
row2CenterY: 0.
|
|
23
|
+
row2CenterY: -0.4,
|
|
22
24
|
// Y position of row 2 (P2, P7)
|
|
23
|
-
row3CenterY:
|
|
25
|
+
row3CenterY: 0.4,
|
|
24
26
|
// Y position of row 3 (P3, P6)
|
|
25
|
-
row4CenterY:
|
|
27
|
+
row4CenterY: 1.2
|
|
26
28
|
// Y position of row 4 (P4, P5)
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -232,7 +234,8 @@ var generateJumperX4Grid = ({
|
|
|
232
234
|
const ports = [];
|
|
233
235
|
const {
|
|
234
236
|
padWidth,
|
|
235
|
-
|
|
237
|
+
outerPadHeight,
|
|
238
|
+
innerPadHeight,
|
|
236
239
|
leftPadCenterX,
|
|
237
240
|
rightPadCenterX,
|
|
238
241
|
row1CenterY,
|
|
@@ -241,10 +244,11 @@ var generateJumperX4Grid = ({
|
|
|
241
244
|
row4CenterY
|
|
242
245
|
} = dims1206x4;
|
|
243
246
|
const padHalfWidth = padWidth / 2;
|
|
244
|
-
const
|
|
247
|
+
const outerPadHalfHeight = outerPadHeight / 2;
|
|
248
|
+
const innerPadHalfHeight = innerPadHeight / 2;
|
|
245
249
|
const cellWidth = rightPadCenterX - leftPadCenterX + padWidth;
|
|
246
250
|
const horizontalSpacing = cellWidth + marginX;
|
|
247
|
-
const cellHeight =
|
|
251
|
+
const cellHeight = row4CenterY - row1CenterY + outerPadHeight;
|
|
248
252
|
const verticalSpacing = cellHeight + marginY;
|
|
249
253
|
let outerPaddingX = outerPaddingXParam;
|
|
250
254
|
let outerPaddingY = outerPaddingYParam;
|
|
@@ -365,25 +369,59 @@ var generateJumperX4Grid = ({
|
|
|
365
369
|
const p7CenterY = centerY + row2CenterY;
|
|
366
370
|
const p8CenterX = centerX + rightPadCenterX;
|
|
367
371
|
const p8CenterY = centerY + row1CenterY;
|
|
368
|
-
const createPadBounds = (padCenterX, padCenterY) => ({
|
|
372
|
+
const createPadBounds = (padCenterX, padCenterY, halfHeight) => ({
|
|
369
373
|
minX: padCenterX - padHalfWidth,
|
|
370
374
|
maxX: padCenterX + padHalfWidth,
|
|
371
|
-
minY: padCenterY -
|
|
372
|
-
maxY: padCenterY +
|
|
375
|
+
minY: padCenterY - halfHeight,
|
|
376
|
+
maxY: padCenterY + halfHeight
|
|
373
377
|
});
|
|
374
|
-
const pad1Bounds = createPadBounds(
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
378
|
+
const pad1Bounds = createPadBounds(
|
|
379
|
+
p1CenterX,
|
|
380
|
+
p1CenterY,
|
|
381
|
+
outerPadHalfHeight
|
|
382
|
+
);
|
|
383
|
+
const pad2Bounds = createPadBounds(
|
|
384
|
+
p2CenterX,
|
|
385
|
+
p2CenterY,
|
|
386
|
+
innerPadHalfHeight
|
|
387
|
+
);
|
|
388
|
+
const pad3Bounds = createPadBounds(
|
|
389
|
+
p3CenterX,
|
|
390
|
+
p3CenterY,
|
|
391
|
+
innerPadHalfHeight
|
|
392
|
+
);
|
|
393
|
+
const pad4Bounds = createPadBounds(
|
|
394
|
+
p4CenterX,
|
|
395
|
+
p4CenterY,
|
|
396
|
+
outerPadHalfHeight
|
|
397
|
+
);
|
|
398
|
+
const pad5Bounds = createPadBounds(
|
|
399
|
+
p5CenterX,
|
|
400
|
+
p5CenterY,
|
|
401
|
+
outerPadHalfHeight
|
|
402
|
+
);
|
|
403
|
+
const pad6Bounds = createPadBounds(
|
|
404
|
+
p6CenterX,
|
|
405
|
+
p6CenterY,
|
|
406
|
+
innerPadHalfHeight
|
|
407
|
+
);
|
|
408
|
+
const pad7Bounds = createPadBounds(
|
|
409
|
+
p7CenterX,
|
|
410
|
+
p7CenterY,
|
|
411
|
+
innerPadHalfHeight
|
|
412
|
+
);
|
|
413
|
+
const pad8Bounds = createPadBounds(
|
|
414
|
+
p8CenterX,
|
|
415
|
+
p8CenterY,
|
|
416
|
+
outerPadHalfHeight
|
|
417
|
+
);
|
|
382
418
|
const underjumperBounds = {
|
|
383
419
|
minX: pad1Bounds.maxX,
|
|
384
420
|
maxX: pad8Bounds.minX,
|
|
385
|
-
minY:
|
|
386
|
-
|
|
421
|
+
minY: pad1Bounds.minY,
|
|
422
|
+
// row 1 is now at bottom (Y=-1.2)
|
|
423
|
+
maxY: pad4Bounds.maxY
|
|
424
|
+
// row 4 is now at top (Y=1.2)
|
|
387
425
|
};
|
|
388
426
|
const throughjumperHeight = 0.3;
|
|
389
427
|
const throughjumper1Bounds = {
|
|
@@ -412,8 +450,8 @@ var generateJumperX4Grid = ({
|
|
|
412
450
|
};
|
|
413
451
|
const mainMinX = pad1Bounds.minX;
|
|
414
452
|
const mainMaxX = pad8Bounds.maxX;
|
|
415
|
-
const mainMinY =
|
|
416
|
-
const mainMaxY =
|
|
453
|
+
const mainMinY = pad1Bounds.minY;
|
|
454
|
+
const mainMaxY = pad4Bounds.maxY;
|
|
417
455
|
const pad1 = createRegion(`${idPrefix}:pad1`, pad1Bounds, true);
|
|
418
456
|
const pad2 = createRegion(`${idPrefix}:pad2`, pad2Bounds, true);
|
|
419
457
|
const pad3 = createRegion(`${idPrefix}:pad3`, pad3Bounds, true);
|
|
@@ -485,8 +523,10 @@ var generateJumperX4Grid = ({
|
|
|
485
523
|
{
|
|
486
524
|
minX: pad1Bounds.minX,
|
|
487
525
|
maxX: pad1Bounds.maxX,
|
|
488
|
-
minY:
|
|
489
|
-
|
|
526
|
+
minY: pad1Bounds.maxY,
|
|
527
|
+
// top of pad1
|
|
528
|
+
maxY: pad2Bounds.minY
|
|
529
|
+
// bottom of pad2
|
|
490
530
|
},
|
|
491
531
|
false
|
|
492
532
|
);
|
|
@@ -495,8 +535,10 @@ var generateJumperX4Grid = ({
|
|
|
495
535
|
{
|
|
496
536
|
minX: pad2Bounds.minX,
|
|
497
537
|
maxX: pad2Bounds.maxX,
|
|
498
|
-
minY:
|
|
499
|
-
|
|
538
|
+
minY: pad2Bounds.maxY,
|
|
539
|
+
// top of pad2
|
|
540
|
+
maxY: pad3Bounds.minY
|
|
541
|
+
// bottom of pad3
|
|
500
542
|
},
|
|
501
543
|
false
|
|
502
544
|
);
|
|
@@ -505,8 +547,10 @@ var generateJumperX4Grid = ({
|
|
|
505
547
|
{
|
|
506
548
|
minX: pad3Bounds.minX,
|
|
507
549
|
maxX: pad3Bounds.maxX,
|
|
508
|
-
minY:
|
|
509
|
-
|
|
550
|
+
minY: pad3Bounds.maxY,
|
|
551
|
+
// top of pad3
|
|
552
|
+
maxY: pad4Bounds.minY
|
|
553
|
+
// bottom of pad4
|
|
510
554
|
},
|
|
511
555
|
false
|
|
512
556
|
);
|
|
@@ -515,8 +559,10 @@ var generateJumperX4Grid = ({
|
|
|
515
559
|
{
|
|
516
560
|
minX: pad8Bounds.minX,
|
|
517
561
|
maxX: pad8Bounds.maxX,
|
|
518
|
-
minY:
|
|
519
|
-
|
|
562
|
+
minY: pad8Bounds.maxY,
|
|
563
|
+
// top of pad8
|
|
564
|
+
maxY: pad7Bounds.minY
|
|
565
|
+
// bottom of pad7
|
|
520
566
|
},
|
|
521
567
|
false
|
|
522
568
|
);
|
|
@@ -525,8 +571,10 @@ var generateJumperX4Grid = ({
|
|
|
525
571
|
{
|
|
526
572
|
minX: pad7Bounds.minX,
|
|
527
573
|
maxX: pad7Bounds.maxX,
|
|
528
|
-
minY:
|
|
529
|
-
|
|
574
|
+
minY: pad7Bounds.maxY,
|
|
575
|
+
// top of pad7
|
|
576
|
+
maxY: pad6Bounds.minY
|
|
577
|
+
// bottom of pad6
|
|
530
578
|
},
|
|
531
579
|
false
|
|
532
580
|
);
|
|
@@ -535,8 +583,10 @@ var generateJumperX4Grid = ({
|
|
|
535
583
|
{
|
|
536
584
|
minX: pad6Bounds.minX,
|
|
537
585
|
maxX: pad6Bounds.maxX,
|
|
538
|
-
minY:
|
|
539
|
-
|
|
586
|
+
minY: pad6Bounds.maxY,
|
|
587
|
+
// top of pad6
|
|
588
|
+
maxY: pad5Bounds.minY
|
|
589
|
+
// bottom of pad5
|
|
540
590
|
},
|
|
541
591
|
false
|
|
542
592
|
);
|
|
@@ -657,8 +707,8 @@ var generateJumperX4Grid = ({
|
|
|
657
707
|
isLastCol ? effectiveOuterChannelXPoints : innerColChannelPointCount
|
|
658
708
|
)
|
|
659
709
|
);
|
|
660
|
-
ports.push(createPort(`${idPrefix}:T-
|
|
661
|
-
ports.push(createPort(`${idPrefix}:T-
|
|
710
|
+
ports.push(createPort(`${idPrefix}:T-P4`, top, pad4));
|
|
711
|
+
ports.push(createPort(`${idPrefix}:T-P5`, top, pad5));
|
|
662
712
|
if (regionsBetweenPads) {
|
|
663
713
|
const ujBounds = underjumper.d.bounds;
|
|
664
714
|
const ujWidth = ujBounds.maxX - ujBounds.minX;
|
|
@@ -698,8 +748,8 @@ var generateJumperX4Grid = ({
|
|
|
698
748
|
isLastCol ? effectiveOuterChannelXPoints : innerColChannelPointCount
|
|
699
749
|
)
|
|
700
750
|
);
|
|
701
|
-
ports.push(createPort(`${idPrefix}:B-
|
|
702
|
-
ports.push(createPort(`${idPrefix}:B-
|
|
751
|
+
ports.push(createPort(`${idPrefix}:B-P1`, bottom, pad1));
|
|
752
|
+
ports.push(createPort(`${idPrefix}:B-P8`, bottom, pad8));
|
|
703
753
|
if (regionsBetweenPads) {
|
|
704
754
|
const ujBounds = underjumper.d.bounds;
|
|
705
755
|
const ujWidth = ujBounds.maxX - ujBounds.minX;
|
|
@@ -906,9 +956,9 @@ var generateJumperX4Grid = ({
|
|
|
906
956
|
}
|
|
907
957
|
ports.push(
|
|
908
958
|
createPort(
|
|
909
|
-
`cell_${row - 1}_${col}->cell_${row}_${col}:B-
|
|
959
|
+
`cell_${row - 1}_${col}->cell_${row}_${col}:B-P4`,
|
|
910
960
|
aboveCell.bottom,
|
|
911
|
-
|
|
961
|
+
pad4
|
|
912
962
|
)
|
|
913
963
|
);
|
|
914
964
|
if (regionsBetweenPads) {
|
|
@@ -938,9 +988,9 @@ var generateJumperX4Grid = ({
|
|
|
938
988
|
}
|
|
939
989
|
ports.push(
|
|
940
990
|
createPort(
|
|
941
|
-
`cell_${row - 1}_${col}->cell_${row}_${col}:B-
|
|
991
|
+
`cell_${row - 1}_${col}->cell_${row}_${col}:B-P5`,
|
|
942
992
|
aboveCell.bottom,
|
|
943
|
-
|
|
993
|
+
pad5
|
|
944
994
|
)
|
|
945
995
|
);
|
|
946
996
|
ports.push(
|
|
@@ -2369,24 +2419,88 @@ function computeCrossingAssignments(region, port1, port2) {
|
|
|
2369
2419
|
return crossingAssignments;
|
|
2370
2420
|
}
|
|
2371
2421
|
|
|
2422
|
+
// lib/JumperGraphSolver/countInputConnectionCrossings.ts
|
|
2423
|
+
function countInputConnectionCrossings(graph, connections) {
|
|
2424
|
+
if (connections.length < 2) {
|
|
2425
|
+
return 0;
|
|
2426
|
+
}
|
|
2427
|
+
let minX = Infinity;
|
|
2428
|
+
let maxX = -Infinity;
|
|
2429
|
+
let minY = Infinity;
|
|
2430
|
+
let maxY = -Infinity;
|
|
2431
|
+
for (const region of graph.regions) {
|
|
2432
|
+
const jRegion = region;
|
|
2433
|
+
if (jRegion.d?.bounds) {
|
|
2434
|
+
minX = Math.min(minX, jRegion.d.bounds.minX);
|
|
2435
|
+
maxX = Math.max(maxX, jRegion.d.bounds.maxX);
|
|
2436
|
+
minY = Math.min(minY, jRegion.d.bounds.minY);
|
|
2437
|
+
maxY = Math.max(maxY, jRegion.d.bounds.maxY);
|
|
2438
|
+
} else if (jRegion.d?.center) {
|
|
2439
|
+
minX = Math.min(minX, jRegion.d.center.x);
|
|
2440
|
+
maxX = Math.max(maxX, jRegion.d.center.x);
|
|
2441
|
+
minY = Math.min(minY, jRegion.d.center.y);
|
|
2442
|
+
maxY = Math.max(maxY, jRegion.d.center.y);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
const regionCenterMap = /* @__PURE__ */ new Map();
|
|
2446
|
+
for (const region of graph.regions) {
|
|
2447
|
+
const jRegion = region;
|
|
2448
|
+
if (jRegion.d?.center) {
|
|
2449
|
+
regionCenterMap.set(region.regionId, jRegion.d.center);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
const chords = [];
|
|
2453
|
+
for (const conn of connections) {
|
|
2454
|
+
let startCenter;
|
|
2455
|
+
let endCenter;
|
|
2456
|
+
if ("startRegion" in conn && conn.startRegion) {
|
|
2457
|
+
const startRegion = conn.startRegion;
|
|
2458
|
+
const endRegion = conn.endRegion;
|
|
2459
|
+
startCenter = startRegion.d?.center;
|
|
2460
|
+
endCenter = endRegion.d?.center;
|
|
2461
|
+
} else if ("startRegionId" in conn) {
|
|
2462
|
+
startCenter = regionCenterMap.get(conn.startRegionId);
|
|
2463
|
+
endCenter = regionCenterMap.get(conn.endRegionId);
|
|
2464
|
+
}
|
|
2465
|
+
if (!startCenter || !endCenter) {
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
const t1 = perimeterT(startCenter, minX, maxX, minY, maxY);
|
|
2469
|
+
const t2 = perimeterT(endCenter, minX, maxX, minY, maxY);
|
|
2470
|
+
chords.push([t1, t2]);
|
|
2471
|
+
}
|
|
2472
|
+
let crossings = 0;
|
|
2473
|
+
for (let i = 0; i < chords.length; i++) {
|
|
2474
|
+
for (let j = i + 1; j < chords.length; j++) {
|
|
2475
|
+
if (chordsCross(chords[i], chords[j])) {
|
|
2476
|
+
crossings++;
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
return crossings;
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2372
2483
|
// lib/JumperGraphSolver/JumperGraphSolver.ts
|
|
2373
2484
|
var JUMPER_GRAPH_SOLVER_DEFAULTS = {
|
|
2374
|
-
portUsagePenalty: 0.
|
|
2375
|
-
portUsagePenaltySq: 0.06194817180037216,
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2485
|
+
portUsagePenalty: 0.034685181009478865,
|
|
2486
|
+
// portUsagePenaltySq: 0.06194817180037216,
|
|
2487
|
+
portUsagePenaltySq: 0,
|
|
2488
|
+
crossingPenalty: 4.072520483177124,
|
|
2489
|
+
crossingPenaltySq: 0,
|
|
2490
|
+
// crossingPenaltySq: 0.1315528159128946,
|
|
2491
|
+
ripCost: 35.38577539020022,
|
|
2492
|
+
greedyMultiplier: 0.5518001238069296
|
|
2380
2493
|
};
|
|
2381
2494
|
var JumperGraphSolver = class extends HyperGraphSolver {
|
|
2382
|
-
UNIT_OF_COST = "
|
|
2495
|
+
UNIT_OF_COST = "hops";
|
|
2383
2496
|
portUsagePenalty = JUMPER_GRAPH_SOLVER_DEFAULTS.portUsagePenalty;
|
|
2384
2497
|
portUsagePenaltySq = JUMPER_GRAPH_SOLVER_DEFAULTS.portUsagePenaltySq;
|
|
2385
2498
|
crossingPenalty = JUMPER_GRAPH_SOLVER_DEFAULTS.crossingPenalty;
|
|
2386
2499
|
crossingPenaltySq = JUMPER_GRAPH_SOLVER_DEFAULTS.crossingPenaltySq;
|
|
2387
2500
|
ripCost = JUMPER_GRAPH_SOLVER_DEFAULTS.ripCost;
|
|
2388
2501
|
baseMaxIterations = 4e3;
|
|
2389
|
-
additionalMaxIterationsPerConnection =
|
|
2502
|
+
additionalMaxIterationsPerConnection = 2e3;
|
|
2503
|
+
additionalMaxIterationsPerCrossing = 2e3;
|
|
2390
2504
|
constructor(input) {
|
|
2391
2505
|
super({
|
|
2392
2506
|
greedyMultiplier: JUMPER_GRAPH_SOLVER_DEFAULTS.greedyMultiplier,
|
|
@@ -2398,7 +2512,11 @@ var JumperGraphSolver = class extends HyperGraphSolver {
|
|
|
2398
2512
|
this.crossingPenalty = input.crossingPenalty ?? this.crossingPenalty;
|
|
2399
2513
|
this.baseMaxIterations = input.baseMaxIterations ?? this.baseMaxIterations;
|
|
2400
2514
|
this.additionalMaxIterationsPerConnection = input.additionalMaxIterationsPerConnection ?? this.additionalMaxIterationsPerConnection;
|
|
2401
|
-
|
|
2515
|
+
const crossings = countInputConnectionCrossings(
|
|
2516
|
+
this.graph,
|
|
2517
|
+
input.inputConnections
|
|
2518
|
+
);
|
|
2519
|
+
this.MAX_ITERATIONS = this.baseMaxIterations + input.inputConnections.length * this.additionalMaxIterationsPerConnection + crossings * this.additionalMaxIterationsPerCrossing;
|
|
2402
2520
|
this.populateDistanceToEndMaps();
|
|
2403
2521
|
}
|
|
2404
2522
|
populateDistanceToEndMaps() {
|