Doron Zeilbeger made a talk last Friday at CRM in Montreal during Sage Days 38 about \(n^{n-2}\). At the end of the talk, he propoed a contest to code Joyal's Bijection which relates double rooted trees on \(n\) vertices and endofunctions on \(n\) elements. I wrote an implementation in Sage. My code is available here : joyal_bijection.sage. It will certainly not win for the most brief code, but it is object oriented, documented, reusable, testable and allows introspection.
Example
First, we must load the file:
sage:loadjoyal_bijection.sage
Creation of an endofunction:
sage:L=[7,0,6,1,4,7,2,1,5]sage:f=Endofunction(L)sage:fEndofunction:[0..8]->[7,0,6,1,4,7,2,1,5]
Creation of a double rooted tree:
sage:L=[(0,6),(2,1),(3,1),(4,2),(5,7),(6,4),(7,0),(8,5)]sage:D=DoubleRootedTree(L,1,7)sage:DDoublerootedtree:Edges:[(0,6),(2,1),(3,1),(4,2),(5,7),(6,4),(7,0),(8,5)]RootA:1RootB:7
From the endofunction f, we get a double rooted tree:
sage:f.to_double_rooted_tree()Doublerootedtree:Edges:[(0,6),(2,1),(3,1),(4,2),(5,7),(6,4),(7,0),(8,5)]RootA:1RootB:7
From the double rooted tree D, we get an endofunction:
sage:D.to_endofunction()Endofunction:[0..8]->[7,0,6,1,4,7,2,1,5]
In fact, we get D from f and vice versa:
sage:D==f.to_double_rooted_tree()Truesage:f==D.to_endofunction()True
Timing
On my machine, it takes 2.23 seconds to transform a random endofunction on \(\{0, 1, \cdots, 9999\}\) to a double rooted tree and then back to the endofunction and make sure the result is OK:
sage:E=Endofunctions(10000)sage:f=E.random_element()sage:timef==f.to_double_rooted_tree().to_endofunction()TrueTime:CPU2.23s,Wall:2.24s
Comments
I am using the Sage graph library (Networkx) to find the cycles of a graph and to find the shortest path between two vertices. It would be interesting to compare the timing when using the zen library which is lot faster then networkx.