-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathgnn-node-aggregation.typ
130 lines (112 loc) · 3.43 KB
/
gnn-node-aggregation.typ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#import "@preview/cetz:0.3.2": canvas, draw
#import draw: line, content, circle
#set page(width: auto, height: auto, margin: 8pt)
#canvas({
// Styles
let arrow-style = (mark: (end: "stealth", fill: black, scale: 0.5, offset: 2pt), stroke: 0.5pt)
let edge-style = (stroke: 0.4pt)
let node-radius = 0.3
let graph-sep = 4.5 // separation between input graph and aggregation
// Node colors - ensure consistency
let colors = (
A: rgb("#ffd700"), // Gold
B: rgb("#ff4d4d"), // Red
C: rgb("#90ee90"), // Light green
D: rgb("#4d94ff"), // Blue
E: rgb("#9370db"), // Purple
F: rgb("#ff69b4"), // Pink
)
// Helper to draw a node with label
let draw-node(pos, label, name) = {
circle(pos, radius: node-radius, fill: colors.at(label), stroke: 0.5pt, name: name)
content(pos, label, anchor: "center")
}
// Input Graph (left side)
// Define node positions
let target-pos = (-1.5, 1.2)
let b-pos = (0.5, 2)
let c-pos = (1, 1)
let d-pos = (-2.5, -.7)
let e-pos = (-0.25, -1.25)
let f-pos = (1.5, 0)
// Draw nodes
draw-node(target-pos, "A", "target")
draw-node(b-pos, "B", "b")
draw-node(c-pos, "C", "c")
draw-node(d-pos, "D", "d")
draw-node(e-pos, "E", "e")
draw-node(f-pos, "F", "f")
// Add target node label
content((rel: (0, 1.5), to: "target"), "Target Node", name: "target-label")
line("target-label.south", "target", ..arrow-style)
// Draw edges
for (start, end) in (
("target", "b"),
("target", "c"),
("b", "c"),
("target", "d"),
("c", "e"),
("c", "f"),
("e", "f"),
) {
line(start, end, ..edge-style)
}
// Add "Input Graph" label
content((0.25, -1.8), [Input Graph])
// Main aggregation box
let box-pos = (graph-sep, 0.5)
content(
box-pos,
[Aggregation\ for Node A],
name: "agg-box",
fill: rgb("ddd"),
frame: "rect",
stroke: 0.2pt,
padding: (3pt, 7pt),
)
// First layer nodes - renamed to show they're neighbors of A
let first-layer = (
(2, 2, "B", "a-to-b"),
(2, 0, "C", "a-to-c"),
(2, -2, "D", "a-to-d"),
)
// Draw first layer nodes and arrows
for (dx, dy, label, name) in first-layer {
draw-node((rel: (dx, dy), to: "agg-box.east"), label, name)
line(name, "agg-box.east", ..arrow-style)
}
content((rel: (0, .7), to: "a-to-b"), "Hop 1")
// Draw aggregation boxes for each first layer node
for node in ("a-to-b", "a-to-c", "a-to-d") {
let letter = node.split("-").at(-1)
content(
(rel: (2, 0), to: node),
[Aggr(#upper(letter))],
fill: rgb("ddd"),
frame: "rect",
stroke: 0.2pt,
padding: (2pt, 4pt),
name: "aggr-" + letter,
)
line("aggr-" + letter, node, ..arrow-style)
}
// Second layer nodes and connections - renamed to show full path
let second-layer = (
// From B-aggregation (B's neighbors)
((2, 1), "A", "aggr-b", "b-to-a"),
((2, 0), "C", "aggr-b", "b-to-c"),
// From C-aggregation (C's neighbors)
((2, 1), "A", "aggr-c", "c-to-a"),
((2, 0.25), "B", "aggr-c", "c-to-b"),
((2, -0.5), "E", "aggr-c", "c-to-e"),
((2, -1.25), "F", "aggr-c", "c-to-f"),
// From D-aggregation (D's neighbors)
((2, 0), "A", "aggr-d", "d-to-a"),
)
// Draw second layer nodes and arrows
for ((dx, dy), label, parent, name) in second-layer {
draw-node((rel: (dx, dy), to: parent), label, name)
line(name, parent + ".east", ..arrow-style)
}
content((rel: (0, .7), to: "b-to-a"), "Hop 2")
})