Skip to content

Commit 26eeb55

Browse files
authored
in-place butcher_product! (#175)
* in-place butcher_product! * fix typo * fix typo * fix typo
1 parent 85c2742 commit 26eeb55

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

Project.toml

+1-1
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 <[email protected]> and contributors"]
4-
version = "2.21.1"
4+
version = "2.22.0"
55

66
[deps]
77
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"

src/RootedTrees.jl

+40
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export butcher_representation, elementary_differential_latexstring,
2222

2323
export α, β, γ, density, σ, symmetry, order, root_color
2424

25+
export butcher_product!
26+
2527
export residual_order_condition, elementary_weight, derivative_weight
2628

2729
export count_trees
@@ -1342,6 +1344,8 @@ end
13421344
The non-associative Butcher product of rooted trees. It is formed
13431345
by adding an edge from the root of `t1` to the root of `t2`.
13441346
1347+
See also [`butcher_product!`](@ref).
1348+
13451349
Reference: Section 301 of
13461350
- Butcher, John Charles.
13471351
Numerical methods for ordinary differential equations.
@@ -1353,6 +1357,42 @@ function Base.:∘(t1::RootedTree, t2::RootedTree)
13531357
rootedtree(level_sequence)
13541358
end
13551359

1360+
"""
1361+
butcher_product!(t::RootedTree, t1::RootedTree, t2::RootedTree)
1362+
1363+
Compute the non-associative Butcher product `t = t1 ∘ t2` of rooted trees
1364+
in-place. It is formed by adding an edge from the root of `t1` to the root
1365+
of `t2`.
1366+
1367+
See also [`∘`](@ref) (available as `\\circ` plus TAB).
1368+
1369+
Reference: Section 301 of
1370+
- Butcher, John Charles.
1371+
Numerical methods for ordinary differential equations.
1372+
John Wiley & Sons, 2016.
1373+
"""
1374+
function butcher_product!(t::RootedTree, t1::RootedTree, t2::RootedTree)
1375+
offset = first(t1.level_sequence) - first(t2.level_sequence) + 1
1376+
1377+
unsafe_resize!(t, order(t1) + order(t2))
1378+
i = firstindex(t.level_sequence)
1379+
j = firstindex(t1.level_sequence)
1380+
while j <= lastindex(t1.level_sequence)
1381+
t.level_sequence[i] = t1.level_sequence[j]
1382+
i += 1
1383+
j += 1
1384+
end
1385+
j = firstindex(t2.level_sequence)
1386+
while j <= lastindex(t2.level_sequence)
1387+
t.level_sequence[i] = t2.level_sequence[j] + offset
1388+
i += 1
1389+
j += 1
1390+
end
1391+
1392+
canonical_representation!(t)
1393+
return t
1394+
end
1395+
13561396
"""
13571397
butcher_representation(t::RootedTree)
13581398

test/runtests.jl

+43
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ using Aqua: Aqua
312312
@inferred α(t1)
313313
@inferred β(t1)
314314
@inferred t1 t1
315+
t_result = copy(t1)
316+
@inferred butcher_product!(t_result, t1, t1)
317+
@test t_result == t1 t1
315318

316319
t2 = rootedtree([1, 2])
317320
@test order(t2) == 2
@@ -320,6 +323,8 @@ using Aqua: Aqua
320323
@test α(t2) == 1
321324
@test β(t2) == α(t2) * γ(t2)
322325
@test t2 == t1 t1
326+
@inferred butcher_product!(t_result, t1, t1)
327+
@test t2 == t_result
323328
@test butcher_representation(t2) == "[τ]"
324329
latex_string = "\\rootedtree[.[.]]"
325330
@test RootedTrees.latexify(t2) == latex_string
@@ -335,6 +340,8 @@ using Aqua: Aqua
335340
@test α(t3) == 1
336341
@test β(t3) == α(t3) * γ(t3)
337342
@test t3 == t2 t1
343+
@inferred butcher_product!(t_result, t2, t1)
344+
@test t3 == t_result
338345
@test butcher_representation(t3) == "[τ²]"
339346
latex_string = "\\rootedtree[.[.][.]]"
340347
@test RootedTrees.latexify(t3) == latex_string
@@ -350,6 +357,8 @@ using Aqua: Aqua
350357
@test α(t4) == 1
351358
@test β(t4) == α(t4) * γ(t4)
352359
@test t4 == t1 t2
360+
@inferred butcher_product!(t_result, t1, t2)
361+
@test t4 == t_result
353362
@test butcher_representation(t4) == "[[τ]]"
354363
latex_string = "\\rootedtree[.[.[.]]]"
355364
@test RootedTrees.latexify(t4) == latex_string
@@ -365,6 +374,8 @@ using Aqua: Aqua
365374
@test α(t5) == 1
366375
@test β(t5) == α(t5) * γ(t5)
367376
@test t5 == t3 t1
377+
@inferred butcher_product!(t_result, t3, t1)
378+
@test t5 == t_result
368379
@test butcher_representation(t5) == "[τ³]"
369380
@test RootedTrees.subtrees(t5) ==
370381
[rootedtree([2]), rootedtree([2]), rootedtree([2])]
@@ -380,6 +391,10 @@ using Aqua: Aqua
380391
@test α(t6) == 3
381392
@test β(t6) == α(t6) * γ(t6)
382393
@test t6 == t2 t2 == t4 t1
394+
@inferred butcher_product!(t_result, t2, t2)
395+
@test t6 == t_result
396+
@inferred butcher_product!(t_result, t4, t1)
397+
@test t6 == t_result
383398
@test butcher_representation(t6) == "[[τ]τ]"
384399
@test RootedTrees.subtrees(t6) == [rootedtree([2, 3]), rootedtree([2])]
385400
@test elementary_differential_latexstring(t6) ==
@@ -393,6 +408,8 @@ using Aqua: Aqua
393408
@test γ(t7) == 12
394409
@test β(t7) == α(t7) * γ(t7)
395410
@test t7 == t1 t3
411+
@inferred butcher_product!(t_result, t1, t3)
412+
@test t7 == t_result
396413
@test butcher_representation(t7) == "[[τ²]]"
397414
@test elementary_differential_latexstring(t7) ==
398415
L"$f^{\prime}f^{\prime\prime}(f, f)$"
@@ -404,6 +421,8 @@ using Aqua: Aqua
404421
@test γ(t8) == 24
405422
@test α(t8) == 1
406423
@test t8 == t1 t4
424+
@inferred butcher_product!(t_result, t1, t4)
425+
@test t8 == t_result
407426
@test butcher_representation(t8) == "[[[τ]]]"
408427
@test elementary_differential_latexstring(t8) ==
409428
L"$f^{\prime}f^{\prime}f^{\prime}f$"
@@ -417,6 +436,8 @@ using Aqua: Aqua
417436
@test α(t9) == 1
418437
@test β(t9) == α(t9) * γ(t9)
419438
@test t9 == t5 t1
439+
@inferred butcher_product!(t_result, t5, t1)
440+
@test t9 == t_result
420441
@test butcher_representation(t9) == "[τ⁴]"
421442
@test elementary_differential_latexstring(t9) == L"$f^{(4)}(f, f, f, f)$"
422443
@test elementary_weight_latexstring(t9) == L"$\sum_{d}b_{d}c_{d}^{4}$"
@@ -428,6 +449,10 @@ using Aqua: Aqua
428449
@test α(t10) == 6
429450
@test β(t10) == α(t10) * γ(t10)
430451
@test t10 == t3 t2 == t6 t1
452+
@inferred butcher_product!(t_result, t3, t2)
453+
@test t10 == t_result
454+
@inferred butcher_product!(t_result, t6, t1)
455+
@test t10 == t_result
431456
@test butcher_representation(t10) == "[[τ]τ²]"
432457
@test elementary_differential_latexstring(t10) ==
433458
L"$f^{\prime\prime\prime}(f^{\prime}f, f, f)$"
@@ -440,6 +465,10 @@ using Aqua: Aqua
440465
@test γ(t11) == 15
441466
@test α(t11) == 4
442467
@test t11 == t2 t3 == t7 t1
468+
@inferred butcher_product!(t_result, t2, t3)
469+
@test t11 == t_result
470+
@inferred butcher_product!(t_result, t7, t1)
471+
@test t11 == t_result
443472
@test butcher_representation(t11) == "[[τ²]τ]"
444473
@test elementary_differential_latexstring(t11) ==
445474
L"$f^{\prime\prime}(f^{\prime\prime}(f, f), f)$"
@@ -453,6 +482,10 @@ using Aqua: Aqua
453482
@test α(t12) == 4
454483
@test β(t12) == α(t12) * γ(t12)
455484
@test t12 == t2 t4 == t8 t1
485+
@inferred butcher_product!(t_result, t2, t4)
486+
@test t12 == t_result
487+
@inferred butcher_product!(t_result, t8, t1)
488+
@test t12 == t_result
456489
@test butcher_representation(t12) == "[[[τ]]τ]"
457490
@test elementary_differential_latexstring(t12) ==
458491
L"$f^{\prime\prime}(f^{\prime}f^{\prime}f, f)$"
@@ -466,6 +499,8 @@ using Aqua: Aqua
466499
@test α(t13) == 3
467500
@test β(t13) == α(t13) * γ(t13)
468501
@test t13 == t4 t2
502+
@inferred butcher_product!(t_result, t4, t2)
503+
@test t13 == t_result
469504
@test butcher_representation(t13) == "[[τ][τ]]"
470505
@test elementary_differential_latexstring(t13) ==
471506
L"$f^{\prime\prime}(f^{\prime}f, f^{\prime}f)$"
@@ -479,6 +514,8 @@ using Aqua: Aqua
479514
@test α(t14) == 1
480515
@test β(t14) == α(t14) * γ(t14)
481516
@test t14 == t1 t5
517+
@inferred butcher_product!(t_result, t1, t5)
518+
@test t14 == t_result
482519
@test butcher_representation(t14) == "[[τ³]]"
483520
@test elementary_differential_latexstring(t14) ==
484521
L"$f^{\prime}f^{\prime\prime\prime}(f, f, f)$"
@@ -492,6 +529,8 @@ using Aqua: Aqua
492529
@test α(t15) == 3
493530
@test β(t15) == α(t15) * γ(t15)
494531
@test t15 == t1 t6
532+
@inferred butcher_product!(t_result, t1, t6)
533+
@test t15 == t_result
495534
@test butcher_representation(t15) == "[[[τ]τ]]"
496535
@test elementary_differential_latexstring(t15) ==
497536
L"$f^{\prime}f^{\prime\prime}(f^{\prime}f, f)$"
@@ -505,6 +544,8 @@ using Aqua: Aqua
505544
@test α(t16) == 1
506545
@test β(t16) == α(t16) * γ(t16)
507546
@test t16 == t1 t7
547+
@inferred butcher_product!(t_result, t1, t7)
548+
@test t16 == t_result
508549
@test butcher_representation(t16) == "[[[τ²]]]"
509550
@test elementary_differential_latexstring(t16) ==
510551
L"$f^{\prime}f^{\prime}f^{\prime\prime}(f, f)$"
@@ -518,6 +559,8 @@ using Aqua: Aqua
518559
@test α(t17) == 1
519560
@test β(t17) == α(t17) * γ(t17)
520561
@test t17 == t1 t8
562+
@inferred butcher_product!(t_result, t1, t8)
563+
@test t17 == t_result
521564
@test butcher_representation(t17) == "[[[[τ]]]]"
522565
@test elementary_differential_latexstring(t17) ==
523566
L"$f^{\prime}f^{\prime}f^{\prime}f^{\prime}f$"

0 commit comments

Comments
 (0)