Skip to content

Commit bff4318

Browse files
committed
ball-tree.typ
1 parent 2308bab commit bff4318

File tree

8 files changed

+452
-126
lines changed

8 files changed

+452
-126
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ repos:
2222
- id: deno-fmt
2323
name: Deno format
2424
entry: deno fmt
25-
types: [file]
25+
types: [svelte, javascript, ts]
2626
language: system
2727
args: [--config, site/deno.json]
28-
exclude_types: [markdown]
2928
- id: deno-lint
3029
name: Deno lint
3130
entry: deno lint
@@ -39,7 +38,7 @@ repos:
3938
- id: codespell
4039
stages: [pre-commit, commit-msg]
4140
exclude_types: [svg]
42-
args: [--ignore-words-list, 'noe,ket,ba,te,nd', --check-filenames]
41+
args: [--ignore-words-list, "noe,ket,ba,te,nd", --check-filenames]
4342

4443
- repo: https://github.com/igorshubovych/markdownlint-cli
4544
rev: v0.44.0
@@ -48,7 +47,7 @@ repos:
4847
# MD013: line too long
4948
# MD033: no inline HTML
5049
# MD041: first line in a file should be a top-level heading
51-
args: [--disable, MD013, MD033, MD041, '--']
50+
args: [--disable, MD013, MD033, MD041, "--"]
5251

5352
- repo: local
5453
hooks:

assets/ball-tree/ball-tree-hd.png

37.1 KB
Loading

assets/ball-tree/ball-tree.pdf

8.37 KB
Binary file not shown.

assets/ball-tree/ball-tree.png

16.8 KB
Loading

assets/ball-tree/ball-tree.svg

Lines changed: 156 additions & 0 deletions
Loading

