versioninfo()
using Pkg
Pkg.status()
using Oscar
const pm=Polymake;
In the context of Hilbert's 16th Problem Itenberg and Viro constructed a counter-example to a conjecture of Ragsdale, via patchworking. This is just to show that (almost) all of polymake's functionality is available through Julia.
R = pm.tropical.ragsdale_counterexample();
Interactive visualization is possible, also within a Jupyter notebook. Yet, for static web versions svg output is nicer.
pm.display_svg(R)
The actual example starts here. We construct a regular $4$-cube, with $\pm1$-coordinates, but the precise coordinates will not matter here.
C = pm.polytope.cube(4);
We can get the combinatorial automorphism group directly.
G_polymake = pm.group.automorphism_group(C.VERTICES_IN_FACETS);
From the type information output (which is suppressed by ";" following the command) we see that the group is given as a permutation group. What is not obvious, but true: this is the natural action on the eight facets.
gens = G_polymake.PERMUTATION_ACTION.GENERATORS
Note that polymake is $0$-based, while Julia is $1$-based.
gens[2]
Generic Julia functions can convert between $0$- and $1$-based containers. Future Polymake.jl versions will have this built-in.
to_one_based_indexing(n::Number) = n + one(n)
to_zero_based_indexing(n::Number) = (n > zero(n) ? n - one(n) : throw(ArgumentError("Can't use negative index")))
for f in [:to_one_based_indexing, :to_zero_based_indexing]
@eval begin
$f(itr) = $f.(itr)
$f(s::S) where S<:AbstractSet = S($f.(s))
end
end
Applying this to the generators of the group computed by polymake yields a standard Julia datatype.
to_one_based_indexing(gens)
The software of choice to deal with groups is GAP. Here is a micro-demo, which constructs a symmetric group of degree four from a 4-cycle and a transposition.
S4 = GAP.Globals.Group(GAP.@gap [(1,2,3,4), (1,2)])
@show S4
GAP.Globals.Order(S4)
A typical OSCAR-function will provide natural ways of communication between the cornerstone systems. The function is fairly short, the bulk of the code are some straightforward conversions.
function combinatorial_automorphism_group(P)
G = pm.group.automorphism_group(P.VERTICES_IN_FACETS)
gens_polymake = G.PERMUTATION_ACTION.GENERATORS # acting on the facets
gens_julia = Vector{Int64}.(pm.to_one_based_indexing(gens_polymake))
gens_gap = GAP.Globals.PermList.(GAP.julia_to_gap.(gens_julia))
return GAP.Globals.Group(gens_gap...)
end
Recognizing the isomorphism type of the (combinatorial) automorphism group of a polytope is available neither in GAP nor polymake alone.
G = combinatorial_automorphism_group(C)
GAP.Globals.StructureDescription(G)
Some functions are implemented independently in both systems. This can be employed for cross-certification.
@show G_polymake.ORDER
@show GAP.Globals.Order(G)