Optimal leaf ordering of dendrograms
Optimal Leaf Ordering
InductiveDendrogram as a leaf-labeled binary tree#✓fully proved
A rooted binary tree whose leaves are labeled by α: the shape of a dendrogram
(merge heights are irrelevant for leaf ordering).
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
Used by 11
Dendrogram
DefinitionLeaves of a dendrogram#✓fully proved
The leaves of a dendrogram, left to right.
def leaves : Dendrogram α → List α
| leaf a => [a]
| node l r => leaves l ++ leaves r
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
DefinitionNumber of internal nodes of a dendrogram#✓fully proved
The number of internal (merge) nodes.
def numInternal : Dendrogram α → ℕ
| leaf _ => 0
| node l r => numInternal l + numInternal r + 1
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
Uses 1 · Used by 2
DefinitionLeaf orderings of a dendrogram#✓fully proved
The leaf orders obtained by choosing, at each internal node, which child is drawn first.
Each choice pattern contributes one entry, so the list has 2 ^ numInternal t entries.
def orderings : Dendrogram α → List (List α)
| leaf a => [[a]]
| node l r =>
(orderings l).flatMap (fun u => (orderings r).map (u ++ ·)) ++
(orderings r).flatMap (fun v => (orderings l).map (v ++ ·))
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
Uses 1 · Used by 7
Optimal Leaf Ordering
DefinitionAdjacent-similarity score of a leaf order#✓fully proved
The score of a leaf order: the sum of the similarities of adjacent leaves.
def adjScore (S : α → α → ℝ) : List α → ℝ
| a :: b :: t => S a b + adjScore S (b :: t)
| _ => 0
DefinitionOptimal leaf-ordering score#✓fully proved
The best score among the leaf orders of t (never ⊥: optScore_ne_bot).
noncomputable def optScore (S : α → α → ℝ) (t : Dendrogram α) : WithBot ℝ :=
((orderings t).map (adjScore S)).maximum
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
def orderings : Dendrogram α → List (List α)
| leaf a => [[a]]
| node l r =>
(orderings l).flatMap (fun u => (orderings r).map (u ++ ·)) ++
(orderings r).flatMap (fun v => (orderings l).map (v ++ ·))
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:82
def adjScore (S : α → α → ℝ) : List α → ℝ
| a :: b :: t => S a b + adjScore S (b :: t)
| _ => 0
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:95
Uses 3 · Used by 2
DefinitionOptimal leaf-ordering score with fixed end leaves#✓fully proved
The best score among the leaf orders of t that start with i and end with j
(⊥ if there is none).
noncomputable def optEnds [DecidableEq α] (S : α → α → ℝ) (t : Dendrogram α) (i j : α) :
WithBot ℝ :=
(((orderings t).filter (fun o => o.head? = some i ∧ o.getLast? = some j)).map
(adjScore S)).maximum
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
def orderings : Dendrogram α → List (List α)
| leaf a => [[a]]
| node l r =>
(orderings l).flatMap (fun u => (orderings r).map (u ++ ·)) ++
(orderings r).flatMap (fun v => (orderings l).map (v ++ ·))
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:82
def adjScore (S : α → α → ℝ) : List α → ℝ
| a :: b :: t => S a b + adjScore S (b :: t)
| _ => 0
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:95
DefinitionJoining two subtree orders at an adjacent leaf pair#✓fully proved
One side of the recursion: the left part ranges over orders of a subtree with leaves Ll
and best-score table Ml, the right part over a subtree with leaves Lr and table Mr; the
two are joined at the adjacent pair (k, l).
DefinitionBar-Joseph–Gifford–Jaakkola dynamic program for leaf ordering#✓fully proved
The dynamic program of Bar-Joseph, Gifford and Jaakkola: bestEnds S t i j is computed
from the tables of the two children, trying both child orders.
noncomputable def bestEnds [DecidableEq α] (S : α → α → ℝ) : Dendrogram α → α → α → WithBot ℝ
| leaf a, i, j => if i = a ∧ j = a then 0 else ⊥
| node l r, i, j =>
max (joinEnds S (bestEnds S l) (bestEnds S r) (leaves l) (leaves r) i j)
(joinEnds S (bestEnds S r) (bestEnds S l) (leaves r) (leaves l) i j)
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
noncomputable def joinEnds (S : α → α → ℝ) (Ml Mr : α → α → WithBot ℝ) (Ll Lr : List α)
(i j : α) : WithBot ℝ :=
(Ll.flatMap fun k => Lr.map fun l => Ml i k + ((S k l : ℝ) : WithBot ℝ) + Mr l j).foldr
max ⊥
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:113
def leaves : Dendrogram α → List α
| leaf a => [a]
| node l r => leaves l ++ leaves r
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:71
TheoremA dendrogram with m internal nodes has \(2^m\) leaf orders#✓fully proved
A dendrogram with m internal nodes has 2 ^ m leaf orders (one per flip pattern).
theorem length_orderings (t : Dendrogram α) : (orderings t).length = 2 ^ numInternal t
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
def orderings : Dendrogram α → List (List α)
| leaf a => [[a]]
| node l r =>
(orderings l).flatMap (fun u => (orderings r).map (u ++ ·)) ++
(orderings r).flatMap (fun v => (orderings l).map (v ++ ·))
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:82
def numInternal : Dendrogram α → ℕ
| leaf _ => 0
| node l r => numInternal l + numInternal r + 1
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:76
Uses 3 · Used by 1
TheoremLeaf orders are permutations of the leaves#✓fully proved
Every leaf order of t is a permutation of its leaves.
theorem perm_of_mem_orderings {t : Dendrogram α} {o : List α} (h : o ∈ orderings t) :
o.Perm (leaves t)
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
def orderings : Dendrogram α → List (List α)
| leaf a => [[a]]
| node l r =>
(orderings l).flatMap (fun u => (orderings r).map (u ++ ·)) ++
(orderings r).flatMap (fun v => (orderings l).map (v ++ ·))
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:82
def leaves : Dendrogram α → List α
| leaf a => [a]
| node l r => leaves l ++ leaves r
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:71
Uses 3 · Used by 2
TheoremCorrectness of the optimal leaf ordering recursion#✓fully proved
Correctness of the optimal leaf ordering recursion (Bar-Joseph, Gifford and
Jaakkola 2001): the dynamic program computes, for every end pair (i, j), the best score of
a leaf order of t starting at i and ending at j.
theorem bestEnds_eq_optEnds [DecidableEq α] (S : α → α → ℝ) (t : Dendrogram α) (i j : α) :
bestEnds S t i j = optEnds S t i j
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
noncomputable def bestEnds [DecidableEq α] (S : α → α → ℝ) : Dendrogram α → α → α → WithBot ℝ
| leaf a, i, j => if i = a ∧ j = a then 0 else ⊥
| node l r, i, j =>
max (joinEnds S (bestEnds S l) (bestEnds S r) (leaves l) (leaves r) i j)
(joinEnds S (bestEnds S r) (bestEnds S l) (leaves r) (leaves l) i j)
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:120
noncomputable def optEnds [DecidableEq α] (S : α → α → ℝ) (t : Dendrogram α) (i j : α) :
WithBot ℝ :=
(((orderings t).filter (fun o => o.head? = some i ∧ o.getLast? = some j)).map
(adjScore S)).maximum
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:105
Uses 8 · Used by 1
TheoremOptimal leaf-ordering score via the dynamic program#✓fully proved
The optimal leaf-ordering score is the best bestEnds value over end pairs of leaves.
theorem optScore_eq_sup_bestEnds [DecidableEq α] (S : α → α → ℝ) (t : Dendrogram α) :
optScore S t =
((leaves t).flatMap fun i => (leaves t).map fun j => bestEnds S t i j).foldr max ⊥
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
noncomputable def optScore (S : α → α → ℝ) (t : Dendrogram α) : WithBot ℝ :=
((orderings t).map (adjScore S)).maximum
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:100
def leaves : Dendrogram α → List α
| leaf a => [a]
| node l r => leaves l ++ leaves r
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:71
noncomputable def bestEnds [DecidableEq α] (S : α → α → ℝ) : Dendrogram α → α → α → WithBot ℝ
| leaf a, i, j => if i = a ∧ j = a then 0 else ⊥
| node l r, i, j =>
max (joinEnds S (bestEnds S l) (bestEnds S r) (leaves l) (leaves r) i j)
(joinEnds S (bestEnds S r) (bestEnds S l) (leaves r) (leaves l) i j)
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:120
TheoremOptimal leaf-ordering score is finite#✓fully proved
Every dendrogram has a leaf order, so the optimal score is a real number.
theorem optScore_ne_bot (S : α → α → ℝ) (t : Dendrogram α) : optScore S t ≠ ⊥
inductive Dendrogram (α : Type*) where
/-- A single object. -/
| leaf : α → Dendrogram α
/-- The merge of two clusters. -/
| node : Dendrogram α → Dendrogram α → Dendrogram α
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:60
noncomputable def optScore (S : α → α → ℝ) (t : Dendrogram α) : WithBot ℝ :=
((orderings t).map (adjScore S)).maximum
CSLibExt/Bioinformatics/Clustering/OptimalLeafOrdering.lean:100
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.