@@ -6,7 +6,7 @@ using LinearAlgebra
6
6
import Base: show, isless, == , iterate, copy
7
7
8
8
9
- export RootedTree , RootedTreeIterator
9
+ export rootedtree , RootedTreeIterator
10
10
11
11
export α, β, γ, σ, order, residual_order_condition, elementary_weight, derivative_weight
12
12
@@ -15,7 +15,7 @@ export count_trees
15
15
16
16
17
17
"""
18
- RootedTree{T<:Integer}
18
+ RootedTree
19
19
20
20
Represents a rooted tree using its level sequence.
21
21
@@ -24,18 +24,33 @@ Reference:
24
24
"Constant time generation of rooted trees."
25
25
SIAM Journal on Computing 9.4 (1980): 706-712.
26
26
"""
27
- struct RootedTree{T<: Integer , V<: AbstractVector }
27
+ mutable struct RootedTree{T<: Integer , V<: AbstractVector }
28
28
level_sequence:: V
29
+ iscanonical:: Bool
29
30
end
30
31
31
- function RootedTree (level_sequence:: AbstractVector )
32
+ function RootedTree (level_sequence:: AbstractVector , iscanonical = false )
32
33
T = eltype (level_sequence)
33
34
V = typeof (level_sequence)
34
- RootedTree {T,V} (level_sequence)
35
+ RootedTree {T,V} (level_sequence, iscanonical )
35
36
end
37
+
38
+ """
39
+ rootedtree
40
+
41
+ Construct a canonical `RootedTree` object from a level sequence.
42
+
43
+ Reference:
44
+ Beyer, Terry, and Sandra Mitchell Hedetniemi.
45
+ "Constant time generation of rooted trees."
46
+ SIAM Journal on Computing 9.4 (1980): 706-712.
47
+ """
48
+ rootedtree (level_sequence:: AbstractVector ) = canonical_representation (RootedTree (level_sequence))
49
+
50
+ iscanonical (t:: RootedTree ) = t. iscanonical
36
51
# TODO : Validate rooted tree in constructor?
37
52
38
- copy (t:: RootedTree ) = RootedTree (copy (t. level_sequence))
53
+ copy (t:: RootedTree ) = RootedTree (copy (t. level_sequence), t . iscanonical )
39
54
40
55
41
56
# #function RootedTree(sequence::Vector{T}, valid::Bool)
@@ -86,7 +101,7 @@ function ==(t1::RootedTree, t2::RootedTree)
86
101
end
87
102
88
103
89
- # generation and caonical representation
104
+ # generation and canonical representation
90
105
"""
91
106
canonical_representation!(t::RootedTree)
92
107
@@ -105,6 +120,7 @@ function canonical_representation!(t::RootedTree)
105
120
t. level_sequence[i: i+ order (τ)- 1 ] = τ. level_sequence[:]
106
121
i += order (τ)
107
122
end
123
+ t. iscanonical = true
108
124
109
125
t
110
126
end
@@ -133,7 +149,7 @@ struct RootedTreeIterator{T<:Integer}
133
149
t:: RootedTree{T,Vector{T}}
134
150
135
151
function RootedTreeIterator (order:: T ) where {T<: Integer }
136
- new {T} (order, RootedTree (Vector {T} (one (T): order)))
152
+ new {T} (order, RootedTree (Vector {T} (one (T): order), true ))
137
153
end
138
154
end
139
155
@@ -154,6 +170,7 @@ function iterate(iter::RootedTreeIterator{T}, state) where {T}
154
170
p = i
155
171
end
156
172
end
173
+ p == 1 && return nothing
157
174
158
175
level_q = iter. t. level_sequence[p] - one (T)
159
176
@inbounds for i in 1 : p
@@ -162,8 +179,6 @@ function iterate(iter::RootedTreeIterator{T}, state) where {T}
162
179
end
163
180
end
164
181
165
- p == 1 && return nothing
166
-
167
182
@inbounds for i in p: length (iter. t. level_sequence)
168
183
iter. t. level_sequence[i] = iter. t. level_sequence[i - (p- q)]
169
184
end
192
207
struct Subtrees{T<: Integer } <: AbstractVector{RootedTree{T}}
193
208
level_sequence:: Vector{T}
194
209
indices:: Vector{T}
210
+ iscanonical:: Bool
195
211
196
212
function Subtrees (t:: RootedTree{T} ) where {T}
197
213
level_sequence = t. level_sequence
@@ -211,12 +227,12 @@ struct Subtrees{T<:Integer} <: AbstractVector{RootedTree{T}}
211
227
# in order to get the stopping index for the last subtree
212
228
push! (indices, length (level_sequence)+ 1 )
213
229
214
- new {T} (level_sequence, indices)
230
+ new {T} (level_sequence, indices, iscanonical (t) )
215
231
end
216
232
end
217
233
218
234
Base. size (s:: Subtrees ) = (length (s. indices)- 1 , )
219
- Base. getindex (s:: Subtrees , i:: Int ) = RootedTree (view (s. level_sequence, s. indices[i]: s. indices[i+ 1 ]- 1 ))
235
+ Base. getindex (s:: Subtrees , i:: Int ) = RootedTree (view (s. level_sequence, s. indices[i]: s. indices[i+ 1 ]- 1 ), s . iscanonical )
220
236
221
237
222
238
"""
@@ -225,7 +241,7 @@ Base.getindex(s::Subtrees, i::Int) = RootedTree(view(s.level_sequence, s.indices
225
241
Returns a vector of all subtrees of `t`.
226
242
"""
227
243
function subtrees (t:: RootedTree{T} ) where {T}
228
- subtr = RootedTree{T} []
244
+ subtr = typeof (t) []
229
245
230
246
if length (t. level_sequence) < 2
231
247
return subtr
@@ -255,25 +271,22 @@ order(t::RootedTree) = length(t.level_sequence)
255
271
256
272
257
273
"""
258
- σ(t::RootedTree, is_canonical::Bool = false )
274
+ σ(t::RootedTree)
259
275
260
276
The symmetry `σ` of a rooted tree `t`, i.e. the order of the group of automorphisms
261
277
on a particular labelling (of the vertices) of `t`.
262
278
263
- If `is_canonical`, it is assumed that `t` is given using the canonical
264
- representation.
265
-
266
279
Reference: Section 301 of
267
280
Butcher, John Charles.
268
281
Numerical methods for ordinary differential equations.
269
282
John Wiley & Sons, 2008.
270
283
"""
271
- function σ (t:: RootedTree , is_canonical = false )
284
+ function σ (t:: RootedTree )
272
285
if order (t) == 1 || order (t) == 2
273
286
return 1
274
287
end
275
288
276
- if ! is_canonical
289
+ if ! iscanonical (t)
277
290
t = canonical_representation (t)
278
291
end
279
292
@@ -325,16 +338,13 @@ end
325
338
326
339
The number of monotonic labellings of `t` not equivalent under the symmetry group.
327
340
328
- If `is_canonical`, it is assumed that `t` is given using the canonical
329
- representation.
330
-
331
341
Reference: Section 302 of
332
342
Butcher, John Charles.
333
343
Numerical methods for ordinary differential equations.
334
344
John Wiley & Sons, 2008.
335
345
"""
336
- function α (t:: RootedTree , is_canonical = false )
337
- div (factorial (order (t)), σ (t, is_canonical )* γ (t))
346
+ function α (t:: RootedTree )
347
+ div (factorial (order (t)), σ (t)* γ (t))
338
348
end
339
349
340
350
@@ -343,16 +353,13 @@ end
343
353
344
354
The total number of labellings of `t` not equivalent under the symmetry group.
345
355
346
- If `is_canonical`, it is assumed that `t` is given using the canonical
347
- representation.
348
-
349
356
Reference: Section 302 of
350
357
Butcher, John Charles.
351
358
Numerical methods for ordinary differential equations.
352
359
John Wiley & Sons, 2008.
353
360
"""
354
- function β (t:: RootedTree , is_canonical = false )
355
- div (factorial (order (t)), σ (t, is_canonical ))
361
+ function β (t:: RootedTree )
362
+ div (factorial (order (t)), σ (t))
356
363
end
357
364
358
365
@@ -404,27 +411,24 @@ end
404
411
405
412
406
413
"""
407
- residual_order_condition(t::RootedTree, A, b, c, is_canonical=false )
414
+ residual_order_condition(t::RootedTree, A, b, c)
408
415
409
416
The residual of the order condition
410
417
`(Φ(t) - 1/γ(t)) / σ(t)`
411
418
with elementary weight `Φ(t)`, density `γ(t)`, and symmetry `σ(t)` of the
412
419
rooted tree `t` for the Runge-Kutta method with Butcher coefficients
413
420
`A, b, c`.
414
421
415
- If `is_canonical`, it is assumed that `t` is given using the canonical
416
- representation.
417
-
418
422
Reference: Section 315 of
419
423
Butcher, John Charles.
420
424
Numerical methods for ordinary differential equations.
421
425
John Wiley & Sons, 2008.
422
426
"""
423
- function residual_order_condition (t:: RootedTree , A, b, c, is_canonical = false )
427
+ function residual_order_condition (t:: RootedTree , A, b, c)
424
428
ew = elementary_weight (t, A, b, c)
425
429
T = typeof (ew)
426
430
427
- (ew - one (T) / γ (t)) / σ (t, is_canonical )
431
+ (ew - one (T) / γ (t)) / σ (t)
428
432
end
429
433
430
434
0 commit comments