Skip to content

Commit 5743abd

Browse files
committed
improve performance of partition skeleton a bit
1 parent bba9f11 commit 5743abd

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

src/RootedTrees.jl

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ function partition_forest!(forest, level_sequence, edge_set)
588588
push!(forest, subtree)
589589
deleteat!(level_sequence, subtree_root_index:subtree_last_index)
590590
deleteat!(edge_set, subtree_root_index-1:subtree_last_index-1)
591+
591592
edge_to_remove = findlast(==(false), edge_set)
592593
end
593594
push!(forest, rootedtree(level_sequence))
@@ -725,38 +726,41 @@ function partition_skeleton(t::RootedTree, edge_set)
725726

726727
edge_set_copy = copy(edge_set)
727728
skeleton = RootedTree(copy(t.level_sequence), true)
728-
return partition_skeleton!(skeleton, edge_set_copy)
729+
return partition_skeleton!(skeleton.level_sequence, edge_set_copy)
729730
end
730731

731732
# internal in-place version of partition_skeleton modifying the inputs
732-
function partition_skeleton!(skeleton::RootedTree, edge_set)
733-
ls = skeleton.level_sequence
734-
735-
while any(edge_set)
736-
# Find next edge to contract
737-
subtree_root_index = findfirst(==(true), edge_set) + 1
738-
733+
function partition_skeleton!(level_sequence, edge_set)
734+
# Iterate over all edges that shall be kept/contracted.
735+
# We start the iteration at the end since this will result in less memory
736+
# moves because we have already reduced the size of the vectors when reaching
737+
# the beginning.
738+
edge_to_contract = findlast(edge_set)
739+
while edge_to_contract !== nothing
739740
# Contract the corresponding edge by removing the subtree root and promoting
740-
# the rest of the subtree
741+
# the rest of the subtree.
742+
# Remember the convention node = edge + 1
743+
subtree_root_index = edge_to_contract + 1
741744
subtree_last_index = subtree_root_index + 1
742-
while subtree_last_index <= length(ls)
743-
if ls[subtree_last_index] > ls[subtree_root_index]
744-
ls[subtree_last_index] -= 1
745+
while subtree_last_index <= length(level_sequence)
746+
if level_sequence[subtree_last_index] > level_sequence[subtree_root_index]
747+
level_sequence[subtree_last_index] -= 1
745748
subtree_last_index += 1
746749
else
747750
break
748751
end
749752
end
753+
750754
# Remove the root node
751-
deleteat!(ls, subtree_root_index)
752-
deleteat!(edge_set, subtree_root_index-1)
755+
deleteat!(level_sequence, subtree_root_index)
756+
deleteat!(edge_set, edge_to_contract)
757+
758+
edge_to_contract = findlast(edge_set)
753759
end
754760

755-
# The level sequence `ls` will not automatically be a canonical representation.
756-
# TODO: partitions;
757-
# Decide whether canonical representations should be used. Disabling
758-
# them will increase the performance.
759-
return rootedtree!(ls)
761+
# The level sequence `level_sequence` will not automatically be a canonical
762+
# representation.
763+
return rootedtree!(level_sequence)
760764
end
761765

762766

@@ -861,7 +865,7 @@ function Base.iterate(partitions::PartitionIterator, edge_set_value)
861865
copy!(edge_set_tmp, edge_set)
862866
resize!(skeleton.level_sequence, order(t))
863867
copy!(skeleton.level_sequence, t.level_sequence)
864-
partition_skeleton!(skeleton, edge_set_tmp)
868+
partition_skeleton!(skeleton.level_sequence, edge_set_tmp)
865869

866870
# Compute the partition forest.
867871
# The following is a more efficient version of

0 commit comments

Comments
 (0)