Skip to content

Commit 16264a3

Browse files
authored
BicoloredRootedTreeIterator is canonical (#73)
* BicoloredRootedTreeIterator is canonical; fixes #72 * bump patch version
1 parent e1375a0 commit 16264a3

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "RootedTrees"
22
uuid = "47965b36-3f3e-11e9-0dcf-4570dfd42a8c"
33
authors = ["Hendrik Ranocha <mail@ranocha.de> and contributors"]
4-
version = "2.9.1-pre"
4+
version = "2.9.1"
55

66
[deps]
77
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"

src/RootedTrees.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,26 @@ function canonical_representation!(t::RootedTree{Int, Vector{Int}})
446446
end
447447

448448

449+
"""
450+
check_canonical(t::AbstractRootedTree)
451+
452+
Check whether `t` is in canonical representation.
453+
454+
!!! warn "Internal interface"
455+
This function is considered to be an internal implementation detail and
456+
will not necessarily be stable.
457+
"""
458+
function check_canonical(t::AbstractRootedTree)
459+
for subtree in SubtreeIterator(t)
460+
if !check_canonical(subtree)
461+
return false
462+
end
463+
end
464+
465+
return issorted(SubtreeIterator(t), rev=true)
466+
end
467+
468+
449469
"""
450470
normalize_root!(t::AbstractRootedTree, root=one(eltype(t.level_sequence)))
451471

src/colored_trees.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,21 @@ end
395395
inner_state, color_id = state
396396

397397
# If we can iterate more by changing the color sequence, let's do so.
398-
if color_id < iter.number_of_colors
398+
while color_id < iter.number_of_colors
399399
binary_digits!(iter.t.color_sequence, color_id)
400-
return (iter.t, (inner_state, color_id + 1))
400+
401+
# This simple enumeration of all possible colors can also yield colored
402+
# trees that are not in canonical representation. For example, the trees
403+
# rootedtree([1, 2, 2], Bool[0, 0, 1])
404+
# rootedtree([1, 2, 2], Bool[1, 0, 1])
405+
# are not in canonical representation.
406+
# TODO: ColoredRootedTrees. Is there a more efficient way to get only
407+
# canonical representations?
408+
if check_canonical(iter.t)
409+
return (iter.t, (inner_state, color_id + 1))
410+
else
411+
color_id = color_id + 1
412+
end
401413
end
402414

403415
# Now, we need to iterate to a new baseline (uncolored) tree - if possible

test/runtests.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,18 @@ end # @testset "RootedTree"
792792
num += 1
793793
end
794794
# number of plain rooted trees times number of possible color sequences
795-
@test num == number_of_rooted_trees[order] * 2^order
795+
# <= since not all possible color sequences are in canonical representation
796+
@test num <= number_of_rooted_trees[order] * 2^order
797+
end
798+
end
799+
800+
# https://github.com/SciML/RootedTrees.jl/issues/72
801+
@testset "BicoloredRootedTreeIterator is canonical" begin
802+
for o in 1:10
803+
for t_iterator in BicoloredRootedTreeIterator(o)
804+
t_canonical = RootedTrees.canonical_representation(t_iterator)
805+
@test t_iterator == t_canonical
806+
end
796807
end
797808
end
798809

0 commit comments

Comments
 (0)