Skip to content

Commit 8740bbd

Browse files
committed
Add methods to count nodes with pre-allocated stack
1 parent c0d051c commit 8740bbd

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/DynamicExpressions.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ using Reexport
1414
@reexport import .EquationModule: Node, string_tree, print_tree, copy_node, set_node!
1515
@reexport import .EquationUtilsModule:
1616
count_nodes,
17+
count_nodes_with_stack,
1718
count_constants,
1819
count_depth,
1920
NodeIndex,

src/EquationUtils.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,44 @@ module EquationUtilsModule
22

33
import ..EquationModule: Node, copy_node
44

5+
"""
6+
count_nodes_with_stack(tree::Node{T}, preallocated_stack)::Int where {T}
7+
8+
Count the number of nodes in the tree, using a stack instead of
9+
recursion. While counting nodes is a quick task already, for further
10+
speed, using a pre-allocated stack can be signficantly faster,
11+
especially if you can re-use the same stack for multiple calls.
12+
13+
# Arguments
14+
- `tree::Node{T}`: The tree to count the nodes of.
15+
- `preallocated_stack::Vector{Node{T}}`: A pre-allocated stack
16+
to use for the counting. This should have a length of the
17+
potential max depth of a tree. e.g., you can initialize this
18+
with `Array{Node{T}}(undef, 100)` for a max depth of 100.
19+
"""
20+
function count_nodes_with_stack(
21+
tree::Node{T}, preallocated_stack::Vector{Node{T}}
22+
)::Int where {T}
23+
preallocated_stack[1] = tree
24+
count = 0
25+
i = 1
26+
while i !== 0
27+
head = preallocated_stack[i]
28+
i -= 1
29+
count += 1
30+
if head.degree == 1
31+
i += 1
32+
preallocated_stack[i] = head.l
33+
elseif head.degree == 2
34+
i += 1
35+
preallocated_stack[i] = head.l
36+
i += 1
37+
preallocated_stack[i] = head.r
38+
end
39+
end
40+
return count
41+
end
42+
543
"""
644
count_nodes(tree::Node{T})::Int where {T}
745

test/test_tree_construction.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ for unaop in [cos, exp, safe_log, safe_log2, safe_log10, safe_sqrt, relu, gamma,
3838

3939
# Test Basics
4040
@test n == 9
41+
@test n == count_nodes_with_stack(const_tree, Vector{typeof(const_tree)}(undef, 100))
4142
@test result == true_result
4243

4344
types_to_test = [Float32, Float64, BigFloat]

0 commit comments

Comments
 (0)