-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathgnn-node-aggregation.typ
137 lines (118 loc) · 3.48 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
131
132
133
134
135
136
137
#import "@preview/cetz:0.3.1": canvas, draw
#set page(width: auto, height: auto, margin: 8pt)
#canvas({
import draw: line, content, circle, rect
// 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: black + 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")
})