Skip to content

Commit 4dae839

Browse files
pw0lfranocha
andauthored
Elementary Differentials as LaTeXString (#140)
* Added function that returns the elementary differentials as latexstrings * Now using \prime instead of ' * Implemented requested changes * Update LaTeXStrings version in Project.toml Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com> * Update docstrings for elementary_differential in src/RootedTrees.jl Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com> * Update test/Project.toml Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com> * Added whitespace after comma. Changed that for the tests, too. Added picture of rendered LaTeXStrings to docs * Changes by formatter --------- Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com>
1 parent ac028b4 commit 4dae839

File tree

6 files changed

+99
-11
lines changed

6 files changed

+99
-11
lines changed

Project.toml

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

66
[deps]
7+
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
78
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
89
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
910
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
@@ -17,6 +18,7 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1718
PlotsExt = "Plots"
1819

1920
[compat]
21+
LaTeXStrings = "1"
2022
Latexify = "0.15, 0.16"
2123
LinearAlgebra = "1"
2224
Plots = "1"

docs/make.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ DocMeta.setdocmeta!(RootedTrees,
1818
# as necessary
1919
open(joinpath(@__DIR__, "src", "license.md"), "w") do io
2020
# Point to source license file
21-
println(io, """
21+
println(io,
22+
"""
2223
```@meta
2324
EditURL = "https://github.com/SciML/RootedTrees.jl/blob/main/LICENSE.md"
2425
```
@@ -34,7 +35,8 @@ end
3435

3536
open(joinpath(@__DIR__, "src", "contributing.md"), "w") do io
3637
# Point to source license file
37-
println(io, """
38+
println(io,
39+
"""
3840
```@meta
3941
EditURL = "https://github.com/SciML/RootedTrees.jl/blob/main/CONTRIBUTING.md"
4042
```

docs/src/tutorials/basics.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ savefig("basics_tree.png"); nothing # hide
7373

7474
![](basics_tree.png)
7575

76+
To get the elementary differential, corresponding to a `RootedTree`, as a [`LaTeXString`](https://github.com/JuliaStrings/LaTeXStrings.jl), you can use [`elementary_differential`](@ref).
77+
78+
```@example basics
79+
for t in RootedTreeIterator(4)
80+
println(elementary_differential(t))
81+
end
82+
```
83+
In LaTeX this results in the following output:
84+
85+
![latex-elementary_differentials](https://user-images.githubusercontent.com/125130707/282897199-4967fe07-a370-4d64-b671-84f578a52391.png)
86+
7687

7788
## Number of trees
7889

src/RootedTrees.jl

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ module RootedTrees
44

55
using LinearAlgebra: dot
66

7+
using LaTeXStrings: latexstring
8+
79
using Latexify: Latexify
810
using Preferences: @set_preferences!, @load_preference
911
using RecipesBase: RecipesBase
@@ -15,7 +17,7 @@ end
1517
export RootedTree, rootedtree, rootedtree!, RootedTreeIterator,
1618
ColoredRootedTree, BicoloredRootedTree, BicoloredRootedTreeIterator
1719

18-
export butcher_representation
20+
export butcher_representation, elementary_differential
1921

2022
export α, β, γ, density, σ, symmetry, order, root_color
2123

@@ -25,7 +27,8 @@ export count_trees
2527

2628
export subtrees, SubtreeIterator
2729

28-
export partition_forest, PartitionForestIterator,
30+
export partition_forest,
31+
PartitionForestIterator,
2932
partition_skeleton,
3033
all_partitions, PartitionIterator
3134

@@ -1009,8 +1012,10 @@ end
10091012

10101013
Base.IteratorSize(::Type{<:PartitionIterator}) = Base.HasLength()
10111014
Base.length(partitions::PartitionIterator) = 2^length(partitions.edge_set)
1012-
function Base.eltype(::Type{PartitionIterator{TreeInput, TreeOutput}}) where {TreeInput,
1013-
TreeOutput}
1015+
function Base.eltype(::Type{
1016+
PartitionIterator{TreeInput, TreeOutput}
1017+
}) where {TreeInput,
1018+
TreeOutput}
10141019
Tuple{PartitionForestIterator{TreeOutput}, TreeOutput}
10151020
end
10161021

@@ -1053,10 +1058,13 @@ end
10531058
end
10541059

10551060
# necessary for simple and convenient use since the iterates may be modified
1056-
function Base.collect(partitions::PartitionIterator{TreeInput, TreeOutput}) where {
1057-
TreeInput,
1058-
TreeOutput
1059-
}
1061+
function Base.collect(partitions::PartitionIterator{
1062+
TreeInput,
1063+
TreeOutput
1064+
}) where {
1065+
TreeInput,
1066+
TreeOutput
1067+
}
10601068
iterates = Vector{Tuple{Vector{TreeOutput}, TreeOutput}}()
10611069
sizehint!(iterates, length(partitions))
10621070
for (forest, skeleton) in partitions
@@ -1413,6 +1421,42 @@ function butcher_representation(t::RootedTree, normalize::Bool = true)
14131421
return result
14141422
end
14151423

1424+
"""
1425+
elementary_differential(t::RootedTree)
1426+
1427+
Returns the elementary differential as a `LaTeXString`
1428+
from the package [LaTeXStrings.jl](https://github.com/JuliaStrings/LaTeXStrings.jl).
1429+
1430+
"""
1431+
function elementary_differential(t::RootedTree)
1432+
return latexstring(rec_elementary_differential(t))
1433+
end
1434+
1435+
# Function used to go recursively through the RootedTree
1436+
# to generate the elementary differential of the tree.
1437+
function rec_elementary_differential(t::RootedTree)
1438+
subtree_strings = String[]
1439+
for subtree in SubtreeIterator(t)
1440+
push!(subtree_strings, rec_elementary_differential(subtree))
1441+
end
1442+
k = length(subtree_strings)
1443+
if k == 0 # Special-Case: No Subtree
1444+
return "f"
1445+
elseif k == 1 # Special-Case: Just 1 Subtree. No () needed
1446+
return "f^{\\prime}" * subtree_strings[1]
1447+
end
1448+
if k in (2, 3) # For first, second and third derivative \prime is used. For the rest just the number of the derivative
1449+
el_diff = "f^{$("\\prime"^k)}("
1450+
else
1451+
el_diff = "f^{($(k))}("
1452+
end
1453+
for s in subtree_strings[1:(end - 1)]
1454+
el_diff *= s * ", "
1455+
end
1456+
el_diff *= subtree_strings[end] * ")"
1457+
return el_diff
1458+
end
1459+
14161460
include("colored_trees.jl")
14171461
include("latexify.jl")
14181462
include("plot_recipes.jl")

test/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
[deps]
22
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3+
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
34
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
45
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
56
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
67
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
78

89
[compat]
910
Aqua = "0.8"
11+
LaTeXStrings = "1"
1012
Plots = "1"
1113
StaticArrays = "1.3"
1214
UnicodePlots = "2, 3"

test/runtests.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ using RootedTrees.Latexify: latexify
77
using Plots: Plots, plot
88
Plots.unicodeplots()
99

10+
using LaTeXStrings: @L_str
11+
1012
using Aqua: Aqua
1113

1214
@testset "RootedTrees" begin
@@ -301,6 +303,7 @@ using Aqua: Aqua
301303
@test isempty(RootedTrees.subtrees(t1))
302304
@test butcher_representation(empty(t1)) == ""
303305
@test RootedTrees.latexify(empty(t1)) == "\\varnothing"
306+
@test elementary_differential(t1) == L"$f$"
304307

305308
@inferred order(t1)
306309
@inferred σ(t1)
@@ -321,6 +324,7 @@ using Aqua: Aqua
321324
@test RootedTrees.latexify(t2) == latex_string
322325
@test latexify(t2) == latex_string
323326
@test RootedTrees.subtrees(t2) == [rootedtree([2])]
327+
@test elementary_differential(t2) == L"$f^{\prime}f$"
324328

325329
t3 = rootedtree([1, 2, 2])
326330
@test order(t3) == 3
@@ -334,6 +338,7 @@ using Aqua: Aqua
334338
@test RootedTrees.latexify(t3) == latex_string
335339
@test latexify(t3) == latex_string
336340
@test RootedTrees.subtrees(t3) == [rootedtree([2]), rootedtree([2])]
341+
@test elementary_differential(t3) == L"$f^{\prime\prime}(f, f)$"
337342

338343
t4 = rootedtree([1, 2, 3])
339344
@test order(t4) == 3
@@ -347,6 +352,7 @@ using Aqua: Aqua
347352
@test RootedTrees.latexify(t4) == latex_string
348353
@test latexify(t4) == latex_string
349354
@test RootedTrees.subtrees(t4) == [rootedtree([2, 3])]
355+
@test elementary_differential(t4) == L"$f^{\prime}f^{\prime}f$"
350356

351357
t5 = rootedtree([1, 2, 2, 2])
352358
@test order(t5) == 4
@@ -358,6 +364,7 @@ using Aqua: Aqua
358364
@test butcher_representation(t5) == "[τ³]"
359365
@test RootedTrees.subtrees(t5) ==
360366
[rootedtree([2]), rootedtree([2]), rootedtree([2])]
367+
@test elementary_differential(t5) == L"$f^{\prime\prime\prime}(f, f, f)$"
361368

362369
t6 = rootedtree([1, 2, 2, 3])
363370
@inferred RootedTrees.subtrees(t6)
@@ -369,6 +376,7 @@ using Aqua: Aqua
369376
@test t6 == t2 t2 == t4 t1
370377
@test butcher_representation(t6) == "[[τ]τ]"
371378
@test RootedTrees.subtrees(t6) == [rootedtree([2, 3]), rootedtree([2])]
379+
@test elementary_differential(t6) == L"$f^{\prime\prime}(f^{\prime}f, f)$"
372380

373381
t7 = rootedtree([1, 2, 3, 3])
374382
@test order(t7) == 4
@@ -377,6 +385,7 @@ using Aqua: Aqua
377385
@test β(t7) == α(t7) * γ(t7)
378386
@test t7 == t1 t3
379387
@test butcher_representation(t7) == "[[τ²]]"
388+
@test elementary_differential(t7) == L"$f^{\prime}f^{\prime\prime}(f, f)$"
380389

381390
t8 = rootedtree([1, 2, 3, 4])
382391
@test order(t8) == 4
@@ -385,6 +394,7 @@ using Aqua: Aqua
385394
@test α(t8) == 1
386395
@test t8 == t1 t4
387396
@test butcher_representation(t8) == "[[[τ]]]"
397+
@test elementary_differential(t8) == L"$f^{\prime}f^{\prime}f^{\prime}f$"
388398

389399
t9 = rootedtree([1, 2, 2, 2, 2])
390400
@test order(t9) == 5
@@ -394,6 +404,7 @@ using Aqua: Aqua
394404
@test β(t9) == α(t9) * γ(t9)
395405
@test t9 == t5 t1
396406
@test butcher_representation(t9) == "[τ⁴]"
407+
@test elementary_differential(t9) == L"$f^{(4)}(f, f, f, f)$"
397408

398409
t10 = rootedtree([1, 2, 2, 2, 3])
399410
@test order(t10) == 5
@@ -403,6 +414,8 @@ using Aqua: Aqua
403414
@test β(t10) == α(t10) * γ(t10)
404415
@test t10 == t3 t2 == t6 t1
405416
@test butcher_representation(t10) == "[[τ]τ²]"
417+
@test elementary_differential(t10) ==
418+
L"$f^{\prime\prime\prime}(f^{\prime}f, f, f)$"
406419

407420
t11 = rootedtree([1, 2, 2, 3, 3])
408421
@test order(t11) == 5
@@ -411,6 +424,8 @@ using Aqua: Aqua
411424
@test α(t11) == 4
412425
@test t11 == t2 t3 == t7 t1
413426
@test butcher_representation(t11) == "[[τ²]τ]"
427+
@test elementary_differential(t11) ==
428+
L"$f^{\prime\prime}(f^{\prime\prime}(f, f), f)$"
414429

415430
t12 = rootedtree([1, 2, 2, 3, 4])
416431
@test order(t12) == 5
@@ -420,6 +435,8 @@ using Aqua: Aqua
420435
@test β(t12) == α(t12) * γ(t12)
421436
@test t12 == t2 t4 == t8 t1
422437
@test butcher_representation(t12) == "[[[τ]]τ]"
438+
@test elementary_differential(t12) ==
439+
L"$f^{\prime\prime}(f^{\prime}f^{\prime}f, f)$"
423440

424441
t13 = rootedtree([1, 2, 3, 2, 3])
425442
@test order(t13) == 5
@@ -429,6 +446,8 @@ using Aqua: Aqua
429446
@test β(t13) == α(t13) * γ(t13)
430447
@test t13 == t4 t2
431448
@test butcher_representation(t13) == "[[τ][τ]]"
449+
@test elementary_differential(t13) ==
450+
L"$f^{\prime\prime}(f^{\prime}f, f^{\prime}f)$"
432451

433452
t14 = rootedtree([1, 2, 3, 3, 3])
434453
@test order(t14) == 5
@@ -438,6 +457,8 @@ using Aqua: Aqua
438457
@test β(t14) == α(t14) * γ(t14)
439458
@test t14 == t1 t5
440459
@test butcher_representation(t14) == "[[τ³]]"
460+
@test elementary_differential(t14) ==
461+
L"$f^{\prime}f^{\prime\prime\prime}(f, f, f)$"
441462

442463
t15 = rootedtree([1, 2, 3, 3, 4])
443464
@test order(t15) == 5
@@ -447,6 +468,8 @@ using Aqua: Aqua
447468
@test β(t15) == α(t15) * γ(t15)
448469
@test t15 == t1 t6
449470
@test butcher_representation(t15) == "[[[τ]τ]]"
471+
@test elementary_differential(t15) ==
472+
L"$f^{\prime}f^{\prime\prime}(f^{\prime}f, f)$"
450473

451474
t16 = rootedtree([1, 2, 3, 4, 4])
452475
@test order(t16) == 5
@@ -456,6 +479,8 @@ using Aqua: Aqua
456479
@test β(t16) == α(t16) * γ(t16)
457480
@test t16 == t1 t7
458481
@test butcher_representation(t16) == "[[[τ²]]]"
482+
@test elementary_differential(t16) ==
483+
L"$f^{\prime}f^{\prime}f^{\prime\prime}(f, f)$"
459484

460485
t17 = rootedtree([1, 2, 3, 4, 5])
461486
@test order(t17) == 5
@@ -465,6 +490,8 @@ using Aqua: Aqua
465490
@test β(t17) == α(t17) * γ(t17)
466491
@test t17 == t1 t8
467492
@test butcher_representation(t17) == "[[[[τ]]]]"
493+
@test elementary_differential(t17) ==
494+
L"$f^{\prime}f^{\prime}f^{\prime}f^{\prime}f$"
468495

469496
# test non-canonical representation
470497
level_sequence = [1, 2, 3, 2, 3, 4, 2, 3, 2, 3, 4, 5, 6, 2, 3, 4]

0 commit comments

Comments
 (0)