assets/ball-tree/ball-tree.typ

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#import "@preview/cetz:0.3.4": canvas, draw
2+
#import draw: line, content, circle
3+
4+
#set page(width: auto, height: auto, margin: 8pt)
5+
#set text(size: 10pt) // Set default text size
6+
7+
#canvas({
8+
// Styles
9+
let node-radius = 0.25
10+
let node-sep-x = 1.2 // Horizontal separation for tree
11+
let node-sep-y = 1.2 // Vertical separation for tree
12+
let tree-color = rgb("#6495ED") // Cornflower blue for tree nodes
13+
let leaf-color = rgb("#FF6347") // Tomato red for leaf nodes
14+
let arrow-style = (mark: (end: "stealth", fill: black, scale: 0.3), stroke: 0.6pt)
15+
let tree-line-style = (stroke: (paint: gray, thickness: 0.6pt))
16+
17+
// Draw the circles with labels and different fills
18+
circle(
19+
(-3, 0),
20+
radius: 3.0,
21+
fill: blue.lighten(70%).transparentize(50%),
22+
name: "circ-a",
23+
)
24+
content("circ-a", $a$)
25+
26+
circle(
27+
(rel: (-1.0, 0.5), to: "circ-a"),
28+
radius: 1.8,
29+
fill: green.lighten(70%).transparentize(50%),
30+
name: "circ-b",
31+
)
32+
content("circ-b", $b$)
33+
34+
circle(
35+
(rel: (1.4, 0.3), to: "circ-a"),
36+
radius: 1.5,
37+
fill: green.lighten(70%).transparentize(50%),
38+
name: "circ-c",
39+
)
40+
content("circ-c", $c$)
41+
42+
circle(
43+
(rel: (0.2, -0.95), to: "circ-b"),
44+
radius: 0.8,
45+
fill: green.lighten(30%).transparentize(50%),
46+
name: "circ-d",
47+
)
48+
content("circ-d", $d$)
49+
50+
circle(
51+
(rel: (0.6, -0.5), to: "circ-c"),
52+
radius: 0.7,
53+
fill: green.lighten(30%).transparentize(50%),
54+
name: "circ-e",
55+
)
56+
content("circ-e", $e$)
57+
58+
circle(
59+
(rel: (-0.7, 0.5), to: "circ-b"),
60+
radius: 0.6,
61+
fill: green.lighten(40%).transparentize(50%),
62+
name: "circ-f",
63+
)
64+
content("circ-f", $f$)
65+
66+
circle(
67+
(rel: (-0.4, 0.3), to: "circ-c"),
68+
radius: 0.7,
69+
fill: orange.lighten(30%).transparentize(50%),
70+
name: "circ-g",
71+
)
72+
content("circ-g", $g$)
73+
74+
circle(
75+
(rel: (0.1, -0.9), to: "circ-g"),
76+
radius: 0.5,
77+
fill: orange.lighten(40%).transparentize(50%),
78+
name: "circ-h",
79+
)
80+
content("circ-h", $h$)
81+
82+
circle(
83+
(rel: (0.0, 1.1), to: "circ-e"),
84+
radius: 0.6,
85+
fill: green.lighten(40%).transparentize(50%),
86+
name: "circ-i",
87+
)
88+
content("circ-i", $i$)
89+
90+
circle(
91+
(rel: (0.2, -1.8), to: "circ-a"),
92+
radius: 1.0,
93+
fill: blue.lighten(30%).transparentize(50%),
94+
name: "circ-j",
95+
)
96+
content("circ-j", $j$)
97+
98+
// --- Tree Structure (Right Side) ---
99+
let tree_offset = (3.5, 2.5)
100+
101+
// Define colors for tree nodes matching partition circles
102+
let node_colors = (
103+
a: blue.lighten(70%).transparentize(50%),
104+
b: green.lighten(70%).transparentize(50%),
105+
c: green.lighten(70%).transparentize(50%),
106+
d: green.lighten(30%).transparentize(50%),
107+
e: green.lighten(30%).transparentize(50%),
108+
f: green.lighten(40%).transparentize(50%),
109+
g: orange.lighten(30%).transparentize(50%),
110+
h: orange.lighten(40%).transparentize(50%),
111+
i: green.lighten(40%).transparentize(50%),
112+
j: blue.lighten(30%).transparentize(50%),
113+
)
114+
115+
// Helper to draw tree nodes
116+
let draw_tree_node(pos, label, name) = {
117+
circle(pos, radius: node-radius, fill: node_colors.at(label), stroke: 0.5pt, name: name)
118+
content(pos, $#label$)
119+
}
120+
121+
// Level 0
122+
draw_tree_node((tree_offset.at(0) + 0, tree_offset.at(1) + 0), "a", "node-a")
123+
124+
// Level 1
125+
draw_tree_node((tree_offset.at(0) - 1.5 * node-sep-x, tree_offset.at(1) - node-sep-y), "b", "node-b")
126+
draw_tree_node((tree_offset.at(0) + 2.0 * node-sep-x, tree_offset.at(1) - node-sep-y), "c", "node-c")
127+
draw_tree_node((tree_offset.at(0) + 0, tree_offset.at(1) - node-sep-y * 1.5), "j", "node-j")
128+
129+
// Level 2
130+
draw_tree_node((tree_offset.at(0) - 2.0 * node-sep-x, tree_offset.at(1) - 2 * node-sep-y), "f", "node-f")
131+
draw_tree_node((tree_offset.at(0) - 1.0 * node-sep-x, tree_offset.at(1) - 2 * node-sep-y), "d", "node-d")
132+
draw_tree_node((tree_offset.at(0) + 1.0 * node-sep-x, tree_offset.at(1) - 2 * node-sep-y), "g", "node-g")
133+
draw_tree_node((tree_offset.at(0) + 2.0 * node-sep-x, tree_offset.at(1) - 2 * node-sep-y), "e", "node-e")
134+
draw_tree_node((tree_offset.at(0) + 3.0 * node-sep-x, tree_offset.at(1) - 2 * node-sep-y), "i", "node-i")
135+
136+
// Level 3
137+
draw_tree_node((tree_offset.at(0) + 1.0 * node-sep-x, tree_offset.at(1) - 3 * node-sep-y), "h", "node-h")
138+
139+
// Draw Tree Edges
140+
line("node-a", "node-b", ..tree-line-style)
141+
line("node-a", "node-c", ..tree-line-style)
142+
line("node-a", "node-j", ..tree-line-style) // Connect a to j
143+
144+
line("node-b", "node-f", ..tree-line-style)
145+
line("node-b", "node-d", ..tree-line-style)
146+
147+
line("node-c", "node-g", ..tree-line-style)
148+
line("node-c", "node-e", ..tree-line-style) // Connect c to e
149+
line("node-c", "node-i", ..tree-line-style)
150+
151+
line("node-g", "node-h", ..tree-line-style) // Connect g to h
152+
// Line from e to h seems incorrect based on hierarchy, e contains i, g contains h
153+
// line("node-e", "node-h", ..tree-line-style) // This edge seems incorrect based on left diagram, removing
154+
})

assets/ball-tree/ball-tree.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
title: Ball Tree
2+
tags:
3+
- algorithms
4+
- data structures
5+
- machine learning
6+
- nearest neighbors
7+
- space partitioning
8+
description: |
9+
Visualization of the Ball Tree algorithm, a space-partitioning data structure used for efficient nearest neighbor searches, particularly in high-dimensional spaces.
10+
11+
The left side illustrates the hierarchical partitioning of a dataset into nested hyperspheres (balls). Each ball represents a region of the space containing a subset of data points.
12+
13+
The right side shows the corresponding tree structure where each node represents a ball. Internal nodes represent larger balls encompassing the balls of their children, while leaf nodes contain the actual data points.
14+
15+
This hierarchical structure allows the search algorithm to prune large portions of the data space by comparing the query point's distance to the ball's center and radius, making it faster than exhaustive search, especially for high-dimensional non-uniformly distributed data.

0 commit comments

Comments
 (0)